Skip to main content
Container images allow you to import prebuilt container images from public sources, private AWS ECR repositories, private GCP Artifact Registry (GAR) repositories, and private Azure Container Registry (ACR) repositories. Container images are used to import prebuilt images, that have already been pushed to either a public registry, a private AWS ECR repository, a private GCP Artifact Registry repository, or a private Azure Container Registry repository.
If you have private prebuilt images in a registry other than AWS ECR, GCP Artifact Registry, or Azure Container Registry, please get in touch!

Configuring a container image component

Using a Public Image

To use a public image from any container registry, configure the public block.
components/public_image.toml

Using a Private AWS ECR Image

To use an image from a private ECR registry, configure the aws_ecr block.
components/ecr_image.toml
To use an AWS ECR image, follow the access setup directions. Both Nuon-hosted (AWS) and self-hosted-on-GCP customers can pull from the same role.

Using a Private GCP GAR Image

To use an image from a private Google Artifact Registry, configure the gcp_gar block.
components/gar_image.toml
To use a GAR image, follow the access setup directions. Both Nuon-hosted (AWS) and self-hosted-on-GCP customers can pull from the same GAR repository.

Using a Private Azure ACR Image

To use an image from a private Azure Container Registry, configure the azure_acr block.
components/acr_image.toml
Access to a private ACR repository is granted through a service principal in your own tenant, not through credentials in your app config. The service principal’s secret (or certificate) value is stored as an app secret and referenced by name; the value itself never appears in app config or git. To set this up, follow the access setup directions.
ACR has no registry-level password. Authentication always goes through Azure AD: Nuon exchanges an Azure AD token for the service principal for an ACR refresh token, then uses that to pull the image. This is why azure_acr takes a tenant, client, and secret/certificate rather than a username and password.
This credential is used only when Nuon’s build runs — it authenticates to your registry once, at build time, from Nuon’s control plane. It never lands in a customer cloud account, and it is shared across all installs of the app rather than configured per install.

Deployments

Container image components cannot be deployed directly in a customer install. When an image is released, it will be synced into the customer install and made available to other components via variables. To deploy a Container image component, reference the image from a Helm component or Terraform component:
components/eks_deployment.toml
components/ecs_service.toml
components/eks_job.toml

Image Syncing

When a Container image component is released, Nuon will automatically sync the image into the end customer account. This image is stored in a local registry that is provisioned in the customer account. Nuon image syncing allows you to sync images into accounts, without worrying about cross account permissions, registry authentication or publishing public images. Any Dockerfile in a repo can be built, and synced. The sync process works by creating a 1-time authentication flow that grants the install runner access to pull the image from the org data plane, and copy it into the local registry.

Granting Nuon Access to Pull Images

Nuon-hosted runs in AWS, and we also offer a self-hosted BYOC deployment on GCP. Pick the section that matches your registry and the deployment kind your customers are using. If you have customers on both deployments, you can set both inputs on the same role or service account. Both modules add the new principals alongside any existing ones.

AWS ECR Access IAM Role

To use a private AWS ECR image, you must create an IAM role that grants Nuon access to pull your container image. When building your component, nuon will automatically assume the role and pull the image from your build runner. The easiest way to setup an IAM role to configure your component with is using our Terraform Module.
If you are having trouble finding the repository ARN in the AWS console, you can run aws ecr describe-repositories to print the ARNs of all repositories in your current context.

AWS ECR from a Self-Hosted-on-GCP Customer

If your customer is running a self-hosted Nuon deployment on GCP, pass the customer’s GCP service account unique IDs via gcp_principals so they can assume the role via Workload Identity Federation. Two SAs need to be listed:
  • The org runner SA, which pulls source for builds. Display name: Nuon org runner <org_id>.
  • The ctl-api SA, which fetches image metadata for external_image components. Display name: ctl-api for <install_id>.
Requires nuonco/ecr-access/aws version 0.1.9 or later.
Don’t construct the SA emails by hand. Nuon truncates the org and install IDs to fit GCP’s 30-character SA name limit, and the truncation length varies. Look the SAs up directly in the customer’s project. The full org and install IDs are preserved in each SA’s display name.
Look them up with:
The default Nuon-hosted (AWS) trust principal stays in place. Adding gcp_principals is additive, so the same role works for both Nuon-hosted and self-hosted-on-GCP customers.

