Este contenido aún no está traducido. Se muestra la versión original.
Oui, c'est possible. Ce projet monte en local, avec Docker, l'équivalent complet du circuit d'entreprise
GitHub → service Terraform managé → cloud, puis le teste de bout en bout, automatiquement.
En entreprise
Ici, en local
Rôle
GitHub
Gitea
Dépôt, pull requests, revues, protection de main, webhooks
Service Terraform managé (HCP Terraform, Atlantis, plateforme interne…)
Atlantis
Plan automatique sur PR, politiques, verrous, apply sur approbation
Bucket Cloud Storage pour l'état (backend "gcs")
MinIO (stockage compatible S3)
État distant versionné + verrouillage
Ressources Google Cloud
Ressources simulées (terraform_data)
Même mécanique, sans compte cloud ni coût
Résultat vérifié sur une installation partant de zéro : 24 vérifications, 0 échec, et la simulation est
rejouable. Le journal de référence est dans docs/execution-reference.txt.
Les personnages (comptes Gitea créés automatiquement) :
Compte
Joue le rôle de
alice
Développeuse : ouvre les PR, commente atlantis apply
bob
Équipe sécurité : relit, approuve, et seul propriétaire des politiques
atlantis-bot
Compte de service du service Terraform (il commente dans les PR)
platform-admin
Équipe plateforme : administre Gitea et le dépôt
Le circuit : PR ouverte → Gitea envoie un webhook → Atlantis clone la branche, lance terraform init +
plan → contrôle les politiques (Conftest) → publie plan et résultat dans la PR → l'apply n'est accepté que si la
PR est approuvée et que les politiques passent → l'état est écrit dans MinIO, sous verrou.
2. Prérequis
Docker et Docker Compose v2 (docker compose version)
Python 3, git, curl (déjà présents sur la plupart des Linux)
Accès Internet pour télécharger 3 images : gitea/gitea, ghcr.io/runatlantis/atlantis, minio/minio
(environ 1 Go). L'image Atlantis embarque déjà Terraform et Conftest.
Ports libres : 3000 (Gitea), 4141 (Atlantis), 9000/9001 (MinIO). Ils sont modifiables dans .env.
cd 07-terraform-service-local./scripts/setup.sh # installe et configure tout (environ 1 à 2 min, plus le téléchargement des images)python3 scripts/scenario.py # simule le circuit complet et vérifie chaque étape (environ 3 à 5 min)
Puis ouvrez :
Gitea : http://localhost:3000 (alice, mot de passe dans .env : ALICE_PASSWORD) → acme/infra-demo → Pull requests
Fichier : scripts/scenario.py. Il joue les personnages via l'API Gitea, attend les
réponses d'Atlantis dans les PR, et vérifie chaque résultat : il s'arrête à la première anomalie.
Scénario 1 : un changement conforme, de bout en bout
Étape
Action
Résultat vérifié
02
alice crée une branche avec un nouveau bucket (UE, labels complets) dans envs/dev
branche poussée
03
alice ouvre la PR
Atlantis planifie tout seul : « Plan: 2 to add » publié dans la PR
04
—
Politiques : 3 tests, 3 passed
05
alice commente atlantis apply -p devsans approbation
refusé : « Pull request must be approved… »
06
bob approuve la PR
revue Approved
07
alice recommente atlantis apply -p dev
Apply complete! Resources: 2 added
08
—
l'état dev/terraform.tfstate dans MinIO contient la ressource ; plus de verrou
09
alice libère le verrou (atlantis unlock) et fusionne
PR fusionnée : main = ce qui est déployé
Scénario 2 : un changement non conforme est arrêté
Étape
Action
Résultat vérifié
10
alice propose un bucket en us-central1, sans label cost_center, en prod
plan calculé, mais Policy Check Failed : « localisation 'us-central1' interdite (UE uniquement) » et « label obligatoire 'cost_center' manquant »
11
bob approuve quand même, alice tente l'apply
refusé : « All policies must pass for project before running apply » ; PR fermée ; l'état prod ne contient rien
C'est le point clé d'un service managé : une approbation humaine ne suffit pas à contourner une règle de
l'entreprise. Seul bob, propriétaire des politiques, pourrait accorder une dérogation tracée
(atlantis approve_policies).
Scénario 3 : deux PR sur le même projet → verrou
Étape
Action
Résultat vérifié
12
deux PR modifient envs/dev
la 1re planifie et verrouille le projet ; la 2e est refusée : « locked by an unapplied plan from pull #… »
13
la 1re est abandonnée (atlantis unlock + fermeture)
la 2e peut planifier
Le verrou garantit que le plan approuvé est celui qui sera appliqué : personne ne peut modifier la même
infrastructure entre-temps.
Approuver : déconnectez-vous, connectez-vous en bob, ouvrez la PR → Fichiers modifiés → Revue → Approuver.
Appliquer : en alice, commentez atlantis apply -p dev → « Apply complete! ».
Voir l'état : console MinIO (http://localhost:9001) → tfstate/dev/terraform.tfstate → onglet Versions
(chaque apply crée une version : c'est votre sauvegarde).
Voir les verrous : http://localhost:4141 → liste des verrous. Puis atlantis unlock et Fusionner.
Variante « politique » : refaites l'étape 2 avec location = "us-east1" : Atlantis affichera
Policy Check Failed avec le motif exact.
Les liens publiés par Gitea pointent vers http://gitea:3000/… (adresse interne au réseau Docker). Pour les
ouvrir tels quels depuis le navigateur, ajoutez 127.0.0.1 gitea à /etc/hosts, ou remplacez gitea par
localhost dans l'URL.
repos: - id: /.*/ apply_requirements: [approved, mergeable] # pas d'apply sans PR approuvée et fusionnable allow_custom_workflows: false # un dépôt ne peut pas injecter ses propres commandes policy_check: true # politiques obligatoirespolicies: owners: { users: [bob] } # seule la sécurité peut accorder une dérogation policy_sets: - { name: socle-entreprise, path: /policies, source: local }
Pourquoi côté serveur : si ces règles étaient dans le dépôt, une PR pourrait les assouplir. Ici, elles
s'imposent à tous les dépôts.
Elle déclare les projets (dev = envs/dev, prod = envs/prod) et quand planifier
(when_modified : les .tf du dossier et des modules). Chaque projet a son état et son verrou.
En production sur Google Cloud : backend "gcs" { bucket = "acme-tfstate-prod", prefix = "dev" }. Le verrou est
natif, l'objet .tflock étant créé par écriture conditionnelle.
terraform_data enregistre la configuration d'un bucket (nom, localisation, labels, public) sans appeler de
cloud. Pour passer en réel, on remplace ce bloc par google_storage_bucket avec les mêmes variables. Les
politiques, les PR, les verrous et l'état fonctionnent à l'identique.
8. Les pièges rencontrés pendant la mise au point, et leurs solutions
Ces problèmes sont apparus réellement pendant les tests. Ils sont corrigés dans les fichiers, mais les connaître
vous fera gagner des heures.
Symptôme
Cause
Solution appliquée
Atlantis ne réagit à aucune PR ; journal Gitea : denied by egress policy
Gitea ≥ 28 bloque les webhooks vers les adresses privées ; le réglage a migré de [webhook] vers [security] ALLOWED_HOST_LIST
GITEA__security__ALLOWED_HOST_LIST: "private" (et l'ancien réglage, gardé pour les versions antérieures)
Atlantis répond « This repo is not allowlisted »
Gitea ≥ 1.24 construit ses URL à partir de l'hôte de la requête (localhost) au lieu de ROOT_URL : Atlantis reçoit localhost, qui ne correspond pas à la liste blanche (et n'est pas joignable depuis son conteneur)
GITEA__server__PUBLIC_URL_DETECTION: "never"
Le verrou d'une PR fermée bloque les autres PR
Avec Gitea, Atlantis 0.48 reçoit la fermeture d'une PR comme un événement « other » et ne libère pas le verrou (avec GitHub, c'est automatique)
Commenter atlantis unlock avant de fermer ou fusionner une PR (fait par le scénario). En cas d'oubli : bouton Unlock sur http://localhost:4141
Le plan annonce « 2 to add » au lieu de 1
Le bucket initial de main n'avait jamais été appliqué en dev : le premier apply l'inclut
Comportement normal : le plan montre tout l'écart entre code et réalité
Le commentaire de plan est replié (« Superseded »)
Atlantis masque son commentaire précédent quand il publie le résultat des politiques (HIDE_PREV_PLAN_COMMENTS)
Normal : dépliez le commentaire pour voir le plan
9. Passer au réel : GitHub + Google Cloud
La mécanique reste la même ; seules les briques changent.
Brique
Local
Réel
Dépôt
Gitea
GitHub : flags ATLANTIS_GH_USER/ATLANTIS_GH_TOKEN ou, mieux, une GitHub App (ATLANTIS_GH_APP_ID, clé privée, ATLANTIS_GH_WEBHOOK_SECRET) ; branche main protégée + CODEOWNERS
Hébergement d'Atlantis
Docker local
Cloud Run ou GKE, derrière HTTPS (et IAP pour l'interface) ; disque persistant pour /atlantis-data (ou base Redis pour les verrous)
Identité vers Google Cloud
—
Compte de service attaché à Atlantis (Workload Identity sur GKE, compte de service Cloud Run) ; aucune clé JSON ; droits limités aux dossiers gérés ; idéalement un compte par projet Atlantis via impersonate_service_account
État
MinIO (backend "s3")
backend "gcs" : bucket versionné, CMEK, accès réservé au compte d'Atlantis
Ressources
terraform_data
google_* (provider hashicorp/google)
Politiques
Conftest local
Mêmes fichiers Rego, versionnés dans un dépôt « policies » relu par la sécurité
Secrets
.env
Secret Manager (jeton GitHub, secret du webhook), injectés dans Cloud Run ou GKE
Exemple : Atlantis sur Cloud Run (extrait, à adapter) :
gcloud run deploy atlantis --image ghcr.io/runatlantis/atlantis:latest --region europe-west1 \ --service-account atlantis-runner@acme-iac.iam.gserviceaccount.com \ --set-secrets ATLANTIS_GH_TOKEN=atlantis-gh-token:latest,ATLANTIS_GH_WEBHOOK_SECRET=atlantis-webhook:latest \ --set-env-vars ATLANTIS_REPO_ALLOWLIST=github.com/acme/*,ATLANTIS_ATLANTIS_URL=https://atlantis.acme.example \ --min-instances 1 --max-instances 1 # Atlantis garde ses verrous localement : une seule instance
Atlantis est mono-instance par défaut (verrous dans une base locale BoltDB). Pour la haute disponibilité :
backend de verrous Redis (ATLANTIS_LOCKING_DB_TYPE=redis) et stockage partagé. C'est l'une des raisons
pour lesquelles les grandes entreprises choisissent souvent un service managé (HCP Terraform, Spacelift…) ou une
plateforme interne.
Et avec Gemini Enterprise : le dépôt infra-gemini-enterprise (chapitre 26 du guide Terraform) se branche
exactement comme infra-demo. Atlantis planifie envs/recette et envs/prod, la politique vérifie par exemple
« localisation eu », « Model Armor en FAIL_CLOSED », « connecteurs en FEDERATED », et l'image Atlantis doit
contenir gcloud et curl pour les réglages REST du socle (image personnalisée FROM ghcr.io/runatlantis/atlantis).
10. Aide-mémoire des commandes Atlantis
À écrire en commentaire de la PR :
Commande
Effet
atlantis plan / atlantis plan -p dev
(Re)planifier tous les projets / le projet dev
atlantis apply -p dev
Appliquer le plan approuvé du projet dev
atlantis unlock
Abandonner les plans et libérer les verrous de la PR
atlantis approve_policies
Dérogation aux politiques (propriétaires des politiques uniquement : bob)
atlantis import -p dev ADRESSE ID
Importer une ressource existante dans l'état
atlantis state rm -p dev ADRESSE
Retirer une ressource de l'état sans la détruire
atlantis help
Aide
11. Dépannage
Symptôme
Où regarder
Solution
Aucun commentaire d'Atlantis
docker compose logs gitea | grep -i deliver
Voir §8 (règle de sortie Gitea) ; vérifier le secret du webhook