Platform Engineering

Un environnement éphémère par merge request avec Terraform

Créer un environnement isolé à chaque MR, le détruire au merge, et ne jamais toucher à celui du voisin.

Relire un plan Terraform, c’est bien. Cliquer sur l’URL de l’environnement que la MR vient de créer, c’est mieux. Encore faut-il que cet environnement soit isolé, qu’il disparaisse tout seul et qu’un job de destruction ne puisse pas se tromper de cible.

Un identifiant stable

Tout part de l’IID de la MR, stable sur toute la vie de la merge request :

variables:
  ENV_ID: mr-$CI_MERGE_REQUEST_IID
  TF_STATE_KEY: development-mr-$CI_MERGE_REQUEST_IID-blog

Cet identifiant se retrouve dans le nom des ressources, leurs tags, la clé de l’état Terraform et le nom DNS (mr-42.blog.review.example.com). Deux MRs ne partagent rien.

Ne dérivez jamais la clé d’état d’une variable qui change d’un pipeline à l’autre, comme $CI_ENVIRONMENT_ID : le pipeline suivant repart d’un état vide et recrée tout à côté de l’existant.

Créer, puis arrêter

GitLab relie le job de déploiement à son job d’arrêt par environment:on_stop :

apply:mr:
  environment:
    name: development/mr-$CI_MERGE_REQUEST_IID/blog
    on_stop: destroy:mr
    auto_stop_in: 2 days

destroy:mr:
  environment:
    name: development/mr-$CI_MERGE_REQUEST_IID/blog
    action: stop
  when: manual

L’arrêt se déclenche au merge, à la fermeture de la MR, à la suppression de la branche ou à l’expiration de auto_stop_in.

Le piège du job d’arrêt

Le job d’arrêt est figé à la création du pipeline. Si le composant CI qui le définit est corrigé ensuite, les pipelines existants gardent l’ancienne version. Relancez un pipeline sur la MR avant de compter sur son arrêt.

Et le destroy doit être un vrai plan -destroy suivi de l’apply de ce plan, pas un apply normal sous un autre nom : sinon chaque arrêt… redéploie.

Garde-fous

  • les buckets des environnements de MR sont créés avec force_destroy ;
  • les ressources persistantes (zones DNS, données) ne sont jamais instanciées par MR ;
  • un job planifié liste les états development-mr-* dont la MR est fermée et les signale.