GCP GAR Access

You grant access to a private GAR repository by creating a reader service account on the repo and allowing each customer’s identity to impersonate it. The same module covers both customer-deployment kinds. Use customer_principals for self-hosted-on-GCP customers, aws_principals for Nuon-hosted (AWS) customers, or both. The easiest way to set this up is using our Terraform Module:
Then set service_account_email in your component’s gcp_gar block to the SA email the module emits. repositories accepts multiple entries, and entries ending in * grant access to every repository matching that prefix (e.g. repositories = ["shared-images", "team-*"]) — including repositories created later. Requires nuonco/gar-access/google version 0.3.0 or later; older versions take a single repository_id string.

GAR for Nuon-hosted (AWS) customers

If some of your customers pull from this GAR repo via Nuon-hosted ctl-api running on AWS, pass each customer’s AWS account ID via aws_principals. You can use it alongside customer_principals if you also have self-hosted-on-GCP customers. The module sets up a Workload Identity Pool and AWS Provider per account, and lets the federated principal impersonate the GAR-access SA.
Requires nuonco/gar-access/google version 0.2.0 or later.
In the customer’s component config, set gcp_gar.service_account_email to the GAR-access SA email, and set gcp_gar.workload_identity_provider to the provider path for that customer’s AWS account from the module’s workload_identity_provider_paths output.

GAR for Nuon self-hosted (Azure) customers

If some of your customers run Nuon self-hosted on Azure, pass each customer’s Azure user-assigned managed identity via azure_principals. You can use it alongside customer_principals and aws_principals. The module sets up a Workload Identity Pool and an OIDC provider per identity — trusting the Entra ID issuer for its tenant — and lets the federated identity impersonate the GAR-access SA.
principal_id is the managed identity’s principal (object) ID — the sub claim Nuon’s Azure ctl-api presents. In the customer’s component config, set gcp_gar.service_account_email to the GAR-access SA email, and set gcp_gar.workload_identity_provider to the provider path for that customer’s identity from the module’s azure_workload_identity_provider_paths output. See the full set of gcp_gar fields in the container-image config reference.

Azure ACR Access

Unlike AWS ECR and GCP GAR, ACR has no cross-tenant identity federation, so access is granted the way most third parties access an Azure resource: you create a service principal (an app registration) in your own tenant, grant it AcrPull scoped to your registry, and give Nuon the tenant ID, client ID, and a secret or certificate for that service principal.
Only your build needs this. The install runner that deploys into a customer’s cloud account pulls the image from Nuon’s own registry, never from your ACR — so no access needs to be granted to any customer’s Azure identity. One service principal, scoped to your tenant, covers every install of the app.
1. Create the app registration and service principal:
2. Grant AcrPull, scoped to just this registry:
3. Create a credential. Use a client secret, or a client certificate (the better practice of the two, since it needs no plaintext secret at rest):
4. Store the value as an app secret, never in app config or git:
5. Reference the secret by name in the component’s azure_acr block — see Using a Private Azure ACR Image. Set tenant_id to your tenant, client_id to the appId from step 1, and client_secret_name or client_certificate_name (never both) to the app secret name from step 4.
Rotating the credential is a plain app secret update — run nuon apps variables create again with the same --name to overwrite it. Nothing re-runs automatically, so a stale or expired credential surfaces as a build failure the next time the component builds, not immediately at rotation time.
See the full set of azure_acr fields in the container-image config reference.

Importing Images Outside of Supported Registries

We currently support public container images, private AWS ECR repositories, private GCP Artifact Registry repositories, and private Azure Container Registry repositories. If your registry is supported by AWS ECR’s pull through cache, the easiest way to import the images into Nuon is to setup a pull through cache and configure your container image to use it. This works for Docker Hub, Github Container Registry and Microsoft Azure Container Registry.
If you would like to use a different private container registry, we would love to know more. Please get in touch to tell us more about your use case.