Aller au contenu
TerraformCloudAWS

Les modules Terraform : un guide pratique

Toutes les clés pour créer et publier un module Terraform complet et bien configuré, à partager au sein de votre entreprise ou publiquement avec la communauté.

Les modules Terraform

Parmi tous les concepts à connaître sur Terraform (providers, states, workspaces, etc.), il y a aussi les modules.

Les modules Terraform sont des collections autonomes et réutilisables de code d'infrastructure, permettant aux utilisateurs d'encapsuler et de partager des configurations pour des composants spécifiques, favorisant ainsi la facilité de maintenance dans les projets d'infrastructure as code.

Ils peuvent être utilisés au sein de votre entreprise ou partagés publiquement avec la communauté.

Dans cet article, nous allons créer un module de la manière la plus simple possible en décrivant la structure et en implémentant certaines best practices d'écriture et mécanismes de validation de code.

Un exemple simple

Pour illustrer la création d'un module, nous allons prendre le cas courant des buckets S3 à créer sur AWS.

Le découpage du module dépendra de vos besoins. Hashicorp ne recommande pas d'écrire des modules pour des wrappers de ressources publiques, car tous ces modules sont déjà rendus disponibles par la communauté.

Nous prenons ici un cas simple pour la démonstration, aussi si vous souhaitez fournir un module privé selon les standards de votre entreprise, il peut toujours être judicieux de faire un wrapper.

Nous allons implémenter la structure expliquée par Hashicorp, en créant uniquement les éléments de base qui nous intéressent. Nous veillons également à suivre les conventions de nommage recommandées.

Voici la structure que nous allons mettre en place, je vais décrire tous ces éléments.

├── .pre-commit-config.yaml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── examples
│   └── s3_bucket_simple.tf
├── main.tf
├── outputs.tf
├── variables.tf
└── versions.tf

Ressources principales

main.tf définit la ressource principale à créer, dans notre cas, le bucket s3 :

resource "aws_s3_bucket" "this" {
  bucket = var.name
  tags   = var.tags
}

resource "aws_s3_bucket_ownership_controls" "this" {
  bucket = aws_s3_bucket.this.id
  rule {
    object_ownership = "BucketOwnerPreferred"
  }
}

resource "aws_s3_bucket_acl" "this" {
  depends_on = [aws_s3_bucket_ownership_controls.this]
  bucket     = aws_s3_bucket.this.id
  acl        = "private"
}

variables.tf définit les variables que vous pouvez passer au module :

variable "name" {
  type        = string
  default     = null
  description = "Name for the bucket. If omitted, Terraform will assign a random, unique name."
}

variable "tags" {
  type        = map(any)
  default     = null
  description = "Details the tags to apply to the bucket"
}

outputs.tf définit les attributs que vous pouvez exporter depuis le module :

output "bucket_id" {
  value       = aws_s3_bucket.this.id
  description = "Bucket Name (aka ID)"
}

output "bucket_arn" {
  value       = aws_s3_bucket.this.arn
  description = "Bucket ARN"
}

output "bucket_name" {
  value       = aws_s3_bucket.this.bucket
  description = "Bucket Name"
}

et versions.tf définit les versions autorisées de Terraform et les fournisseurs pour utiliser le module :

terraform {
  required_version = ">=1.2"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 4.0, < 5.16.0"
    }
  }
}

Exemple d’utilisation

Un exemple est décrit dans le fichier examples/s3_bucket_simple.tf, vous pouvez l'utiliser pour vous inspirer dans l'utilisation du module :

module "test_s3" {
  source = "git::<https://github.com/mylab/terraform-s3-module.git?ref=0.0.4>"
  name   = "${var.workspace}-${var.env}-test-bucket"

  tags = {
    Name = "${var.workspace}-${var.env}-test-bucket"
    Env  = var.env
  }
}

Licence

Pour les dépôts publics, un choix courant est la GPL (General Public License) v3, elle offre de solides protections pour les logiciels open source, garantissant que toute modification ou distribution du code doit également être open source et librement accessible à la communauté.
Si vous n'êtes pas sûr de la licence que vous souhaitez attribuer au projet, vous pouvez vous rendre sur choosealicense.com.

Documentation

Il y a deux niveaux de documentation :

  • README.md donne des instructions pour utiliser le module
  • CONTRIBUTING.md fournit des instructions pour améliorer le module lui-même

Validation de la qualité pour les contributions

Lorsque les gens contribuent au projet, nous utilisons un outil appelé pre-commit, qui nous permet d'améliorer le code avant que les modifications ne soient partagées dans le dépôt.

Nous utilisons des scripts de validation, appelés hooks, notamment ceux de pre-commit-terraform.

.pre-commit-config.yaml définit les hooks que nous voulons exécuter avec pre-commit

repos:
- repo: <https://github.com/antonbabenko/pre-commit-terraform>
  rev: v1.85.0
  hooks:
    - id: terraform_fmt
    - id: terraform_tflint
    - id: terraform_checkov
    - id: terraform_docs

Terraform-fmt est une commande intégrée à Terraform pour garantir que le code est correctement formaté.

tflint vérifie que le code Terraform ne présente aucun problème de frappe ou d'oubli.

checkov évite de valider des ressources AWS présentant des vulnérabilités de sécurité, il analyse les ressources déployées et indique ce qui n'est pas conforme aux règles de bonnes pratiques de sécurité.

terraform-docs génère la documentation bien formatée dans le fichier README.md.

Exposition du module

Le module peut provenir d'un registre ou d'une référence locale/distante.

Pour une référence locale, vous pouvez l'appeler ainsi :

module "s3" {
  source = "./path/to/your/module"
…

Pour une référence à distance, vous avez le choix entre https et ssh :

# https
module "s3" {
  source = "git::<https://github.com/mylab/terraform-s3-module.git?ref=0.0.4>"
…

# ssh
module "s3" {
  source = "git@github.com:mylab/terraform-s3-module.git?ref=0.0.4"
…

Vous pouvez mettre le module sur le registry Terraform, mais vous pouvez très bien l'utiliser directement sans le référencer sur cette plateforme.

Si vous souhaitez le référencer pour le partager avec la communauté publique, il est assez simple d'y publier votre dépôt git. Il suffit de vous inscrire avec votre compte Github, de sélectionner votre dépôt et de cliquer sur « publier ».

Une bonne pratique consiste à créer des releases git taggées, afin de pointer dessus lors des appels de modules (vous pouvez également mettre à jour le changelog pour tracer les évolutions).

Conclusion

Vous avez maintenant toutes les clés pour créer et publier un module complet et bien configuré, à partager au sein de votre entreprise ou publiquement avec la communauté.

Dernier