Faire usage des boucles count, for et for_each pour créer des ressources similaires avec Terraform
S'il y a une règle très important à suivre en codant, c'est de ne jamais se répéter. Dans cet article, nous allons vois comment est ce que nous pouvons utiliser une boucle dans Terraform pour éviter les répétition dans la création de ressources similaires.
Terraform est une infrastructure en tant qu'outil de code pour la création, la modification et la gestion des versions d'une infrastructure de manière sûre et efficace entre divers fournisseurs de cloud.
Notre but sera de créer plusieurs topic de PubSub sur Google Cloud Platform. Nous allons passer un ensemble de noms et nous espérons comme output, une list de dictionnaire ayant comme clé l'élément de l'ensemble et pour valeur l'id et le nom du topic. Quelque chose comme ceci
[
{
event = ""
id = ""
name = ""
},
{
event = ""
id = ""
name = ""
},
{
event = ""
id = ""
name = ""
},
]
Terraform propose 3 boucles différentes (for, for_each, count) et chacune est destinée à être utilisée dans un scénario légèrement différent.
count itère sur un nombre et retourne le nombre actuel comme index
.
resource "google_pubsub_topic" "topic" {
count = 2
name = count.index
}
Dans ce cas , name sera 0 ,1,2 à chaque incrémentation. Attention, count
commence par 0 et la valeur est incluse.
for
itère sur les listes (list) et les dictionnaire (map).
variable "regions" {
type = list(string)
default = ["europe-west1", "us-central"]
}
[for region in var.regions : upper(region)]
Ce code donnera
["EUROPE-WEST1", "US_CENTRAL"]
Il est aussi possible d'avoir l'index ainsi que la valeur a chaque iteeration
[for index, region in var.regions : upper("${index}-${region})]
Résultat:
["0-EUROPE-WEST1", "1-US_CENTRAL"]
Attention, quand la collection est un dictionnaire (map), l'index dans le cas de la liste deviendra la clé de l'élément.
for_each
itère les dictionnaires (map) et les sets de strings aussi, mais avec un petit différence. les éléments itéré sont disponible sous le mot-clé each.
each.key
donne la cléeach.value
donne la valeuvariable "events" {
type = map(object({
name = string
}))
default = {
in : { name : "in-event" },
out : { name : "out-event" },
}
}
resource "google_pubsub_topic" "events_topics" {
for_each = var.events
name = each.value.name
}
Dans ce cas, name dans la ressource events_topics
sera a chaque itération respectivement in-event
et out-event
.
Revenons maintenant sur notre objectif. Les codes préliminaires
variable "project_id" {
description = "Google Cloud Platform (GCP) Project ID"
type = string
default = "loopbin"
}
variable "region" {
description = "GCP region"
type = string
default = "europe-west1"
}
variable "events" {
type = list(string)
default = [
"users-auth-created",
"users-auth-blocked",
"users-auth-deleted",
]
description = "list of pubsub events related to user account"
}
Vu que la variable events
est une liste, nous ne pourrons pas utiliser for_each
. Il nous reste alors count
.
resource "google_pubsub_topic" "users_auth_topics" {
count = length(var.events)
name = "${var.events[count.index]}-topic"
}
output
output "users_auth_topics" {
description = "Users authentication related topics"
value = [for created_topic in google_pubsub_topic.users_auth_topics :
{ id = created_topic.id,
name = created_topic.name,
event = "${trimsuffix(created_topic.name, "-topic")}"
}
]
}
La commande terraform apply
nous donnera comme output
users_auth_topics = [
{
"event" = "users-auth-created"
"id" = "projects/loopbin/topics/users-auth-created-topic"
"name" = "users-auth-created-topic"
},
{
"event" = "users-auth-blocked"
"id" = "projects/loopbin/topics/users-auth-blocked-topic"
"name" = "users-auth-blocked-topic"
},
{
"event" = "users-auth-deleted"
"id" = "projects/loopbin/topics/users-auth-deleted-topic"
"name" = "users-auth-deleted-topic"
},
]
Boom c'est fini 😎. J'espère que vous avez bien compris et aimé.