diff --git a/gcp-artifact-registry/README.md b/gcp-artifact-registry/README.md new file mode 100644 index 0000000..de777f0 --- /dev/null +++ b/gcp-artifact-registry/README.md @@ -0,0 +1,55 @@ +# Configuring Google Artifact Registry Pull-Through Cache for cgr.dev + +This directory contains Terraform resources to configure a [Google Artifact Registry remote repository](https://cloud.google.com/artifact-registry/docs/repositories/remote-repo) for a private `cgr.dev` registry, using a [Pull Token](https://edu.chainguard.dev/chainguard/chainguard-registry/authenticating/#authenticating-with-a-pull-token). + +First, create a pull token for your organization: + +``` +chainctl auth configure-docker --pull-token +``` + +This will print a `docker login` command that you can use to authenticate with the pull token. For example: + +``` +To use this pull token in another environment, run this command: + + docker login "cgr.dev" --username "abcdef11e47a927f78ffa39cd6393f4a83ec6eb7/e3b0123abcdef123" --password "eyJh...krglE" +``` + +We'll use this username and password to configure the pull-through cache in Terraform. + +Next, `terraform init` and `terraform apply` the configuration in this directory: + +``` +terraform apply +``` + +This will prompt for your GCP project, and the Chainguard pull token `username` and `password`. + +When Terraform is done creating resources, it will print the remote repo URLs that were created. + +``` +repos = [ + "us-east4-docker.pkg.dev/my-cool-project/remote", +] +``` + +You can now pull through these URLs to pull images from the `cgr.dev` registry. + +Simply append your Chainguard organization name and repo name to the URL, and use it as a remote repo URL. + +``` +docker pull us-east4-docker.pkg.dev/my-cool-project/remote/customer.biz/image:latest +latest: Pulling from my-cool-project/remote/customer.biz/image +6cdb74e61124: Downloading [====> ] 18.21MB/224.2MB +``` + +You can configure Terraform to set up resources in other regions, or with other names, by updating these variables: + +``` +TF_VAR_regions="['us-central1']" TF_VAR_repo="custom" terraform apply +... +repos = [ + "us-central1-docker.pkg.dev/my-cool-project/custom", +] +``` diff --git a/gcp-artifact-registry/main.tf b/gcp-artifact-registry/main.tf new file mode 100644 index 0000000..4d92d43 --- /dev/null +++ b/gcp-artifact-registry/main.tf @@ -0,0 +1,88 @@ +variable "project" { + type = string + description = "The GCP project ID" +} + +variable "repo" { + type = string + description = "The GCP Artifact Registry repository name" + default = "remote" +} + +variable "regions" { + type = list(string) + description = "The GCP regions to deploy to" + default = ["us-east4"] +} + +variable "username" { + type = string + description = "Username for the cgr.dev pull token" +} + +variable "password" { + sensitive = true + type = string + description = "Password for the cgr.dev pull token" +} + +provider "google" { + project = var.project +} + +resource "google_secret_manager_secret" "pull-token" { + secret_id = "pull-token" + replication { + auto {} + } +} + +resource "google_secret_manager_secret_version" "pull-token" { + secret = google_secret_manager_secret.pull-token.name + secret_data = var.password +} + +resource "google_artifact_registry_repository" "repo" { + for_each = toset(var.regions) + + location = each.key + repository_id = var.repo + description = "Remote Chainguard Images repository" + format = "DOCKER" + mode = "REMOTE_REPOSITORY" + remote_repository_config { + description = "chainguard" + + // The password won't be populated at first, so we need to disable + // validating the token at repo-creation time. + disable_upstream_validation = true + + docker_repository { + custom_repository { + uri = "https://cgr.dev" + } + } + + upstream_credentials { + username_password_credentials { + username = var.username + password_secret_version = google_secret_manager_secret_version.pull-token.name + } + } + } +} + +data "google_project" "project" {} + +locals { project-number = data.google_project.project.number } + +// Give the AR service account the ability to read the secret. +resource "google_secret_manager_secret_iam_member" "reader" { + secret_id = google_secret_manager_secret.pull-token.id + role = "roles/secretmanager.secretAccessor" + member = "serviceAccount:service-${local.project-number}@gcp-sa-artifactregistry.iam.gserviceaccount.com" +} + +output "repos" { + value = [for r in var.regions : "${google_artifact_registry_repository.repo[r].location}-docker.pkg.dev/${var.project}/${google_artifact_registry_repository.repo[r].name}"] +}