LAB16_GCP_Container Images: Artifact Registry Repository

Container Images: Artifact Registry Repository

☁ GCP 🟢 Beginner Artifact Registry Docker IAM

Scenario

Before you can deploy containers to Cloud Run or GKE, you must store their images in a secure registry. Google Cloud replaced the legacy "Container Registry (GCR)" with Artifact Registry. You need to create a Docker repository and grant a specific service account read access to it so it can pull the images during deployment.

Your Objectives
  • Create a google_artifact_registry_repository of format DOCKER.
  • Set the location of the repository to your region.
  • Create a google_service_account to act as your deployment principal.
  • Create a google_artifact_registry_repository_iam_member giving that service account the roles/artifactregistry.reader role on the repository.
  • Output the full repository pull URL (e.g., us-central1-docker.pkg.dev/proj/repoName).

Additional Context

Cleanup Policies: In a real-world scenario, container registries grow indefinitely, costing money. Artifact Registry supports "Cleanup Policies" (like keeping the 10 most recent images, or deleting anything older than 30 days that isn't tagged 'latest'). Terraform supports this via the `cleanup_policies` block.

Formats: Artifact Registry doesn't just hold Docker images. It can act as a private NPM registry, Maven repository, Python package index, or Apt/Yum package manager backend.

variables.tf

variable "project_id" { type = string }
variable "gcp_region" { type = string; default = "us-central1" }

main.tf

provider "google" {
  project = var.project_id
  region  = var.gcp_region
}

# 1. The Deployment Service Account
resource "google_service_account" "deployer" {
  account_id   = "docker-deployer"
  display_name = "Docker Image Deployer"
}

# 2. The Artifact Registry Repository
resource "google_artifact_registry_repository" "app_repo" {
  location      = var.gcp_region
  repository_id = "app-container-repo"
  description   = "Docker repo for main application services"
  format        = "DOCKER"
  
  # Basic cleanup policy: keep only the newest 5 versions of any image
  cleanup_policies {
    id     = "keep-minimum-versions"
    action = "KEEP"
    most_recent_versions {
      keep_count = 5
    }
  }
}

# 3. Grant the SA permission to read images from THIS specific repository
resource "google_artifact_registry_repository_iam_member" "reader" {
  project    = google_artifact_registry_repository.app_repo.project
  location   = google_artifact_registry_repository.app_repo.location
  repository = google_artifact_registry_repository.app_repo.name
  role       = "roles/artifactregistry.reader"
  member     = "serviceAccount:${google_service_account.deployer.email}"
}

outputs.tf

output "repository_url" {
  value       = "${var.gcp_region}-docker.pkg.dev/${var.project_id}/${google_artifact_registry_repository.app_repo.name}"
  description = "The root URL used to tag and push docker images"
}

Workflow Commands

terraform init
terraform apply -var="project_id=my-gcp-project-123"

# Authenticate local Docker daemon to the registry
gcloud auth configure-docker us-central1-docker.pkg.dev

# Tag a local image for the registry
docker tag my-app:latest $(terraform output -raw repository_url)/my-app:v1

# Push the image
docker push $(terraform output -raw repository_url)/my-app:v1

terraform destroy -var="project_id=my-gcp-project-123"
✓ Expected Output After Apply
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

Outputs:

repository_url = "us-central1-docker.pkg.dev/my-gcp-project-123/app-container-repo"