Aller au contenu
Infrastructure as Code medium

Providers Terraform : source explicite, alias et modules

20 min de lecture

logo terraform

Un provider est le plugin qui traduit vos ressources en appels d'API. On le déclare dans required_providers, on le configure dans un bloc provider, et tout semble simple, jusqu'à ce qu'un module s'en mêle. Deux confusions dominent : l'adresse source (le préfixe hashicorp/ implicite est en réalité déconseillé) et la différence entre nom local et alias.

Ce guide traite l'adresse source complète, le nom local face à l'alias, les contraintes de version selon le contexte, la place des providers dans un module, et la preuve par le plan JSON. Les comportements ont été vérifiés sur Terraform v1.15.4.

  • L'adresse source complète, et pourquoi l'implicite est déconseillé
  • La différence entre nom local et alias
  • Les contraintes de version selon le contexte (racine ou module)
  • Pourquoi un module réutilisable ne contient pas de bloc provider
  • configuration_aliases, providers = {}, et la preuve par le plan JSON

Depuis Terraform 0.13, source est requis dans required_providers. On lit souvent qu'il est « implicite » pour les providers HashiCorp : c'est vrai techniquement, mais la doc le classe comme une rétro-compatibilité et recommande l'inverse : « use explicit source addresses for all providers ».

terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

L'adresse complète est [HOSTNAME/]NAMESPACE/TYPE. hashicorp/aws est en fait registry.terraform.io/hashicorp/aws : le hostname, souvent omis, est la porte d'entrée des registres privés et des miroirs. L'omettre revient à câbler le registre public par défaut.

C'est la confusion la plus fréquente, et le guide d'origine la mélangeait. Ce sont deux mécanismes différents :

  • Le nom local (la clé dans required_providers) identifie le provider dans le module. C'est lui qui rattache un type de ressource à un provider, par son préfixe : aws_instance va au provider de nom local aws. Un nom local différent du type impose un provider = <nom_local> sur chaque ressource.
  • L'alias crée une configuration supplémentaire du même provider, pour cibler par exemple deux régions.
provider "aws" {
region = "eu-west-3"
}
provider "aws" {
alias = "us"
region = "us-east-1"
}
resource "aws_instance" "paris" {
# provider par defaut
}
resource "aws_instance" "virginie" {
provider = aws.us
}

Le plan JSON le confirme : configuration.provider_config liste chaque configuration avec son full_name, son alias éventuel, et chaque ressource porte un provider_config_key (aws ou aws.us).

Une même règle ne vaut pas partout, et c'est un point d'examen :

  • Module racine : bornez haut et bas, typiquement ~> 5.0, « to avoid accidental upgrades to incompatible new versions ».
  • Module réutilisable : ne contraignez que le minimum, et n'utilisez pas ~> : « reusable modules should constrain only their minimum allowed versions », sans quoi le module « forces users to update many modules simultaneously ».

Terraform ne fait pas correspondre les pré-releases aux opérateurs de plage, et un bloc provider {} n'accepte que des valeurs connues avant l'apply : jamais un attribut calculé d'une ressource.

Voici le cœur du sujet, et ce que l'examen interroge. Un module destiné à être appelé ne doit contenir aucun bloc provider : « A module intended to be called by one or more other modules must not contain any provider blocks. » La configuration du provider vit dans le module racine, et traverse la frontière.

Trois mécanismes gouvernent ce passage :

  • L'héritage implicite : un module enfant hérite des configurations par défaut du parent, mais pas des exigences de source et de version, que chaque module doit redéclarer dans son propre required_providers.
  • configuration_aliases : dans son required_providers, un module enfant déclare qu'il attend une configuration aliasée (configuration_aliases = [aws.us]).
  • providers = { ... } : le meta-argument du bloc module passe une configuration (aliasée ou non) au module enfant.
module "reseau" {
source = "./modules/reseau"
providers = {
aws = aws.us
}
}

Deux outils machine, souvent ignorés :

  • terraform providers schema -json décrit le schéma complet de chaque provider (attributs, types, write_only) : c'est l'outil de référence quand un argument semble manquant.
  • terraform version -json expose provider_selections, l'adresse complète vers la version réellement retenue :
Fenêtre de terminal
terraform version -json | jq '.provider_selections'

Pour la CI, terraform init -lockfile=readonly vérifie les empreintes du lock sans le réécrire ; il est incompatible avec -upgrade.

Ces symptômes touchent à la source, à l'alias ou aux modules.

SymptômeCauseSolution
Une ressource va au mauvais providerSon préfixe ne correspond pas au nom local attenduPoser provider = <nom_local> sur la ressource
provider configuration not presentUn module attend une config aliasée non passéeLa passer via providers = { aws = aws.us }
provider blocks are not allowed (module)Un bloc provider dans un module appeléLe remonter au module racine, passer par providers
Avertissement de dépréciation sur versionversion dans un bloc provider {}Déplacer la contrainte dans required_providers
count/for_each refusés sur un moduleLe module hérite d'un bloc providerPasser la config explicitement, sans bloc dans l'enfant
  1. source est requis et doit être explicite ; l'adresse est [HOSTNAME/]NAMESPACE/TYPE.
  2. Nom local ≠ alias : le nom local rattache les ressources, l'alias ajoute une configuration du même provider.
  3. La contrainte va dans required_providers, pas dans provider {} (où version est déprécié).
  4. Module racine : borné (~> 5.0). Module réutilisable : minimum seul, pas de ~>.
  5. Un module appelé ne contient aucun bloc provider ; il hérite des configs par défaut, redéclare source/version, et reçoit les alias par configuration_aliases + providers = {}.
  6. Un provider hérité casse count/for_each/depends_on.
  7. version -json et providers schema -json sont les preuves machine.

Les questions ci-dessous reprennent les confusions les plus fréquentes sur les providers : l'adresse source, la différence nom local / alias, et les providers dans les modules.

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