Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.nuon.co/llms.txt

Use this file to discover all available pages before exploring further.

Container images allow you to import prebuilt container images from public sources, private AWS ECR repositories, and private GCP Artifact Registry (GAR) repositories.

Container Images vs Docker Build images

Container images are used to import prebuilt images, that have already been pushed to either a public registry, a private AWS ECR repository, or a private GCP Artifact Registry repository.

When to use a docker build component

Use a docker build component if:
  • your container build process does not do any additional scanning/processing on your built container images
  • you do not need to access any internal resources during the build process
  • you want to get started faster

When to use a container image component

  • you want to leverage public images
  • you post process or scan built container images
  • your build process accesses internal resources (such as a private dependency registry)
  • you value building once, and using everywhere for consistency purposes
If you have private prebuilt images in a registry other than AWS ECR or GCP Artifact 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
# container-image
name   = "public"
type   = "container_image"

[public]
image_url = "kennethreitz/httpbin"
tag       = "latest"

Using a Private AWS ECR Image

To use an image from a private ECR registry, configure the aws_ecr block.
components/ecr_image.toml
# container-image
name   = "ecr"
type   = "container_image"

[aws_ecr]
image_url    = "123927561584.dkr.ecr.us-west-2.amazonaws.com/repo-name"
tag          = "latest"
region       = "us-west-2"
iam_role_arn = "arn:aws:iam::123927561584:role/nuon-container-image-access"
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
# container-image
name   = "gar"
type   = "container_image"

[gcp_gar]
image_url      = "us-central1-docker.pkg.dev/my-project/my-repo/my-image"
tag            = "latest"
region         = "us-central1"
gcp_project_id = "my-project"

# Reader SA that Nuon impersonates to pull. Optional for self-hosted-on-GCP
# customers if the customer's ctl-api SA already has artifactregistry.reader
# directly on the repo; required for Nuon-hosted (AWS) customers.
service_account_email = "nuon-puller@my-project.iam.gserviceaccount.com"

# Required for Nuon-hosted (AWS) customers. Workload Identity Provider that
# Nuon's AWS ctl-api federates against before impersonating the reader SA.
workload_identity_provider = "projects/123456789/locations/global/workloadIdentityPools/nuon-aws/providers/aws-prod"
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.

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
# helm
name       = "eks_deployment"
type       = "helm_chart"
chart_name = "<your-app>"

[connected_repo]
repo      = "<your-app>"
directory = "components/helm-chart"
branch    = "main"

[values]
"env.IMAGE_TAG"        = "{{.nuon.components.app_image.image.tag}}"
"env.IMAGE_REPOSITORY" = "{{.nuon.components.app_image.image.repository.uri}}"
components/ecs_service.toml
# terraform
name              = "ecs_service"
type              = "terraform_module"
terraform_version = "v1.6.3"

[connected_repo]
repo      = "<your-app>"
directory = "components/ecs-service"
branch    = "main"

[vars]
"image_tag"        = "{{.nuon.components.app_image.image.tag}}"
"image_repository" = "{{.nuon.components.app_image.image.repository.uri}}"
components/eks_job.toml
# action
name      = "eks_job"
type      = "job"
image_url = "{{.nuon.components.app_image.image.repository.uri}}"
tag       = "{{.nuon.components.app_image.image.tag}}"

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.
Image registryCustomer deploymentSetup
AWS ECRNuon-hosted (AWS)AWS ECR Access IAM Role
AWS ECRSelf-hosted on GCPAWS ECR from a Self-Hosted-on-GCP Customer
GCP Artifact RegistryNuon-hosted (AWS)GAR for Nuon-hosted (AWS) customers
GCP Artifact RegistrySelf-hosted on GCPGCP GAR Access
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.
module "nuon_ecr_access" {
  source  = "nuonco/ecr-access/aws"

  repository_arns = ["<repository-arn>"]
}

output "iam_role_arn" {
  value = module.nuon_ecr_access.iam_role_arn
}
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.
module "nuon_ecr_access" {
  source  = "nuonco/ecr-access/aws"

  repository_arns = ["<repository-arn>"]

  gcp_principals = [
    {
      service_account_unique_id = "123456789012345678901"  # org runner SA UID
      service_account_email     = "<org-id-truncated>@<customer-project>.iam.gserviceaccount.com"
    },
    {
      service_account_unique_id = "987654321098765432109"  # ctl-api SA UID
      service_account_email     = "ctl-api-<install-id-truncated>@<customer-project>.iam.gserviceaccount.com"
    },
  ]
}
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:
gcloud iam service-accounts list \
  --project=<customer-project> \
  --filter='displayName~"Nuon org runner" OR displayName~"ctl-api for"' \
  --format='table(email,uniqueId,displayName)'
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:
module "nuon_gar_access" {
  source  = "nuonco/gar-access/google"

  project_id          = "<your-gcp-project>"
  repository_location = "us-central1"
  repository_id       = "<repo-name>"

  customer_principals = [
    "serviceAccount:ctl-api-<install>@<customer-project>.iam.gserviceaccount.com",
  ]
}

output "gar_access_sa_email" {
  value = module.nuon_gar_access.service_account_email
}
Then set service_account_email in your component’s gcp_gar block to the SA email the module emits.

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.
module "nuon_gar_access" {
  source = "nuonco/gar-access/google"

  project_id          = "<your-gcp-project>"
  repository_location = "us-central1"
  repository_id       = "<repo-name>"

  aws_principals = [
    { aws_account_id = "123456789012" },
  ]
}

output "workload_identity_provider_paths" {
  value = module.nuon_gar_access.workload_identity_provider_paths
}
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. See the full set of gcp_gar fields in the container-image config reference.

Importing Images Outside of Supported Registries

We currently support public container images, private AWS ECR repositories, and private GCP Artifact 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.