Artifact Registry¶
Two Docker repos, both in asia-east1, both managed by infrastructure/gcp/registry.tf. Argo CD Image Updater pulls metadata from these to detect new tags.
Repos¶
| Repo | Format | Location | Purpose |
|---|---|---|---|
tomoda-dev-repo |
DOCKER | asia-east1 |
Main-branch builds — dev environment |
tomoda-prod-repo |
DOCKER | asia-east1 |
Semver-tagged builds — prod environment |
Full URIs:
asia-east1-docker.pkg.dev/development-485000/tomoda-dev-repo/<image>:<tag>
asia-east1-docker.pkg.dev/development-485000/tomoda-prod-repo/<image>:<tag>
The image names inside each repo (e.g. tomoda-backend, tomoda-frontend) are determined by the build YAMLs in the tomoda repo, not by Terraform.
Tag conventions¶
- Dev repo:
:latestis overwritten on every successful main-branch build (set via theTAG_NAME = "latest"substitution incloudbuild.tf). The previous digest is still reachable by SHA, but there is no immutable name for it. - Prod repo: the build YAML reads
${TAG_NAME}from the substitution, which release triggers leave unset → the YAML falls back to the Git tag (e.g.v0.4.2). Each prod image is therefore tagged exactly once and never overwritten.
Retention & cleanup¶
Both repos have native Artifact Registry cleanup_policies configured in registry.tf. Cleanup runs asynchronously on GCP's schedule.
Dev repo (tomoda-dev-repo) — aggressive¶
| Policy | Action | Condition |
|---|---|---|
delete-untagged-7d |
DELETE | Untagged images older than 7 days |
delete-tagged-30d |
DELETE | Tagged images older than 30 days |
keep-recent-10 |
KEEP | Last 10 tagged versions (any age) |
KEEP is evaluated before DELETE, so the 10-version floor protects recent images that would otherwise hit the 30-day window.
Prod repo (tomoda-prod-repo) — conservative¶
| Policy | Action | Condition |
|---|---|---|
delete-untagged-14d |
DELETE | Untagged images older than 14 days |
delete-tagged-180d |
DELETE | Tagged images older than 180 days |
keep-recent-20 |
KEEP | Last 20 tagged versions (any age) |
Prod is sized to keep rollback targets viable for ~6 months while still bounding storage growth.
Manual cleanup¶
If you ever need to short-circuit a policy (e.g. delete a specific vulnerable image immediately), use the console or:
gcloud artifacts docker images delete \
asia-east1-docker.pkg.dev/development-485000/tomoda-prod-repo/<image>@<digest>
Who can read & write¶
Authoritative bindings live in the IAM Terraform files; see IAM Overview for the full table.
| Principal | Role | What it enables |
|---|---|---|
cloudbuild-worker-sa@… |
roles/artifactregistry.writer (project-level, cloudbuild_iam.tf) |
Cloud Build can push image layers to both repos |
GKE default compute SA (…-compute@developer.gserviceaccount.com) |
roles/artifactregistry.reader (project-level, gke_iam.tf) |
Cluster nodes can pull images |
argocd-image-updater-sa@… |
roles/artifactregistry.reader (project-level, image_updater_iam.tf) |
Argo CD Image Updater can list tags |
All three roles are granted at the project level rather than per-repo, so adding a third repo later does not require new bindings.
Argo CD Image Updater integration¶
Argo CD Image Updater runs in the argocd namespace as the KSA argocd-image-updater. It impersonates argocd-image-updater-sa@${project_id}.iam.gserviceaccount.com via Workload Identity (binding in image_updater_iam.tf) and uses that SA's artifactregistry.reader role to:
- List tags on a watched image (e.g.
…/tomoda-dev-repo/tomoda-backend). - Compare against the digest currently referenced in the Argo CD Application manifest.
- If newer, write a Git commit updating the manifest, which Argo CD then reconciles.
This is read-only metadata access — the updater never pushes images, only reads tags. The dev/prod split between which application watches which repo is configured per Argo CD Application via annotations, not via Terraform.
flowchart LR
CB[Cloud Build] -->|push| AR[(Artifact Registry)]
IU[Argo CD Image Updater<br/>KSA: argocd-image-updater]
IU -. impersonates .-> SA[argocd-image-updater-sa@…]
SA -->|artifactregistry.reader| AR
IU -->|git commit| REPO[(GitOps repo)]
REPO --> ARGO[Argo CD]
ARGO --> GKE[GKE workloads]
See Argo CD for the install and Cloud Build for the producer side.