Aller au contenu
Développement medium

Fonctions HCL : chaînes, collections et transformations

5 min de lecture

Les fonctions HCL servent à transformer des valeurs sans alourdir votre code. C'est elles qui vous évitent de concaténer à la main, de reconstruire des maps laborieusement, ou de multiplier des conditions peu lisibles. Elles sont très présentes dans Terraform et Packer.

Le plus important n'est pas de mémoriser toute la référence, mais de reconnaître quelques grandes familles de fonctions et les problèmes qu'elles résolvent.

  • Reconnaître les grandes familles de fonctions HCL.
  • Choisir une fonction adaptée à un besoin fréquent.
  • Distinguer ce qui est partagé entre Terraform et Packer.
  • Découvrir les fonctions définies par les providers (Terraform 1.8, OpenTofu 1.7).

Ces fonctions servent à nettoyer, composer ou formater du texte :

locals {
slug = replace(lower(var.project), " ", "-")
short_name = substr(var.project, 0, 8)
display = format("%s-%s", var.project, var.environment)
}

Retenez notamment :

  • lower() et upper() ;
  • replace() ;
  • substr() ;
  • format() ;
  • split() et join().

Elles servent à manipuler listes, sets, maps et objets :

locals {
names = distinct(var.names)
all_names = concat(["bootstrap"], local.names)
config = merge(var.default_tags, var.extra_tags)
has_admin = contains(var.roles, "admin")
}

Les plus fréquentes sont souvent :

  • length() ;
  • contains() ;
  • concat() ;
  • distinct() ;
  • merge() ;
  • keys() et values() ;
  • lookup().

Certaines fonctions sont utiles pour garder un code plus robuste :

locals {
enabled_text = tostring(var.enabled)
safe_port = try(var.service.port, 8080)
valid_name = can(regex("^[a-z0-9-]+$", var.project))
}

Trois fonctions valent l'effort d'être retenues tôt :

  • tostring(), tonumber(), tolist() et autres conversions ;
  • try() pour prévoir un repli ;
  • can() pour tester si une expression s'évalue sans erreur.

La logique générale est commune aux deux outils. Exemples :

  • dans Terraform, vous utiliserez souvent ces fonctions pour construire des tags, des noms de ressources, des valeurs d'outputs ou des locals ;
  • dans Packer, vous les utiliserez pour préparer une image, générer des labels, composer un identifiant de build ou sélectionner des paquets.

Exemple Packer :

locals {
image_name = format("%s-%s", var.project, var.environment)
packages = var.environment == "prod" ? ["curl", "ca-certificates"] : ["curl", "jq", "vim"]
}

Exemple Terraform :

locals {
vm_name = format("%s-%s", var.project, var.environment)
tags = merge(var.default_tags, { Name = local.vm_name })
}

Même si Terraform et Packer partagent une grande partie de l'écosystème HCL, toutes les fonctions ne sont pas forcément disponibles de manière identique dans toutes les versions. Si vous travaillez sur un projet ancien, vérifiez toujours la version de l'outil avant d'utiliser une fonction récente.

Jusqu'ici, toutes les fonctions présentées sont intégrées au langage. Depuis Terraform 1.8 et OpenTofu 1.7, un provider peut aussi exposer ses propres fonctions, appelées provider-defined functions. Cela étend le langage sans modifier l'outil : chaque provider apporte des fonctions métier adaptées à son domaine.

La syntaxe d'appel est préfixée par provider::, le nom local du provider, puis le nom de la fonction :

# forme générale
provider::<nom_local>::<fonction>(arguments)
# exemple fourni par le provider terraform lui-même
output "tfvars" {
value = provider::terraform::encode_tfvars({
exemple = "Bonjour"
})
}

Concrètement, un provider cloud peut ainsi fournir une fonction pour valider un identifiant de ressource ou transformer une valeur spécifique à sa plateforme, sans que vous ayez à la réécrire à la main. Vérifiez la documentation du provider pour connaître les fonctions qu'il publie.

  • Les fonctions HCL évitent le code répétitif et rendent les expressions lisibles.
  • Commencez par les familles chaînes, collections et robustesse.
  • format(), merge(), contains(), length(), lookup(), try() et can() couvrent déjà beaucoup de cas réels.
  • Depuis Terraform 1.8 et OpenTofu 1.7, les providers peuvent exposer leurs propres fonctions via provider::<nom>::<fonction>().
  • Terraform et Packer partagent largement cette logique, même si les usages concrets diffèrent.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn