> ## Content Index
> Fetch the complete content index at: https://www.sfeir.dev/llms.txt
> Use this file to discover other available public pages before exploring further.

# Les modules Terraform : un guide pratique
- URL: https://www.sfeir.dev/cloud/les-modules-terraform-un-guide-pratique/
- Published: 2025-01-31T08:29:53.000Z
- Updated: 2025-01-31T08:30:12.000Z
- Description: 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é.
- Author: Jérôme Devoucoux
- Tags: Terraform, Cloud, AWS

Parmi tous les concepts à connaître sur [Terraform](https://www.sfeir.dev/cloud/terraform-definition/) (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é](https://github.com/terraform-aws-modules?ref=sfeir.dev).

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](https://developer.hashicorp.com/terraform/language/modules/develop?ref=sfeir.dev), en créant uniquement les éléments de base qui nous intéressent. Nous veillons également à suivre les [conventions de nommage](https://www.terraform-best-practices.com/?ref=sfeir.dev) recommandées.

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

```bash
├── .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 :

```bash
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 :

```bash
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 :

```bash
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 :

```bash
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 :

```bash
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](http://choosealicense.com/?ref=sfeir.dev).

## 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](https://pre-commit.com/?ref=sfeir.dev), 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](https://github.com/antonbabenko/pre-commit-terraform?ref=sfeir.dev).

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

```bash
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**](https://developer.hashicorp.com/terraform/cli/commands/fmt?ref=sfeir.dev) est une commande intégrée à Terraform pour garantir que le code est correctement formaté.

[**tflint**](https://github.com/terraform-linters/tflint?ref=sfeir.dev) vérifie que le code Terraform ne présente aucun problème de frappe ou d'oubli.

[**checkov**](https://www.checkov.io/?ref=sfeir.dev) é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**](https://terraform-docs.io/?ref=sfeir.dev) 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 :

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

```

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

```bash
# 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](https://registry.terraform.io/?ref=sfeir.dev), 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é.