Les bonnes pratiques Terraform

Les bonnes pratiques Terraform

Publié le


Do not index
Do not index
Primary Keyword
Lié à Analyse sémantique (Articles liés) 1
Lié à Analyse sémantique (Articles liés)
Statut rédaction
Terminé
Lié à Analyse sémantique (Articles liés) 2

Introduction

Créer un code de qualité en Terraform qui ne génère pas de surprise sur la facture et qui est réutilisable pour plusieurs projets peut être challengeant.
Voici un ensemble de règles que nous appliquons chez Keltio lorsque nous codons en Terraform.

0. Avoir une structure de projet normalisé

Terraform lit tous les fichiers avec des extensions .tf. Vous pouvez avoir autant de fichiers que vous le souhaitez.
Cependant, il est préférable d'avoir une structure propre afin que tout le monde dans l'équipe puisse comprendre et participer au projet.
Voici le format suggéré à suivre :
  • regrouper les ressources du même type dans un fichier .tf (Réseau, stockage, compute …)
  • avoir un fichier README.md pour avoir une description du projet et des informations telles que les entrées, les sorties. Vous pouvez utiliser des outils comme terraform-docs pour générer ce fichier
  • avoir un fichier fournisseur provider.tf pour définir les fournisseurs dans votre projet
  • avoir un fichier de version version.tf pour indiquer à terraform quelles versions de terraform et de fournisseur doivent être utilisées
  • avoir un dossier de documentation docs/ pour mettre la documentation pertinente sur le projet
Si le projet est grand, envisagez de le diviser en plusieurs sous-projets pour que le nombre de ressources dans chaque sous-projet ne soit pas trop important (par exemple : 100 ressources).

1. Bien lire la documentation Terraform

Cela peut sembler évident, mais en réalité, la lecture de la documentation est de loin la pratique la plus sous-estimée lorsque vous travaillez avec Terraform.
L’un des aspects qui différencie Terraform des autres projets est le travail incroyable que HashiCorp a réalisé avec la documentation officielle.
Que vous ayez des questions concernant la syntaxe HCL, la configuration Terraform, l’API, l’intégration VCS ou les espaces de travail Terraform, la documentation officielle devrait être votre point de départ. Cela vous permet d’économiser de nombreuses heures de recherche et peut même vous éviter de faire des erreurs lors de l’utilisation de configurations ou de conseils qui ne sont plus valides dans les versions les plus récentes de Terraform.
En d’autres termes, en lisant la documentation officielle de Terraform, vous :
  • Évitez d’avoir des surprises de coûts et de instabilité sur vos infras
  • Améliorez la sécurité de votre code.
  • Évitez de faire des erreurs ou d’introduire des régressions lors de l’utilisation de code qui n’est plus valide,

2. Indentation

Utiliser la commande terraform fmt pour auto aligner le code
Le résultat doit ressembler à ça :
notion image

2. Variabilisation

Dans les modules ne jamais mettre de valeur en dur sauf si l’infrastructure casse si la valeur est différente. Utiliser des variables avec des valeurs par défaut plutôt

3. Commentaire

S’il y a une partie dans le code un peu complexe ou avec des subtilités ajouter des commentaires.

4. Module sans contexte métier

Les modules doivent pouvoir être réutilisables et configurables. Il ne faut donc pas mettre d'élément en dur spécifique à un seul projet.

5. Tags

Afin de permettre de faire des analyses sur les ressources utilisés sur le clouds et donc d’avoir des estimations sur les coûts par projet / environnement … il est très fortement recommandé d’ajouter un maximum de tags sur les ressources (compute, network, storage…)
Voici quelques exemples de tags intéressants à mettre sur ses ressources :
  • project
  • stage
  • environment
  • owner

6. Nommage des ressources

Les modules doivent pouvoir être lancés à plusieurs reprises. Il faut donc que chaque ressources aient des noms configurables.
En règle général afin de pouvoir dissocié des ressources facilement des préfixes peuvent être ajoutés dans les noms des ressources

7. Utilisation des variables locales

Afin d’éviter les erreurs dans le code et faciliter la réutilisation de code il est conseillé de créer des variables locales dès lors que l’on réalise des opérations pour générer une variable.
Voici un exemple :
notion image

8. Répartition des ressources dans les fichiers tf

Plus les infras sont grosses, plus le nombre de ressources devient important. Il faut donc soit exporter une partie du code en module (si réutilisable dans d’autres projets de la même façon) soit mettre toutes les ressources qui répondent au même besoin dans un fichier tf dédié.
Voici un petit exemple de ce que ça peut donner :
notion image

