Aller au contenu

Utilisation des meta-arguments Terraform

logo terraform

Terraform est un langage déclaratif, alors comment rendre ce code un plus intelligent ? Comment imposer certains fonctionnements lors de la création, modification et destruction de ressources ? Comment éviter de dupliquer du code ? Nous allons voir tout cela avec l’utilisation des meta-arguments.

Les meta-arguments

Les meta-arguments sont des constructions spéciales qui peuvent être utilisé sur les blocs ‘Resource’ et ‘Module’. Ils sont au nombre de cinq : depends_on, count, for_each, provider et lifecycle

depends_on

Ce meta-argument permet de définir des dépendances entre Resource, là ou Terraform n’arrive pas à les détecter. C’estdonc souvent pour attendre la fin de la création d’une Resource pour en exécuter une autre. depends_on prend en argument une liste de références d’autres Resource. Il ne doit être utilisé qu’en dernier recours, car souvent, c’est un manque dans les ressources en référence.

Un exemple :

resource "powerdns_record" "test" {
zone = "robert.local."
name = "test.robert.local."
type = "A"
ttl = 300
records = [libvirt_domain.domain-alma.network_interface.0.addresses.0]
depends_on = [
libvirt_domain.domain-alma
]
}

count

Un bloc de ressource Terraform n’instancie qu’un seul objet par défaut. Vous pouvez en créer plusieurs en utilisant le meta-argument count afin d’éviter la duplication de code.

count prend en argument un entier. Les valeurs de count seront de 0 à la valeur-1. Pour identifier les ressources, on utilise la propriété count.index

resource "aws_instance" "server" {
count = 4
ami = "ami-a1b2c3d4"
instance_type = "t2.micro"
tags = {
= "Server${count.index}"
}
}

Attention de n’utiliser count que dans le cas où les instances sont vraiment identiques !. Si certains de leurs arguments nécessitent des valeurs distinctes qui ne peuvent pas être directement dérivées d’un entier, il est plus sûr d’utiliser for_each.

for_each

Ce meta-argument prend en paramètre une map sur lequel Terraform va boucler. Chaque instance d’une ressource est associée à un objet d’infrastructure distinct et chacune est créée, mise à jour ou détruite séparément.

L’objet qui est créé s’apelle each qui possède deux propriétés : key et value

resource "azurerm_resource_group" "rg" {
for_each = {
a_group = "eastus"
another_group = "westus2"
}
name = each.key
location = each.value
}

ou

resource "aws_iam_user" "the-accounts" {
for_each = toset( ["Todd", "James", "Alice", "Dottie"] )
name = each.key
}

provider

Il peut arriver que vous utilisiez plusieurs instances du même provider. Par exemple, un provider de cloud, mais dans différentes régions. Il faut dans ce cas utiliser des alias :

provider "google" {
alias = "usa"
region = "us-central1"
}
# alternate configuration, whose alias is "europe"
provider "google" {
alias = "europe"
region = "europe-west1"
}

Ensuite pour les utiliser dans les ressources, il faudra ajouter le meta-argument provider dans les ressources.

resource "google_compute_instance" "example" {
provider = google.europe
}

lifecycle

Parfois vous aurez besoin de modifier le cycle de vie de vos ressources, c’est dans ce cas qu’intervient le meta-argument lifecycle. lifecycle est un bloc imbriqué, car il est composé de plusieurs paramètres :

Terminal window
resource "google_compute_instance" "example" {
# ...
lifecycle {
create_before_destroy = true
}
}

Les paramètres possibles :

  • create_before_destroy : On modifie le comportement de terraform afin que le nouvel objet de remplacement soit créé en premier et que l’objet précédent soit détruit après la création du remplacement. Attention parfois vous serez bloqué, car l’API distante refusera de créer deux objets de même nom. Il faudra alors ajoutez un suffixe aléatoire.
  • prevent-destroy : On impose à Terraform de tomber en erreur sur toute demande de destruction de cette ressource.
  • ignore_changes : Ce paramètre permet d’empêcher la modification d’instance après création pour des ressources qui font appel à des références qui peuvent changer ensuite. Il s’agit d’une liste d’attributs ou all (tous les attributs) :
resource "google_compute_instance" "example" {
# ...
lifecycle {
ignore_changes = [
tags,
]
}
}

Voilà pour ce premier tutoriel sur du code avancé Terraform. Dans les prochains temps, je poursuivrai sur les boucles et les conditions.

Maj : Tout est documenté ici