Skip to content

fix(infra): add DELETE cleanup policy to Artifact Registry (D116) - #94

Open
GMartin-Data wants to merge 1 commit into
mainfrom
fix/ar-cleanup-delete-policy
Open

GMartin-Data wants to merge 1 commit into
mainfrom
fix/ar-cleanup-delete-policy

Conversation

@GMartin-Data

Copy link
Copy Markdown
Owner

Contexte

Le repo Artifact Registry datatalent accumulait les versions d'images sans
jamais être purgé : 22 versions ingestion / 28 dbt, ~9 Go (~17× le free
tier de 0,5 Go), malgré une cleanup policy censée n'en garder que 3 par image.

Le diagnostic initial (D115) attribuait l'inertie au mode dry-run.
C'était une erreur de diagnostic : le HCL portait déjà cleanup_policy_dry_run = false, et deux armements gcloud … --no-dry-run (02 et 03/06) n'ont rien purgé.

Cause-racine réelle (D116) : la policy ne contenait qu'une entrée KEEP.
Or une policy KEEP ne supprime jamais rien par elle-même — doc Google,
verbatim : « Keep policies work with delete policies to keep artifacts that would
be deleted according to the specifications of your delete policy »
. Il manquait
une policy DELETE pour désigner les candidats à la suppression. Sans elle,
le --no-dry-run n'avait rien à armer.

Refs : D116 (cause rectifiée), D115 (diagnostic erroné conservé pour traçabilité),
D26 (free tier AR), D31 (terraform plan zéro diff — nuance ci-dessous).

Décisions techniques

Sujet Arbitrage
Mécanique de purge Policy à 2 entrées : DELETE (tag_state=ANY, matche toutes les versions) + KEEP (keep_count=3). Quand une version matche les deux, la KEEP gagne (doc Google).
Sécurité prod Images déployées recoupées digest↔Cloud Run Job : dbt → f7fcfea…, ingestion → ece987a…, toutes deux #1 du top-3 → protégées par keep_count=3.
tag_state=ANY Les versions sont toutes taguées par SHA de commit (un 1er comptage les avait ratées — faux négatif). ANY couvre taguées + untaguées. La DELETE exige au moins une condition (doc) ; ANY est la condition « tout matcher » valide.

Changements

  • infra/main.tf — ajout du bloc cleanup_policies { action = "DELETE" ; condition { tag_state = "ANY" } } avant le bloc KEEP existant. Commentaire HCL réécrit (D115 → D116).

Validation

⚠️ Particularité : contrairement à la règle d'or « terraform plan zéro diff »
(D31), ce plan montre 1 to change — c'est attendu et voulu. L'ajout d'un
bloc est un vrai diff structurel (≠ le champ dry_run de D115, no-op au plan
car state==HCL). C'est précisément ce qui rend ce fix corrigeable par Terraform,
là où D115 ne l'était pas.

~ resource "google_artifact_registry_repository" "docker" {
    ~ update in-place
      + cleanup_policies {
          + action = "DELETE"
          + id     = "delete-all-but-recent"
          + condition {
              + tag_state = "ANY"
            }
        }
  }
Plan: 0 to add, 1 to change, 0 to destroy.

Suite — PR délibérément NON mergée / NON armée

Appliquer ce plan EST l'armement destructif (pose la DELETE côté API → purge
sous ~24 h). Le geste est volontairement différé post-soutenance : le process
GCP impose un dry-run + relecture des logs Cloud Logging pour prouver qu'aucune
image prod n'est supprimée avant de confirmer.

Procédure d'armement pas-à-pas (hors repo) : ~/explain/procedure-armement-ar-cleanup.md.
Recompte attendu après purge : 3/3, repo ~1–1,5 Go.

Refs : D116, D115, D26, D31.

A KEEP-only cleanup policy never deletes anything (Google docs: "Keep
policies work with delete policies"). The repo accumulated 22/28 versions
(~9 GB, ~17x free tier) despite two `--no-dry-run` arming attempts, which
had nothing to arm. Root cause rectifies D115 (dry-run was a misdiagnosis).

Add a DELETE policy (condition tag_state=ANY, matches all versions); the
existing KEEP most_recent_versions/keep_count=3 protects the 3 newest of
each package. When a version matches both, KEEP wins — prod images
(dbt f7fcfea, ingestion ece987a, both #1 in top-3) are preserved.

Unlike the dry_run field of D115 (no-op at plan: state==HCL==false), adding
a block is a real structural diff — `terraform plan` shows "1 to change".
Applying this plan IS the destructive arming (purge within ~24h), so it is
left unapplied: arming is a deliberate post-defense step via dry-run +
log review (see ~/explain/procedure-armement-ar-cleanup.md).
@AFlo59

AFlo59 commented Jun 4, 2026

Copy link
Copy Markdown

Ici GitHub je valide la revue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants