GitOps avec Terraform
Le GitOps applique les pratiques Git (branches, pull requests, review, merge) au cycle de vie de l'infrastructure. Toute modification passe par une MR, le plan est visible avant le merge, l'apply est automatique après validation. Le résultat : traçabilité complète, peer review systématique, rollback via revert.
Workflow GitOps basique
- Modifier le code HCL sur une branche feature
- Ouvrir une Merge Request : le pipeline CI lance un
terraform planet poste le résultat en commentaire - Review humaine du plan
- Merge : le pipeline CI lance
terraform applyautomatiquement
GitLab CI : plan + apply
# .gitlab-ci.yml
variables:
TF_ROOT: ${CI_PROJECT_DIR}
TF_STATE_NAME: production
stages: [validate, plan, apply]
.terraform_base:
image: hashicorp/terraform:1.14
before_script:
- terraform init
-backend-config="bucket=${TF_STATE_BUCKET}"
-backend-config="key=${TF_STATE_NAME}/terraform.tfstate"
validate:
extends: .terraform_base
stage: validate
script:
- terraform fmt -check -recursive
- terraform validate
- tfsec .
plan:
extends: .terraform_base
stage: plan
script:
- terraform plan -out=tfplan
- terraform show -no-color tfplan > plan.txt
artifacts:
paths: [tfplan, plan.txt]
expire_in: 1 week
rules:
- if: $CI_MERGE_REQUEST_ID
apply:
extends: .terraform_base
stage: apply
script:
- terraform apply tfplan
dependencies: [plan]
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual # approbation manuelle avant apply en prodGitHub Actions
# .github/workflows/terraform.yml
name: Terraform
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
terraform:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.14.0
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::ACCOUNT:role/TerraformRole
aws-region: eu-west-1
- run: terraform init
- name: Plan
id: plan
run: terraform plan -no-color -out=tfplan
- name: Comment PR avec le plan
uses: actions/github-script@v7
if: github.event_name == 'pull_request'
with:
script: |
const plan = require('fs').readFileSync('plan.txt', 'utf8')
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `\`\`\`terraform
${plan}
\`\`\``
})
- name: Apply
if: github.ref == 'refs/heads/main'
run: terraform apply tfplanAtlantis : GitOps dédié pour Terraform
Atlantis est un serveur open-source spécialisé dans le GitOps Terraform. Il écoute les webhooks Git et gère automatiquement le cycle plan/apply depuis les commentaires de PR.
# Installation via Docker
docker run -p 4141:4141 -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e ATLANTIS_GH_TOKEN -e ATLANTIS_GH_WEBHOOK_SECRET ghcr.io/runatlantis/atlantis server --gh-user=monuser --repo-allowlist=github.com/monorg/*Dans une PR, les commentaires déclenchent Atlantis :
atlantis plan: lance un plan et poste le résultatatlantis apply: applique le plan approuvéatlantis unlock: libère le verrou si un apply a échoué
# atlantis.yaml — config par dépôt
version: 3
projects:
- name: prod-vpc
dir: environments/prod/vpc
workspace: default
autoplan:
when_modified: ["**/*.tf", "../../modules/vpc/**/*.tf"]
- name: prod-ec2
dir: environments/prod/ec2
depends_on: [prod-vpc]