Trop de bûche? c'est l'heure de la remise en Terraform
Alors comme ça, tu as abusé pendant les fêtes ? Tu as le foie plus gras que celui que tu as mis sur tes toasts ? Tu as fini tout le saumon gravlax ? Tu as passé ton 1er à parler à ta cuvette de toilette ?
Pas de soucis mon ami, j’ai ce qu’il te faut pour reprendre une année dans les bonnes dispositions :) 30% de réduction sur un abonnement basic-fit avec le code créateur “JAIVOMIMABUCHE”.
J’ai réalisé que pendant un moment, j’ai choppé des infos çà et là sur de bonnes pratiques et sur des façons de faire du Terraform, mais je n’ai jamais partagé ici. Parce qu’en fait quand on y pense, Hashicorp ne s’est jamais vraiment mouillé dans la doc officielle sur la gestion multienv du code, sur l’organisation des répertoires et sur la modularité du code.
Pour certains ça sera du réchauffé picard de Noël; mais je mettrai quelques petits trucs inédits que je n’ai jamais partagés qui peuvent aider, à vous de voir si ça à du sens ou pas.
On va surtout faire du GCP dans nos exemples, mais c’est tout à fait transposable sur d’autres technos bien sûr :)
Cette introduction est rédigée par ChatGPT, c’est incroyable non ? (c’est faux, mais c’est pour mon référencement ! Pour me faire pardonner, je vous mets un dall-E d’un chat qui pète)
Utiliser un remote backend
Bon celle-ci est à la fois noob et en même temps pas si triviale que ça, on déballe les banalités et ensuite on regarde en peu plus en détail ce que je te recommande.
Terraform fonctionnant sur un système d’état différentiel, il est primordial de conserver les fichiers tfstate représentant l’état de vos ressources au moment du dernier apply dans un endroit sécurisé, et c’est aussi la seule bonne façon de partager le state entre plusieurs personnes sans tout péter.
Ma préconisation quand on fonctionne avec plusieurs environnements, c’est de mettre un bucket régional sur chacun des environnements sur lequel tu travailles.
Voici les raisons de cette affirmation:
- si on décide de supprimer un env, on supprime l’env et le bucket associé sans polluer les autres envs.
- pas de contact entre les environnements, si un bucket est compromis, ça ne concerne que l’env concerné.
- moins de risque de se tromper de bucket si on fait des ops nécessitant des actions tf manuelles.
- le régional est important pour assurer un HA en cas de zone temporairement indisponible (moins de risque de perte de state)
Ça implique d’avoir le remote bucket hardcodé dans la conf des dossiers tf ou via une variable à l’init, on y revient plus tard, mais bien outillé ce n’est pas forcément un problème. Utiliser le même remote backend pour tout les envs en utilisant les workspaces en plus d’avoir plus de risques de se tromper apporte une adhérence entre les environnements.
Et même si tout le monde le fait c’est écrit dans la documentation de Terraform que c’est une mauvaise pratique.
https://developer.hashicorp.com/terraform/language/state/workspaces
Important: Workspaces are not appropriate for system decomposition or deployments requiring separate credentials and access controls.
Refer to Use Cases in the Terraform CLI documentation for details and recommended alternatives.
Découper votre infrastructure en petits dossiers fonctionnels
Plus tu travailles sur un nombre important de ressources et plus les apply seront long et plus tu risques de péter des trucs dans ton infra. Deuxième effet kiss kool, tu lock toutes tes ressources et réduit la capacité de travailler en équipe en verrouillant toutes les ressources à chaque apply.
Un dernier point pas du tout négligeable, c’est qu’on veut au maximum éviter de manipuler des ressources critiques si on n’a pas besoin de les modifier. Genre les VPC, les adresses IP réservées les interconnexions, c’est typiquement les ressources qu’on deploy une fois et qu’on touche plus ensuite. Les activations d’API sont particulièrement longues et pénibles, on voudrait pouvoir activer une nouvelle API et continuer de travailler sur autre chose en même temps.
Une façon d’ordonnancer les dossiers, c’est de les préfixer avec un numéro. Attention à ne pas utiliser cette numérotation dans le remote prefix, on veut pouvoir changer l’ordre des numéros de dossier sans avoir à impacter le remote state. ça nous donne un truc comme ça :
|
|
Cette organisation implique d’utiliser des datasources pour accéder aux attributs des ressources qu’on veut partager. Dans cet exemple on voudrait utiliser le VPC* dans le gitlab runner, au lieu de faire un lien direct avec la ressource, on va plutôt utiliser un datasource.
|
|
Ce qui implique de connaître le nom du réseau qu’on veut récupérer, qu’on peut choisir de mettre en dur comme ici, ou via une variable. Ce qui m’amène à transiter sur le partage de variable globale pour l’environnement. Notre fichier source_env.sh contiendra toutes les variables qu’on veut partager entre nos dossiers.
Premier cadeau, voici un script qui va générer ce dossier de squelette prêt à fonctionner.
https://github.com/helldrum/bootstrap_terraform_folder
L’idée c’est de construire un dossier qui respecte la convention de nommage et qui contiendra le backend configuré et le fichier de variable tf avec la variable projet.
|
|
Fonctionnellement il te manquera la variable d’env TF_VAR_project qui contiendra ton nom de projet GCP et un moyen d’authentification avec GCP sur ce projet. Tu peux utiliser la variable GOOGLE_APPLICATION_CREDENTIALS=/path/service/account/d79c867debaa.json de cette façon, ou configurer le default account gcloud.
|
|
On découpe tout ça en petits bouts et on fait des paquets cadeau :)
Et le numéro complémentaire
Quand on travaille en équipe, c’est possible qu’à partir d’un moment on se retrouve avec des numérotations de dossier en conflit ou des briques oubliées qui doivent être créées avant.
Du coup, renommer tous les dossiers manuellement c’est une corvée qu’on voudrait éviter, surtout quand on commence à avoir beaucoup de dossiers.
Du coup premier outils de ma liste du père Noël, un script python qui permet de gérer cette numérotation.
Petit ajout en plus, un paramètre d’exclusion de dossier, au cas où tu traînes des exceptions :)
Je te mets le lien github directement
https://github.com/helldrum/rename_tf_folders
Par exemple j’ai fait un trou dans ma numérotation
|
|
le script va me proposer cette configuration de renommage
|
|
Si je souhaite faire une exclusion de private VPC et james bond je fais comme ça
|
|
Conserver une configuration flat sur tout les envs
Il faut traiter Terraform comme de la configuration et éviter de mutualiser et partager le même dossier pour plusieurs envs. À tout moment on devrait pouvoir changer le code dans un env sans impacter les autres.
Opinion impopulaire, mais il vaut mieux un environnement un peu déviant, mais complètement tracé en Terraform, que des modifications manuelles intraçables qui reviennent ensuite vous péter à la tronche.
C’est pourquoi il vaut mieux dupliquer le code des ressources pour chaque environnement et avoir une configuration flat à chaque instant.
La duplication et le différentiel d’env peuvent être source de problèmes si on le gère manuellement, c’est pourquoi sur les gros projets je te conseille de t’outiller pour faire cette tâche.
Pour ça j’ai dev un outil qui permet de faire des diffs entre environnements, en excluant le remplissage des variables, la configuration du backend et les fichiers système Terraform.
L’idée étant de ne montrer que les différences de création de ressources, pour repérer les divergences.
J’essaye de diversifier mon audience, voici un différentiel mécanique, pas mal non ?
je vous mets le code de mon script directement ici
https://github.com/helldrum/terraform_diff_envs
|
|
dans notre cas on a 2 dossiers en plus en dev [‘008_gke_cluster’, ‘007_james_bond’] et une divergence de fichiers entre prod et dev sur 000_enable_api/api.tf
C’est intéressant de mettre un coup de terraform fmt sur tout les dossiers pour garder une cohérence de formatage (certains utilisent des IDEs qui le font directement, certains non).
un petit oneliner un peu claqué au sol pour faire ça :)
|
|
Vous comprendrez que du coup ce n’est pas beaucoup plus compliqué de lancer tout ou partie de l’infra en cicd ou manuellement.
Faut juste pas se louper en faisant la loop :)
dernier petit truc, si on veut copier les dossiers d’un env a un autre sans risquer de casser le remote backend ou la configuration ce bon vieux rsync, toujours la pour sauver les miches :)
|
|
Alors oui, ça fait faire pas mal de bordel, mais la faute à qui hein ? Merci hashicorp de ne pas fournir de vrai standard et de solide bonne pratique pour gérer convenablement les environnements multiples.
Je vous laisse ici une petite référence discrète https://www.terraform-best-practices.com/references
Utiliser les modules, seulement quand vous comprenez comment ils marchent
Les terraform module sont une très bonne chose à condition de maitriser 100% de leur fonctionnement, parce que une fois en prod, les conséquences peuvent être dramatiques. On abstrait de la complexité dans un but de packaging de ressources, mais si on ne comprend pas le fonctionnement des ressources et la manière dont elles sont connectées, on peut casser des choses :)
D’une manière générale, mais c’est mon point de vue, si vous n’avez pas l’intention de réutiliser les ressources, rester simple, ne packager pas. Terraform est un outil fait pour faire des choses simples, mais les gens aiment l’utiliser de manière compliquée et tordue.
Le mot de la fin
J’espère que certains d’entre vous on appris des choses :)
Bien évidemment cette organisation n’engage que moi, mais je trouve que c’est un très bon compromis entre la gestion du chaos, la collaboration d’équipe et la modularité. Un grand big up à Thomas Poindessous et Yann Coleu si vous passez par ici, et également aux anciens et nouveaux skalers :)
J’aurais dû le faire depuis un moment, mais il y à un moment pour recevoir, et un moment pour transmettre !
Alors je vous invite à prendre votre plume la plus déglinguée et faire des articles, même si encore aujourd’hui je ne sais pas qui me lis vraiment et quelle mauvaise influence j’ai sur vous :)
Je vois que de plus en plus de bots de Singapour me rendent visite, mais également que la France est enfin devenue ma principale audience, merci à vous !
Je vous souhaite à tous une bonne année !