18 min de lecture

Objectifs d'apprentissage

À la fin de ce module, vous serez en mesure de:

  • Créer un workflow GitHub Actions qui construit un conteneur, le pousse vers IONOS CLOUD Container Registry et le déploie sur Managed Kubernetes à chaque push vers `main`
  • Configurer un pipeline GitLab CI équivalent avec des étapes de build, de push et de déploiement spécifiques à IONOS CLOUD
  • Exécuter Terraform dans CI/CD avec `plan` sur les pull requests et `apply` sur la fusion, en gérant `IONOS_TOKEN` et d'autres secrets en toute sécurité
  • Mettre en œuvre des stratégies de déploiement et de rollback en utilisant `kubectl rollout` et la récupération de l'état Terraform
  • Extraire des modules Terraform réutilisables à partir de l'infrastructure TaskBoard pour construire une bibliothèque de modules d'équipe

Unité 3.3 : Pipelines CI/CD pour IONOS CLOUD

Introduction

Vous avez conteneurisé TaskBoard, poussé ses images vers IONOS CLOUD Container Registry et déployé manuellement l'application sur Managed Kubernetes. Exécuter docker push et kubectl apply depuis votre ordinateur portable n'est pas évolutif pour une équipe, et cela ne survit pas au moment où vous oubliez quelle étiquette d'image est en production. Dans cette unité, vous assemblez l'ensemble de la boucle afin qu'un git push soit la seule étape manuelle. Un commit déclenche une construction, l'image arrive dans Container Registry avec une étiquette correspondant au SHA git, et la nouvelle étiquette est déployée sur le cluster.

Vous soumettre également l'infrastructure à la même discipline. Terraform plan s'exécute à chaque demande de tirage afin que les réviseurs voient la différence avant tout changement, et apply ne s'exécute qu'après la fusion. Deux contraintes d'IONOS CLOUD façonnent chaque pipeline que vous écrivez ici : l'API est asynchrone, de sorte que les déploiements doivent attendre la disponibilité plutôt que de la supposer, et l'authentification de Container Registry repose uniquement sur une connexion docker basée sur des jetons, sans RBAC et sans dépôts par équipe, si bien que les identifiants sont stockés dans les secrets CI.

1. Conception du pipeline pour IONOS CLOUD

Un pipeline CI/CD sur IONOS CLOUD se divise en deux flux distincts qui ne doivent pas partager un même job. Les modifications applicatives suivent build -> test -> push image -> deploy to Kubernetes. Les modifications d'infrastructure suivent plan -> apply. Les mélanger signifie qu'une coquille dans un manifeste Kubernetes peut bloquer une correction d'infrastructure urgente, et qu'un terraform apply lent retarde tout déploiement applicatif.

Le flux applicatif se termine par kubectl apply ou, plus précisément, par une mise à jour contrôlée de l'étiquette d'image sur un Deployment existant. Le flux d'infrastructure se termine par terraform apply sur vos ressources IONOS CLOUD. Les deux flux s'authentifient auprès d'IONOS CLOUD, mais ils utilisent des identifiants différents : le flux applicatif a besoin d'un jeton Container Registry et d'un kubeconfig, tandis que le flux d'infrastructure a besoin d'un jeton bearer IONOS_TOKEN pour l'API Cloud.

1.1 Étiquetage des images avec le SHA Git

Ne déployez jamais :latest. Une étiquette mutable rend les retours arrière ambigus et rompt le lien entre un pod en cours d'exécution et le commit qui l'a produit. Étiquetez chaque image avec le SHA git immuable afin que la révision en cours d'exécution soit toujours traçable.

# Derive an immutable tag from the commit
REGISTRY="taskboard.cr.de-fra.ionos.com"
SHA=$(git rev-parse --short HEAD)
IMAGE="${REGISTRY}/taskboard-api:${SHA}"

docker build -t "${IMAGE}" ./api
docker push "${IMAGE}"

Le nom d'hôte du registre suit le modèle {registry-name}.cr.{location-with-dash}.ionos.com, par exemple tue1608es.cr.es-vit.ionos.com. Le nom d'hôte n'est attribué qu'après que le registre a atteint l'état Running et reste vide jusqu'à ce moment, de sorte qu'un pipeline qui provisionne un registre neuf doit lire le nom d'hôte à partir de la sortie de Terraform plutôt que de le coder en dur.

1.2 Séparation des dépôts d'application et d'infrastructure

Conservez Terraform dans un dépôt d'infrastructure et les manifests Kubernetes ainsi que le code applicatif dans un dépôt d'application. Le dépôt d'infrastructure s'applique à la fusion ; le dépôt d'application construit et déploie à la poussée. Cette séparation limite l'impact d'une modification erronée et permet d'accorder des accès différents à différentes équipes.

taskboard-app/          # build, push, kubectl deploy
  api/Dockerfile
  k8s/deployment.yaml
  .github/workflows/deploy.yml
taskboard-infra/        # terraform plan/apply
  main.tf
  modules/
  .github/workflows/terraform.yml

2. GitHub Actions pour IONOS CLOUD

Un workflow GitHub Actions pour le flux applicatif comporte trois étapes logiques au sein d'un seul job : construction et tests, connexion et poussée Docker, puis déploiement sur Managed Kubernetes. Les parties spécifiques à IONOS CLOUD sont la connexion au registre (basée sur un jeton) et la récupération du kubeconfig.

2.1 Stockage des secrets IONOS CLOUD

Les jetons ne doivent jamais être stockés dans le dépôt. Stockez le jeton du Container Registry et le kubeconfig en tant que secrets de dépôt ou d'environnement. Le mot de passe du jeton du Container Registry n'est affiché qu'une seule fois lors de sa création ; capturez-le immédiatement et stockez-le dans la CI. Un jeton de registre peut être permanent ou temporaire avec un expiryDate, et à son expiration, le jeton est supprimé plutôt que désactivé, ce qui signifie qu'un jeton expiré dans la CI provoque un échec direct de la connexion Docker plutôt qu'une dégradation silencieuse.

Nom du secret Contenu Utilisé par
CR_USERNAME Nom du jeton du Container Registry docker login
CR_PASSWORD Mot de passe du jeton du Container Registry (affiché une seule fois) docker login
KUBECONFIG kubeconfig encodé en base64 issu de la sortie Terraform kubectl
IONOS_TOKEN Jeton bearer de l'API Cloud Terraform / ionosctl

2.2 Le workflow de déploiement

# .github/workflows/deploy.yml
name: deploy-taskboard
on:
  push:
    branches: [main]

env:
  REGISTRY: taskboard.cr.de-fra.ionos.com
  IMAGE_NAME: taskboard-api

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set image tag
        run: echo "TAG=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"

      - name: Run tests
        run: |
          cd api
          pip install -r requirements.txt
          pytest

      - name: Log in to IONOS CLOUD Container Registry
        run: echo "${{ secrets.CR_PASSWORD }}" | docker login "$REGISTRY" \
             -u "${{ secrets.CR_USERNAME }}" --password-stdin

      - name: Build and push image
        run: |
          docker build -t "$REGISTRY/$IMAGE_NAME:$TAG" ./api
          docker push "$REGISTRY/$IMAGE_NAME:$TAG"

      - name: Configure kubectl
        run: |
          mkdir -p "$HOME/.kube"
          echo "${{ secrets.KUBECONFIG }}" | base64 -d > "$HOME/.kube/config"

      - name: Deploy to Managed Kubernetes
        run: |
          kubectl set image deployment/taskboard-api \
            api="$REGISTRY/$IMAGE_NAME:$TAG"
          kubectl rollout status deployment/taskboard-api --timeout=180s

kubectl set image met à jour uniquement le champ image du Deployment existant, ce qui déclenche une mise à jour progressive sans réappliquer l'ensemble du manifeste. L'étape kubectl rollout status bloque jusqu'à la fin du déploiement ou jusqu'à l'expiration du délai, ce qui est la méthode correcte pour signaler un déploiement échoué comme une pipeline échouée. Le kubeconfig provient lui-même du cluster Managed Kubernetes : vous le téléchargez à partir des paramètres du cluster ou, dans une pipeline automatisée, vous le lisez à partir de la sortie Terraform (traité dans l'Unité 3.2) et vous stockez la valeur encodée en base64 en tant que secret KUBECONFIG.

3. GitLab CI pour IONOS CLOUD

GitLab CI exprime le même flux sous forme d'étapes discrètes dans .gitlab-ci.yml. Les spécificités d'IONOS CLOUD sont identiques : connexion Docker basée sur jeton au registre et kubeconfig pour le cluster. GitLab fournit un service Docker-in-Docker pour la construction d'images à l'intérieur du pipeline.

3.1 Étapes du pipeline

# .gitlab-ci.yml
stages: [test, build, deploy]

variables:
  REGISTRY: taskboard.cr.de-fra.ionos.com
  IMAGE_NAME: taskboard-api

test:
  stage: test
  image: python:3.12
  script:
    - cd api && pip install -r requirements.txt && pytest

build:
  stage: build
  image: docker:24
  services: [docker:24-dind]
  script:
    - export TAG=$CI_COMMIT_SHORT_SHA
    - echo "$CR_PASSWORD" | docker login "$REGISTRY" -u "$CR_USERNAME" --password-stdin
    - docker build -t "$REGISTRY/$IMAGE_NAME:$TAG" ./api
    - docker push "$REGISTRY/$IMAGE_NAME:$TAG"

deploy:
  stage: deploy
  image: bitnami/kubectl:latest
  script:
    - echo "$KUBECONFIG_B64" | base64 -d > /tmp/kubeconfig
    - export KUBECONFIG=/tmp/kubeconfig
    - kubectl set image deployment/taskboard-api api="$REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA"
    - kubectl rollout status deployment/taskboard-api --timeout=180s
  only: [main]

Stockez CR_USERNAME, CR_PASSWORD et KUBECONFIG_B64 en tant que variables CI/CD masquées et protégées dans les paramètres du projet GitLab. Les variables protégées ne sont exposées qu'aux pipelines exécutés sur des branches protégées, ce qui empêche les identifiants de production d'être utilisés dans les pipelines de branches de fonctionnalité. CI_COMMIT_SHORT_SHA est l'équivalent GitLab de l'étiquette SHA de git, offrant la même garantie d'étiquette immuable que l'exemple GitHub Actions.

4. Terraform dans CI/CD

Les modifications d'infrastructure méritent une révision avant d'affecter les ressources IONOS CLOUD, car terraform apply crée des ressources facturables et peut les détruire. Le modèle standard consiste à exécuter terraform plan à chaque demande d'extraction et à publier le plan en tant que commentaire de la demande d'extraction, puis à exécuter terraform apply uniquement après la fusion dans main. Cela permet aux réviseurs de voir la diff exacte et d'empêcher quiconque d'appliquer des modifications non révisées.

4.1 Plan sur la demande d'extraction, application sur la fusion

# .github/workflows/terraform.yml
name: terraform
on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

env:
  IONOS_TOKEN: ${{ secrets.IONOS_TOKEN }}

jobs:
  plan:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
      - run: terraform init
      - run: terraform plan -no-color -out=tfplan
      - run: terraform show -no-color tfplan > plan.txt
      - uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const plan = fs.readFileSync('plan.txt', 'utf8');
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: '```\n' + plan.slice(0, 60000) + '\n```'
            });

  apply:
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
      - run: terraform init
      - run: terraform apply -auto-approve

Le fournisseur Terraform IONOS CLOUD s'authentifie à partir de la variable d'environnement IONOS_TOKEN, de sorte que la transmission du jeton bearer en tant que variable d'environnement est tout ce dont le bloc fournisseur a besoin. Le fournisseur interroge en interne les opérations asynchrones d'IONOS CLOUD, de sorte que terraform apply est bloquant jusqu'à ce que chaque ressource atteigne son état prêt avant de passer à la suite. Cela signifie que le pipeline n'a pas besoin de ses propres boucles de disponibilité pour les ressources gérées par Terraform.

4.2 État distant pour CI/CD

L'état local ne fonctionne pas dans CI/CD, car chaque exécuteur démarre avec une copie propre. Utilisez l'arrière-plan IONOS CLOUD Object Storage compatible S3 afin que chaque exécution de pipeline lise et écrive le même état, et afin que le verrouillage de l'état empêche deux applications simultanées de le corrompre.

terraform {
  backend "s3" {
    bucket                      = "taskboard-tfstate"
    key                         = "infra/terraform.tfstate"
    region                      = "de"
    endpoints = { s3 = "https://s3-eu-central-1.ionoscloud.com" }
    skip_credentials_validation = true
    skip_region_validation      = true
    skip_requesting_account_id  = true
  }
}

Object Storage utilise l'authentification par Access Key et Secret Key, et non par jetons bearer, de sorte que les identifiants d'accès à l'arrière-plan sont distincts de IONOS_TOKEN. Fournissez-les au pipeline en tant que secrets AWS_ACCESS_KEY_ID et AWS_SECRET_ACCESS_KEY. L'arrière-plan S3 les lit automatiquement.

5. Stratégies de déploiement et restauration

La stratégie de déploiement par défaut de Kubernetes est RollingUpdate, qui remplace les pods de manière incrémentielle afin que le service reste disponible pendant le déploiement. Pour les charges de travail qui ne peuvent pas exécuter deux versions simultanément, utilisez Recreate, qui met fin à tous les pods anciens avant de démarrer les nouveaux, au prix d'une courte interruption de service.

5.1 Configuration de la stratégie

apiVersion: apps/v1
kind: Deployment
metadata:
  name: taskboard-api
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels: { app: taskboard-api }
  template:
    metadata:
      labels: { app: taskboard-api }
    spec:
      imagePullSecrets:
        - name: cr-pull-secret
      containers:
        - name: api
          image: taskboard.cr.de-fra.ionos.com/taskboard-api:abc1234
          readinessProbe:
            httpGet: { path: /healthz, port: 8080 }
            initialDelaySeconds: 5

maxUnavailable: 0 garantit qu'aucune capacité n'est perdue pendant le déploiement, et readinessProbe s'assure que le trafic n'atteint que les pods qui signalent un état sain. L'entrée imagePullSecrets fait référence au jeton Container Registry, car le cluster tire les images en utilisant les mêmes identifiants basés sur des jetons que votre pipeline utilisait pour les pousser. Les déploiements canary et bleu-vert sont réalisables à l'aide de Deployments parallèles et de basculement du trafic, ou avec un outil GitOps tel qu'ArgoCD, qui est traité comme un modèle dans l'unité 5.3 et non ici.

5.2 Retour en arrière

Lorsqu'un déploiement échoue, faites revenir l'application à l'état antérieur avec kubectl rollout undo, ce qui restaure le Deployment à sa révision précédente sans reconstruire quoi que ce soit.

# Inspect revision history
kubectl rollout history deployment/taskboard-api

# Roll back to the immediately previous revision
kubectl rollout undo deployment/taskboard-api

# Roll back to a specific revision
kubectl rollout undo deployment/taskboard-api --to-revision=4

Chaque image étant étiquetée avec son SHA git, vous pouvez également effectuer un retour arrière de manière déterministe à l'aide de kubectl set image en pointant vers une étiquette connue comme valide. Pour l'infrastructure, le retour arrière consiste à annuler l'engagement fautif et à relancer terraform apply, ce qui réconcilie les ressources en cours d'exécution avec l'état engagé. Si l'état lui-même est endommagé, restaurez-le à partir d'une copie versionnée dans l'arrière-plan Object Storage.

6. Création d'une bibliothèque de modules Terraform

Une fois que l'infrastructure de TaskBoard fonctionne, extrayez les motifs répétés en modules afin que le service suivant ne parte pas de zéro. Un module regroupe des ressources associées derrière des variables d'entrée et expose des sorties, transformant une pile verbale en quelques lignes de code appelant.

6.1 Structure d'un module

# modules/k8s-service/variables.tf
variable "name"        { type = string }
variable "node_count"  { type = number, default = 2 }
variable "k8s_version" { type = string, default = "1.34" }

# modules/k8s-service/main.tf
resource "ionoscloud_k8s_cluster" "this" {
  name        = var.name
  k8s_version = var.k8s_version
}

resource "ionoscloud_k8s_node_pool" "this" {
  name        = "${var.name}-pool"
  k8s_cluster_id = ionoscloud_k8s_cluster.this.id
  node_count  = var.node_count
  # ... cores, ram, availability_zone, etc.
}

# modules/k8s-service/outputs.tf
output "cluster_id" { value = ionoscloud_k8s_cluster.this.id }

Les versions de Kubernetes prises en charge sont 1.34, 1.33, 1.32 et 1.31. Il convient donc de verrouiller une version connue pour fonctionner correctement dans la valeur par défaut du module et de permettre aux appelants de l'écraser. Les pools de Node peuvent utiliser des types de serveurs Dedicated Core ou vCPU, et un pool de Node a un maximum absolu de 100 nœuds, avec un maximum recommandé de 20. Il est donc préférable de valider node_count par rapport à ces limites plutôt que de laisser une erreur de frappe provisionner un pool de taille excessive.

6.2 Utilisation du module

module "taskboard" {
  source     = "./modules/k8s-service"
  name       = "taskboard-prod"
  node_count = 3
}

output "taskboard_cluster" {
  value = module.taskboard.cluster_id
}

Versionnez votre dépôt de module avec des étiquettes git et référencez une étiquette spécifique dans source afin qu'une modification en aval du module ne modifie pas silencieusement une pile existante. C'est ainsi qu'une équipe transforme un déploiement fonctionnel en bibliothèque réutilisable.

Fiche de référence rapide de l'API

Principales extrémités utilisées par les pipelines CI/CD sur IONOS CLOUD :

Méthode Extrémité Description
POST /containerregistries/registries/{id}/tokens Créer un jeton de registre pour CI
GET /k8s/{clusterId}/kubeconfig Récupérer le kubeconfig pour le déploiement
GET /k8s/{clusterId}/nodepools Lister les pools de nœuds d'un cluster
GET /requests/{requestId}/status Interroger l'opération asynchrone jusqu'à DONE
DELETE /containerregistries/registries/{id}/repositories/{name} Supprimer un dépôt (nom encodé en URL)

URL de base : https://api.ionos.com/cloudapi/v6 Authentification : Authorization: Bearer <token>

Atelier de code

Objectif : Créer un pipeline GitHub Actions qui construit, pousse et déploie TaskBoard sur Managed Kubernetes à chaque poussée vers main.

Prérequis :

  • Compte IONOS CLOUD avec jeton API (IONOS_TOKEN)
  • Un Container Registry et un cluster Managed Kubernetes existants (issus des Unités 3.1 et 3.2)
  • Un dépôt GitHub pour l'application TaskBoard
  • docker, kubectl et ionosctl installés localement

Étape 1 : Créer un jeton de registre pour l'IC

ionosctl container-registry token create \
  --registry-id "$REGISTRY_ID" --name ci-deploy

Sortie attendue :

TokenId    Name        Status   ExpiryDate
a1b2c3d4   ci-deploy   enabled  -
Password: <shown once - copy it now>

Étape 2 : Stocker les secrets dans GitHub

gh secret set CR_USERNAME --body "ci-deploy"
gh secret set CR_PASSWORD --body "<password from step 1>"
gh secret set KUBECONFIG  --body "$(ionosctl k8s kubeconfig get \
  --cluster-id "$CLUSTER_ID" | base64 -w0)"

Sortie attendue :

✓ Set secret CR_USERNAME
✓ Set secret CR_PASSWORD
✓ Set secret KUBECONFIG

Étape 3 : Ajouter le fichier de flux de travail Valider .github/workflows/deploy.yml de la section 2.2 dans le dépôt. Sortie attendue :

[main 9f3c1ab] add deploy workflow
 1 file changed, 38 insertions(+)

Étape 4 : Déclencher le pipeline

git commit --allow-empty -m "trigger deploy"
git push origin main

Sortie attendue :

To github.com:you/taskboard-app.git
   8d2e1f0..9f3c1ab  main -> main

Étape 5 : Observer l'exécution

gh run watch

Sortie attendue :

✓ build-and-deploy succeeded
  ✓ Build and push image
  ✓ Deploy to Managed Kubernetes

Étape 6 : Vérifier le déploiement sur le cluster

kubectl get deployment taskboard-api -o wide

Sortie attendue :

NAME            READY   IMAGE
taskboard-api   3/3     taskboard.cr.de-fra.ionos.com/taskboard-api:9f3c1ab

Liste de contrôle de validation :

  • [ ] L'image avec l'étiquette git-SHA existe dans Container Registry
  • [ ] L'image de déploiement correspond à l'étiquette poussée
  • [ ] kubectl rollout status a signalé une réussite dans le pipeline
  • [ ] Un second envoi produit une nouvelle étiquette SHA et une mise à jour progressive propre

Nettoyage :

gh secret delete CR_USERNAME CR_PASSWORD KUBECONFIG
ionosctl container-registry token delete --registry-id "$REGISTRY_ID" --token-id "$TOKEN_ID"

Erreurs courantes

Erreurs de développement à éviter avec CI/CD sur IONOS CLOUD :

  1. Codage en dur du nom d'hôte du registre avant que le registre ne soit en état Running

    • Problème : Le pipeline échoue lors de la commande docker login avec une erreur de résolution DNS pour un nom d'hôte vide.
    • Cause : Le nom d'hôte du registre n'est attribué que lorsque le registre atteint l'état Running, de sorte qu'un registre nouvellement provisionné n'a pas encore de nom d'hôte.
    • Correction : Lire le nom d'hôte à partir de la sortie Terraform au lieu de le coder en dur, et conditionner la tâche de push à la disponibilité du registre :
    output "registry_hostname" { value = ionoscloud_container_registry.this.hostname }
    
  2. S'attendre à ce qu'un Service Kubernetes de type LoadBalancer soit un équilibreur de charge externe à part entière

    • Problème : Le débit plafonne et l'IP source de chaque requête apparaît comme une adresse interne au cluster, ce qui compromet la limitation de débit et les journaux d'audit.
    • Cause : Un Service de type LoadBalancer sur Managed Kubernetes ne provisionne pas d'équilibreur de charge externe. IONOS CLOUD réserve une IP publique statique et l'assigne comme IP secondaire à un nœud worker, puis kube-proxy applique le NAT au trafic vers le pod, ce qui limite le débit au plafond public de ce nœud unique et fait perdre l'IP source.
    • Correction : Définissez externalTrafficPolicy: Local pour conserver l'IP source, et placez un Managed ALB provisionné séparément devant le service, ou répartissez le trafic sur plusieurs IP d'équilibreur de charge pour dépasser le débit d'un nœud unique :
    spec:
      type: LoadBalancer
      externalTrafficPolicy: Local
    
  3. Exécution de Terraform avec un état local dans CI/CD

    • Problème : Chaque exécution du pipeline démarre avec un état vide, de sorte que terraform apply tente de recréer des ressources qui existent déjà et génère des erreurs en cas de noms en double.
    • Pourquoi cela se produit : Les agents CI effectuent un déploiement d'un espace de travail propre sans fichier d'état, et il n'y a aucun backend partagé.
    • Solution : Configurez le backend Object Storage compatible S3 afin que toutes les exécutions partagent l'état, et fournissez les identifiants Access Key et Secret Key en tant que secrets du pipeline :
    export AWS_ACCESS_KEY_ID="$IONOS_S3_KEY"
    export AWS_SECRET_ACCESS_KEY="$IONOS_S3_SECRET"
    terraform init
    

Résumé

Vous pouvez désormais piloter la boucle complète de construction, de test et de déploiement à partir d'un seul git push. Le pipeline applicatif construit un conteneur, l'étiquette avec le SHA git, s'authentifie auprès de IONOS CLOUD Container Registry via une connexion docker basée sur jeton, pousse l'image et la déploie sur Managed Kubernetes avec un kubectl set image et un kubectl rollout status conditionnés par un contrôle de disponibilité. Le pipeline d'infrastructure garantit la rigueur de Terraform en planifiant sur les demandes d'extraction (pull requests) et en appliquant uniquement lors de la fusion, avec un état partagé stocké dans Object Storage. En cas de problème, kubectl rollout undo et un commit Terraform annulé vous ramènent à un état valide connu, et votre bibliothèque de modules extraits permet au service suivant de réutiliser ces modèles au lieu de les recréer.

Points clés :

  • Séparez le flux applicatif (build -> test -> push -> deploy) du flux d'infrastructure (plan -> apply) ; ne partagez jamais un job entre les deux
  • Étiquetez chaque image avec le SHA git immuable, jamais :latest, afin que la révision en cours soit toujours traçable et que les retours arrière soient déterministes
  • Les jetons de Container Registry sont affichés une seule fois à la création et supprimés à leur expiration ; stockez-les comme secrets CI et récupérez les images avec les mêmes identifiants basés sur jeton
  • Exécutez terraform plan sur les PR et terraform apply lors de la fusion, avec un état partagé compatible S3 dans Object Storage et IONOS_TOKEN en tant que secret
  • Revenez en arrière sur les applications avec kubectl rollout undo et sur l'infrastructure en annulant le commit et en réappliquant

Terminologie importante :

  • Étiquette immuable : une étiquette d'image de conteneur dérivée du SHA git qui ne change jamais, reliant chaque pod en cours d'exécution au commit exact qui l'a construit.
  • Mise à jour progressive : la stratégie de déploiement Kubernetes par défaut qui remplace les pods de manière incrémentale afin que le service reste disponible pendant un déploiement.
  • Planification sur PR : le modèle CI de Terraform qui consiste à exécuter terraform plan sur les demandes d'extraction et à publier la différence pour relecture avant tout apply.
  • Backend d'état distant : un magasin d'état Terraform partagé (Object Storage compatible S3 sur IONOS CLOUD) qui permet à chaque exécution CI de lire et d'écrire le même état avec verrouillage.
  • imagePullSecret : un Secret Kubernetes contenant les identifiants de jeton de Container Registry afin que le cluster puisse récupérer des images privées.

Prochaines étapes

Continuer l'apprentissage : Unité 3.4 : Vérification des connaissances - Conteneurs et CI/CD

Sujets connexes :