9. Gestion du tfstate

Ne jamais gérer le tfstate en local. Il faut toujours créer un backend pour stocker l’état de votre infra (S3 + DynamoDB, Terraform cloud …).
Si vous perdez accidentellement le fichier d'état terraform, terraform essaiera de dupliquer les mêmes ressources au lieu de sauter celle existante.
Il est grandement recommandé d’utiliser des backends mettant en place le locking du tfstate. De cette façon si un de vos collègues modifie en même temps l’infra que vous, vous n’aurez pas de problème de désynchronisation du tfstate.

10. Secrets

Aucune valeur confidentielle ne doit être présente dans le code. Si les infras ont des données sensibles alors utilisez les services de gestion de secret de votre cloud provider.

11. Documentation

Afin d’assurer une bonne réutilisation du code, une bonne documentation de ses modules et infra est primordial. Ca tombe bien une librairie Terraform existe pour générer automatiquement sa documentation Terraform (https://github.com/terraform-docs/terraform-docs )
Lorsque vous définissez des variables sous Terraform, il est très fréquent de ne pas voir de type ni de description. Ces éléments sont souvent les seuls éléments qui vont permettre à vos collègues de réutiliser le code facilement.

13. Mettre en place des git hooks pour analyser la qualité du code (sécurité, propreté)

14. N’utiliser count que pour les conditions

Lorsque l’on utilise count pour réaliser des boucles, les ressources générées dans le tfstate, apparaissent de la façon suivante : aws_instance.my_instances[0] .
Cela peut poser un problème si l’on souhaite réaliser des imports de ressources dans le tfstate par la suite.
Une bonne pratique est donc d’utiliser un for_each et de nommer les ressources. De cette façon le tfstate sera plus compréhensible et les ressources apparaitront de la façon suivante : aws_instance.my_instances["<Nom nom d'instance>"]

15. Utilisation de for_each

Lorsque l'on utilise un for_each, il est important de le mettre en premier dans le bloc de définition de la ressource et d’y ajouter un saut de ligne.
De cette façon, il sera facile de comprendre que le bloc comprend une liste de ressources.
A la place de ceci :
resource "azurerm_subnet" "private_subnet" {
  resource_group_name  = azurerm_virtual_network.ketio_vnet.resource_group_name
  virtual_network_name = azurerm_virtual_network.ketio_vnet.name
  for_each             = var.subnet_private
  name                 = each.key
  address_prefixes     = each.value
}
Il faudra donc faire cela :
resource "azurerm_subnet" "private_subnet" {
  for_each             = var.subnet_private

  resource_group_name  = azurerm_virtual_network.ketio_vnet.resource_group_name
  virtual_network_name = azurerm_virtual_network.ketio_vnet.name
  name                 = each.key
  address_prefixes     = each.value
}

16. Convention de nommage pour les variables

Essayez de suivre une convention de nommage cohérente non seulement pour les ressources créées par Terraform, mais aussi pour les noms des ressources et des fichiers Terraform.
Certaines ressources doivent être nommées de manière unique à l'échelle mondiale, par exemple, un bucket AWS S3. Vous pouvez envisager de définir des variables locales contenant le préfixe de nom de vos ressources. Un exemple de préfixe de nom serait <resource-type>-<organization name>-<environment>.
 
Afin de garantir une réutilisation forte de nos modules. Voici les conventions de nommage que nous appliquons chez Keltio.
Pour les booléens :
  • Doit commencer par le prefix is_

17. Utilisez des outils d’analyse de qualité et de sécurité du code

Voici les outils au minimum à mettre en place :
  • tflint - pour effectuer le linting terraform
  • tfsec - pour analyser la sécurité de la configuration du code
  • terraform validate - pour valider le bon fonctionnement du code
  • terraform fmt - pour formater le code proprement
  • checkov (optionnel) - pour effectuer une analyse de sécurité
  • bridgecrew (optionnel) - une version premium de checkov, elle peut aider à générer des rapports de conformité de sécurité
Vous pouvez exécuter les outils mentionnés avec pre-commit afin que, avant chaque fois qu'un git push est effectué, votre code soit validé par ces outils.

Pour aller plus loin, vous pouvez lire les articles suivants :

S'inscrire à la newsletter DevSecOps Keltio

Pour recevoir tous les mois des articles d'expertise du domaine

S'inscrire

Écrit par

Kévin Didelot
Kévin Didelot

Kévin est notre super expert DevSecOps et le fondateur de Keltio 👨🏻‍💻