Aller au contenu
Développement medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Types et collections HCL : string, list, map, object

6 min de lecture

Les types deviennent vraiment importants dès que vous écrivez des variables Terraform, des inputs Packer, des outputs ou des objets plus riches. Tant que vous ne manipulez que quelques chaînes simples, tout paraît facile. Dès qu’une configuration doit accepter une liste, une map ou un objet structuré, il faut savoir décrire précisément la forme attendue.

Cette page clarifie un point essentiel : dans l’écosystème Terraform, on mélange souvent valeurs HCL et contraintes de type. Les deux sont proches, mais ce n’est pas la même chose.

Voici la distinction la plus utile à retenir :

Vous écrivezCe que c’estExemple
une valeurune donnée concrète["dev", "prod"]
une contrainte de typela forme attendue pour une valeurlist(string)

Exemple avec une variable Terraform :

variable "environments" {
type = list(string)
default = ["dev", "prod"]
}

list(string) n’est pas une valeur à déployer. C’est une contrainte de type. La valeur concrète est ["dev", "prod"].

La même logique s’applique dans Packer :

variable "packages" {
type = list(string)
default = ["curl", "jq"]
}

Les trois types primitifs à connaître en premier sont :

variable "name" {
type = string
default = "vm-dev"
}
variable "memory" {
type = number
default = 2048
}
variable "enabled" {
type = bool
default = true
}
  • string pour du texte ;
  • number pour des entiers ou décimaux ;
  • bool pour true ou false.

Terraform convertit parfois automatiquement certaines valeurs simples, mais cela ne doit pas vous inciter à laisser les types implicites quand un module ou une variable doit être claire.

Une liste regroupe plusieurs valeurs du même type, dans un ordre donné.

variable "dns_servers" {
type = list(string)
default = ["1.1.1.1", "8.8.8.8"]
}

Une map associe des clés à des valeurs du même type.

variable "tags" {
type = map(string)
default = {
env = "dev"
team = "platform"
}
}

Un set contient des valeurs uniques, sans ordre garanti. Il est pratique quand la duplication n’a pas de sens.

variable "availability_zones" {
type = set(string)
default = ["eu-west-3a", "eu-west-3b"]
}

Un objet permet de définir plusieurs attributs nommés, chacun avec son propre type.

variable "vm" {
type = object({
name = string
memory = number
vcpu = number
})
}

Ce type est souvent le plus utile pour décrire une entrée structurée propre.

Un tuple décrit une séquence positionnelle où chaque élément peut avoir un type différent.

locals {
metadata = ["vm-dev", 2048, true]
}

La contrainte correspondante serait :

tuple([string, number, bool])

Dans la pratique courante, tuple est moins fréquent que list ou object, mais il aide à comprendre pourquoi Terraform distingue parfois les littéraux de collection et les types attendus.

La documentation officielle Terraform rappelle que ces paires sont proches, mais pas identiques :

  • list décrit une collection homogène ordonnée ;
  • tuple décrit une collection ordonnée avec un type par position ;
  • map décrit des clés nommées avec des valeurs homogènes ;
  • object décrit des attributs nommés avec un type précis pour chacun.

Pour beaucoup de cas quotidiens, la différence est discrète. Elle devient importante quand vous écrivez des variables typées, des modules ou des validations fines.

Terraform permet aussi de marquer certains attributs d’objet comme optionnels :

variable "vm" {
type = object({
name = string
memory = optional(number, 1024)
tags = optional(map(string), {})
})
}

Ce mécanisme est très utile quand vous voulez offrir une interface de module plus souple sans abandonner le typage.

any existe, mais la documentation officielle recommande de l’utiliser avec parcimonie.

variable "settings" {
type = any
}

Ce choix n’est raisonnable que si vous traitez la valeur comme un bloc opaque, par exemple pour l’envoyer telle quelle dans un jsonencode. Si vous comptez lire ses attributs ou imposer une structure, décrivez plutôt le type attendu explicitement.

Quand ce guide suffit et quand passer à Terraform

Section intitulée « Quand ce guide suffit et quand passer à Terraform »

Ce guide suffit si votre difficulté principale est de comprendre la forme des valeurs et des types. Passez ensuite aux guides Terraform ou Packer quand le sujet devient concret :

  • Une valeur et une contrainte de type sont deux choses différentes.
  • string, number et bool sont les bases.
  • list, map, set, object et tuple servent à structurer des données plus riches.
  • object({...}) est souvent le meilleur choix pour décrire une entrée complexe de module.
  • any doit rester l’exception, pas la solution de facilité.

Ce site vous est utile ?

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

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn