TP 4 : Plusieurs conteneurs avec for_each
Objectif
Section intitulée « Objectif »Créer plusieurs conteneurs Docker à partir d’une map Terraform avec for_each.
Cette méthode est plus adaptée que count lorsque chaque ressource a une configuration différente, car Terraform identifie chaque ressource par une clé nommée et non par un index numérique. Ajouter ou supprimer un élément n’affecte pas les autres ressources.
Prérequis
Section intitulée « Prérequis »- Terraform installé
- Docker installé et lancé
terraform versiondocker versionArborescence
Section intitulée « Arborescence »tp-terraform-for-each/├── main.tf├── variables.tf├── outputs.tf└── .gitignoreFichier .gitignore
Section intitulée « Fichier .gitignore ».terraform/*.tfstate*.tfstate.**.tfvars.terraform.lock.hclFichier variables.tf
Section intitulée « Fichier variables.tf »variable "containers" { description = "Liste des conteneurs à créer" type = map(object({ image = string external_port = number }))
default = { nginx = { image = "nginx:latest" external_port = 8080 }
apache = { image = "httpd:latest" external_port = 8081 }
caddy = { image = "caddy:latest" external_port = 8082 } }}Fichier main.tf
Section intitulée « Fichier main.tf »terraform { required_providers { docker = { source = "kreuzwerker/docker" version = "~> 3.0" } }}
provider "docker" {}
resource "docker_image" "images" { for_each = var.containers
name = each.value.image}
resource "docker_container" "web" { for_each = var.containers
name = each.key image = docker_image.images[each.key].image_id
ports { internal = 80 external = each.value.external_port }}Avec
for_each, Terraform expose deux mots-clés dans le bloc de ressource :
each.key: la clé de la map, ici"nginx","apache"ou"caddy": utilisée comme nom du conteneur.each.value: l’objet associé à cette clé, ici{ image = "...", external_port = ... }.Terraform crée ainsi
docker_container.web["nginx"],docker_container.web["apache"]etdocker_container.web["caddy"]: des identifiants stables qui ne changent pas si l’on ajoute ou retire un autre élément de la map.
Fichier outputs.tf
Section intitulée « Fichier outputs.tf »output "container_urls" { description = "URLs des conteneurs créés" value = { for name, container in var.containers : name => "http://localhost:${container.external_port}" }}Commandes
Section intitulée « Commandes »terraform initterraform fmtterraform validateterraform planterraform applyVérification
Section intitulée « Vérification »Ouvrir :
http://localhost:8080http://localhost:8081http://localhost:8082Ou tester avec curl :
curl http://localhost:8080curl http://localhost:8081curl http://localhost:8082Modification : ajouter un quatrième conteneur
Section intitulée « Modification : ajouter un quatrième conteneur »Ajouter l’entrée traefik dans le bloc default de la variable containers dans variables.tf :
default = { nginx = { image = "nginx:latest" external_port = 8080 }
apache = { image = "httpd:latest" external_port = 8081 }
caddy = { image = "caddy:latest" external_port = 8082 }
traefik = { image = "traefik:v3.0" external_port = 8083 }}Puis exécuter :
terraform planterraform applyTerraform doit proposer uniquement la création de docker_container.web["traefik"] et docker_image.images["traefik"], sans toucher aux trois conteneurs existants.
C’est l’avantage de
for_eachsurcount: ajouter ou supprimer un élément nommé n’affecte pas les ressources dont la clé n’a pas changé.
Nettoyage
Section intitulée « Nettoyage »terraform destroy