Deux boutiques, une seule recette
Une société tient une boutique au coin de la rue et une autre sur la colline. Les deux ont besoin de la même installation. Copier les fichiers marche, jusqu’au jour où il faut corriger quelque chose : on le corrige deux fois.
Un module est la recette écrite une seule fois. Chaque boutique l’appelle avec ses propres valeurs.
À la fin de cette leçon
Remarque
Je peux appeler un module deux fois et lire ce que chaque copie renvoie.
Mots-clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Module | un dossier de fichiers que l’on peut réutiliser | |
| Appel de module | un bloc qui utilise un module et lui donne des valeurs | module "colline" |
| Sortie | une valeur qu’un module renvoie | |
| Validation | une règle qui refuse une mauvaise entrée | |
| Adresse de module | le chemin d’une ressource, qui commence par module | module.colline.terraform_data.enseigne |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Un module est un dossier que l’on appelle
Un module est un dossier de fichiers OpenTofu. Le projet qui l’utilise est la racine. La racine écrit un appel de module, nomme le dossier dans source et donne une valeur à chaque entrée.
Deux appels font deux copies séparées de tout ce que contient le dossier. Ici la source est un chemin local, donc rien n’est téléchargé.
Créer les dossiers et y entrer
mkdir -p ~/atelier-iac/modules/modules/boutique && cd ~/atelier-iac/modulesAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire le module
printf '%s\n' 'variable "nom" {' ' type = string' ' validation {' ' condition = length(var.nom) >= 3 && length(var.nom) <= 10' ' error_message = "Le nom doit avoir de 3 à 10 caractères."' ' }' '}' '' 'resource "terraform_data" "enseigne" {' ' input = format("%s : ouvert", var.nom)' '}' '' 'output "enseigne" {' ' value = terraform_data.enseigne.output' '}' > modules/boutique/main.tfAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire la racine : deux appels, une sortie
printf '%s\n' 'module "coin" {' ' source = "./modules/boutique"' ' nom = "Coin"' '}' '' 'module "colline" {' ' source = "./modules/boutique"' ' nom = "Colline"' '}' '' 'output "enseignes" {' ' value = [module.coin.enseigne, module.colline.enseigne]' '}' > main.tfAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Préparer le dossier
tofu init -no-color | grep -E "Initializing modules|coin|colline|successfully"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Planifier et regarder les adresses
tofu plan -no-color | grep -E "will be created|^Plan"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Un module renvoie des sorties
Une ressource dans un module a une adresse plus longue, comme module.colline.terraform_data.enseigne. La racine ne peut pas la lire directement.
Seule une sortie traverse le mur. La racine la lit sous la forme module.colline.enseigne : le nom de l’appel, puis le nom de la sortie.
Appliquer, pour que l’état contienne les deux copies
tofu apply -auto-approve -no-color | grep "Apply complete"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Lister les adresses de l’état
tofu state listAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Lire la sortie que la racine a faite
tofu output enseignesAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Erreur fréquente
Attention
Beaucoup pensent que la racine peut lire n’importe quelle ressource d’un module. Ce n’est pas le cas. Un module ne partage que ce que ses sorties nomment : une valeur voulue à l’extérieur a besoin d’un bloc output.
Lire une ressource sans sortie
printf '%s\n' 'output "mauvaise" {' ' value = module.coin.terraform_data.enseigne' '}' > mauvaise.tf; tofu validate -no-color 2>&1 | grep -E "Error|Unsupported"; rm mauvaise.tfAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Une règle de validation refuse une mauvaise entrée
Un bloc validation contient une condition et un error_message. Quand la condition est fausse, OpenTofu s’arrête avant de planifier quoi que ce soit et affiche le message.
Le module accepte un nom de 3 à 10 caractères. Essayez un nom trop court.
Donner un nom trop court à la colline
sed -i 's/"Colline"/"Co"/' main.tf; tofu validate -no-color 2>&1 | grep -E "Error|doit avoir"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Remettre le nom et vérifier
sed -i 's/"Co"/"Colline"/' main.tf; tofu validate -no-colorAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Deux appels calculés en Python
# Calculer les adresses que fait un appel de module.
ressources = ["enseigne", "porte"]
appels = {"coin": None, "colline": None}
for appel in appels:
for nom in ressources:
print("module." + appel + ".terraform_data." + nom)
# Remplacez "colline": None par "colline": ["a", "b"] et regardez de nouveau.
Maintenant, dans le labo
Les Run ont construit un module dans un dossier d’essai. Le labo a lui aussi un dossier pour cela, ~/tofu-lab/shop, et la partie 7 de son README (en anglais) dit quoi construire. Ce n’est pas le même module : il faut changer ce que vous avez vu, pas le copier.
Comment c’est noté
Votre enseignant le note en lançant une vérification sur votre labo enregistré. La vérification applique votre projet, puis appelle de nouveau votre module avec des noms et un statut que vous n’avez jamais vus. Un module où les réponses sont tapées ne peut pas les suivre, ni un module sans règle de validation.
Pour aller plus loin : un appel avec count
Ajoutez count = 2 à l’appel colline, et remplacez module.colline.enseigne dans la sortie par module.colline[0].enseigne. Lancez tofu plan -no-color | grep -E "will be|^Plan".
Quelles adresses le plan montre-t-il maintenant, et pourquoi la ligne de sortie devait-elle changer ?