Providers et ressources Terraform AWS 5.x
À la fin de ce tutoriel, vous saurez déclarer le provider AWS (
hashicorp/aws~> 5.0), l’épingler viarequired_providerset le lock file, configurer la Regionca-central-1avec tags par défaut (sans clés), puis manipuler des ressources : adresseTYPE.NAME, arguments vs attributs, dépendances implicites /depends_on, lifecycle basique, et un aperçu des aliases multi-Region.Niveau : Débutant · Temps estimé : 35–45 min · Versions testées : Terraform 1.16.2 (série ≥ 1.9), AWS provider ~> 5.0 · Dernière vérification : 2026-09-10
Slug proposé :
terraform-providers-ressources· Série : Terraform · Remplace / fusionne : #1625
Prérequis
- Avoir suivi Workflow Terraform (
terraform-workflow) :init→plan→apply→destroy - Avoir suivi Blocs HCL (
terraform-blocs-hcl) : syntaxe, blocsterraform/provider/resource - Terraform ≥ 1.9, AWS CLI v2, profil de lab prêt (
aws sts get-caller-identityOK)
Coût estimé : 0 € si vous vous arrêtez à init / plan (recommandé). Un apply créerait un bucket S3 (Free Tier / faible coût) : destroy obligatoire. Aucun secret dans le HCL.
Auth sans secrets. Utilisez
AWS_PROFILE/ SSO. Jamais d’access_key/secret_keydans le blocprovider.
Ce que nous allons construire
Lab providers & ressources (ca-central-1)
├── versions.tf → required_providers aws ~> 5.0 + lock file
├── providers.tf → region, default_tags (pas de clés)
├── main.tf → aws_s3_bucket + public_access_block
├── dépendances implicites / depends_on + lifecycle (aperçu)
├── terraform init → plan
└── aperçu provider aliases (multi-Region)
(Schéma à remplacer par une image locale Excalidraw / draw.io, alt : « Provider Terraform AWS et ressources : Registry, lock file, adresse TYPE.NAME ».)
Ce guide révise et actualise le post #1625 : provider AWS 5.x + ressources, sans rejouer apply/destroy (Workflow) ni la syntaxe HCL (Blocs).
Étape 1 — Qu’est-ce qu’un provider ?
Un provider est le plugin qui traduit votre HCL en appels API (AWS, Azure, Kubernetes…). Terraform le télécharge depuis le Terraform Registry au init.
Pour AWS : source officielle hashicorp/aws sur registry.terraform.io, nom logique aws (label du bloc provider et clé dans required_providers). Sans déclaration correcte, Terraform ne sait ni quelle API appeler, ni quelle version de plugin utiliser. Le provider ne crée rien tout seul : il contextualise les resource et data.
Étape 2 — Épingler la version ~> 5.0 et le lock file
Dans versions.tf, déclarez la contrainte et la source :
terraform {
required_version = ">= 1.9.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
~> 5.0: autorise 5.x mais pas 6.0 — correctifs de la série sans breaking majeure.source: évite l’ambiguïté entre registries / forks.- Après
init, Terraform écrit.terraform.lock.hcl(versions exactes + empreintes). Committez-le ; ignorez.terraform/.
Sans required_providers, un init peut tirer une version inattendue. Sans lock partagé, deux machines divergent silencieusement.
Étape 3 — Configurer le provider (Region, profil, default tags)
Créez providers.tf — Region Canada Central, aucune clé :
provider "aws" {
region = "ca-central-1"
# Auth : AWS_PROFILE / SSO / variables d’environnement
# Jamais access_key / secret_key ici
default_tags {
tags = {
Project = "devopselastichayway"
ManagedBy = "terraform"
Stage = "providers-ressources"
}
}
}
Points essentiels :
regionexplicite (ca-central-1), alignée sur le lab.- Auth via profil / SSO / env — zéro secret en clair.
default_tags: injectés sur les ressources qui les supportent (surcharge locale possible).- Optionnel :
profile = "lab"dans le bloc au lieu deAWS_PROFILE— jamais de clés.
Le label "aws" doit matcher la clé de required_providers.
Étape 4 — Ressources : adresse, arguments et attributs
Une resource déclare un objet que Terraform gère. Syntaxe rappel :
resource "aws_s3_bucket" "lab_providers" {
bucket = "deh-lab-providers-SUFFIXE-UNIQUE"
}
| Concept | Exemple | Rôle |
|---|---|---|
| Type | aws_s3_bucket |
Famille de ressource du provider |
| Nom local | lab_providers |
Identifiant dans votre module |
| Adresse | aws_s3_bucket.lab_providers |
Référence TYPE.NAME ailleurs |
| Arguments | bucket, tags |
Entrées que vous définissez |
| Attributs | id, arn, bucket_domain_name |
Sorties exposées après apply (souvent connues seulement au runtime) |
Notation pointée : aws_s3_bucket.lab_providers.id. Arguments non ForceNew → update in-place (~) ; certains forcent un replace (-/+) — lisez toujours le plan.
Étape 5 — Dépendances implicites vs depends_on
Terraform construit un graphe à partir des références entre ressources.
Implicite — dès que vous référencez une autre adresse, l’ordre est déduit :
resource "aws_s3_bucket_public_access_block" "lab_providers" {
bucket = aws_s3_bucket.lab_providers.id # dépendance implicite
# …
}
Le public access block ne sera créé qu’après le bucket, car il lit .id.
depends_on — dépendance explicite quand il n’y a pas de référence d’attribut (ordre API, effet de bord) :
# depends_on = [aws_s3_bucket.lab_providers] # inutile ici : la ref .id suffit
Préférez les dépendances implicites. Réservez depends_on aux cas où Terraform ne peut pas inférer l’ordre.
Étape 6 — Lifecycle basique
Le bloc lifecycle ajuste le comportement de Terraform autour d’une ressource :
resource "aws_s3_bucket" "lab_providers" {
bucket = "deh-lab-providers-SUFFIXE-UNIQUE"
lifecycle {
create_before_destroy = true
# prevent_destroy = true # bloque un destroy / replace — à manier avec soin
}
}
create_before_destroy: lors d’un replace, crée la nouvelle instance avant de détruire l’ancienne (LB / alias DNS ; peu critique sur un bucket lab).prevent_destroy: refuse destroy/replace — filet prod. En lab, laissez-le commenté sinondestroyéchoue.
Autres options (ignore_changes, …) plus tard. lifecycle ne change pas l’API AWS : il change comment Terraform orchestre create/update/destroy.
Étape 7 — Lab léger ca-central-1 : init et plan
mkdir -p ~/terraform-providers-lab && cd ~/terraform-providers-lab
export AWS_PROFILE=lab
export AWS_REGION=ca-central-1
aws sts get-caller-identity
versions.tf — bloc de l’étape 2 (>= 1.9.0, hashicorp/aws ~> 5.0).
providers.tf — provider de l’étape 3 (ca-central-1 + default_tags, sans clés).
main.tf — bucket + bloc d’accès public (dépendance implicite) :
resource "aws_s3_bucket" "lab_providers" {
# Remplacez SUFFIXE-UNIQUE (initiales + date)
bucket = "deh-lab-providers-SUFFIXE-UNIQUE"
tags = {
Environment = "lab"
Name = "deh-providers-lab"
}
}
resource "aws_s3_bucket_public_access_block" "lab_providers" {
bucket = aws_s3_bucket.lab_providers.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
Les tags Project / ManagedBy / Stage viennent de default_tags ; Environment et Name s’ajoutent.
terraform init
terraform fmt -recursive
terraform validate
terraform plan
Attendez des + sur les deux ressources (« Plan: 2 to add… ») et un .terraform.lock.hcl. Pas d’obligation d’apply ; si vous appliquez, enchaînez un destroy.
Étape 8 — Provider aliases (aperçu multi-Region)
Un seul bloc provider "aws" couvre la Region par défaut. Pour cibler une autre Region dans le même module, déclarez un alias :
provider "aws" {
region = "ca-central-1"
# provider par défaut (sans alias)
}
provider "aws" {
alias = "us_east_1"
region = "us-east-1"
# même auth (profil / SSO) — Region différente
}
# Exemple : ressource forcée sur l’alias
# resource "aws_s3_bucket" "logs_us" {
# provider = aws.us_east_1
# bucket = "deh-lab-logs-SUFFIXE-UNIQUE"
# }
Meta-argument provider = aws.us_east_1 : la resource utilise l’alias. Cas typique : ACM / CloudFront en us-east-1, métier en ca-central-1. Ne créez pas le second bucket ici — retenez le pattern. Multi-compte plus tard.
Étape 9 — Checklist providers & ressources
required_providersavecsource = "hashicorp/aws"etversion = "~> 5.0".- Committer
.terraform.lock.hcl; ignorer.terraform/. - Region explicite
ca-central-1; auth via profil / SSO — zéroaccess_key. default_tagspour Project / ManagedBy / Stage.- Adresse ressource =
TYPE.NAME; arguments ≠ attributs. - Préférer les dépendances implicites ;
depends_onen dernier recours. - Connaître
create_before_destroyetprevent_destroy(lifecycle). - Alias (
provider = aws.xxx) pour multi-Region dans le même module. init→fmt→validate→planavant tout apply ; destroy si apply.
Nettoyage
Si vous n’avez fait que init / plan :
cd ~ && rm -rf ~/terraform-providers-lab
Si vous avez apply : terraform destroy, vérifiez l’absence du bucket en ca-central-1, puis supprimez le dossier. Aucune ressource « lab-providers » ne doit rester.
Erreurs fréquentes
| Symptôme | Cause | Correction |
|---|---|---|
| Provider version inattendue / breaking | Pas de ~> 5.0 ou lock file absent |
Épinglez required_providers ; committez .terraform.lock.hcl |
| Ressources dans la mauvaise Region | region omise ou AWS_REGION ≠ provider |
Alignez providers.tf et l’env sur ca-central-1 |
No valid credential sources |
Profil / SSO non chargés | export AWS_PROFILE=… puis aws sts get-caller-identity |
Clés collées dans provider |
Anti-pattern sécurité | Supprimez access_key / secret_key ; utilisez le profil |
Reference to undeclared resource |
Typo sur TYPE.NAME |
Vérifiez type + nom local (aws_s3_bucket.lab_providers) |
| Cycle / ordre incorrect | depends_on inutile ou ref manquante |
Préférez une référence d’attribut ; lisez le graphe du plan |
Error: Instance cannot be destroyed |
prevent_destroy = true |
Retirez le flag (lab) ou assumez le filet (prod) |
| Alias ignoré | Oubli de provider = aws.alias |
Meta-argument provider sur la resource concernée |
Quiz (3 questions)
1. Que signifie version = "~> 5.0" pour le provider AWS ?
- A. Exactement 5.0.0 uniquement
- B. Toute version 5.x compatible, sans passer en 6.x
- C. N’importe quelle version majeure ≥ 5
2. Dans aws_s3_bucket.lab_providers.id, que représente id ?
- A. Un argument que vous devez toujours écrire à la main
- B. Un attribut exposé par la ressource (souvent après apply)
- C. Le nom du profil AWS
3. Quand utiliser depends_on en priorité ?
- A. Toujours, sur chaque resource
- B. Quand Terraform ne peut pas inférer l’ordre faute de référence d’attribut
- C. Uniquement avec les provider aliases
Réponses : 1‑B · 2‑B · 3‑B
Pourquoi / quand maîtriser providers et ressources
Sans provider correctement épinglé, votre HCL ne parle à aucune API. Sans compréhension des ressources (adresse TYPE.NAME, arguments vs attributs), vous ne lirez pas un plan correctement. Travaillez cette page juste après Blocs HCL et Workflow : vous savez déjà init/plan, vous apprenez ici quoi Terraform crée et via quel plugin.
Quand épingler ~> 5.0 et committer le lock file
Dès qu’un dépôt est partagé ou CI-ifié. Le fichier .terraform.lock.hcl fige les versions de providers pour que votre collègue et la pipeline voient le même comportement. En solo lab, épingler reste une bonne hygiène pour Terraform ≥ 1.9.
Pièges providers / ressources
- Oublier
required_providerspuis dépendre d’une résolution implicite fragile. - Mettre
access_key/secret_keydans le blocprovider: interdit dans nos labs ;AWS_PROFILEou SSO uniquement. - Confondre argument (ce que vous écrivez) et attribut (ce que le provider expose après apply, ex.
id,arn). - Abuser de
depends_onalors qu’une référence d’attribut crée déjà la dépendance implicite. - Changer un argument force-new sans lire le plan : replace = destroy + create.
FAQ providers & ressources
Pourquoi ca-central-1 partout ? Cohérence pédagogique de la série et Region de lab stable ; adaptez en production selon latence et résidence des données.
À quoi servent les default_tags ? Ils taguent automatiquement les ressources supportées (Owner, Project, Environment) : audit et nettoyage plus simples.
Quand utiliser un alias de provider ? Multi-Region ou multi-compte dans un même root module. Sinon, un provider par défaut suffit.
Le lock file se commit-il ? Oui, en général : reproductibilité. Ne committez jamais le dossier .terraform/ ni le state.
Pour aller plus loin
- Doc officielle : Providers, Resource behavior, AWS provider 5.x
- Sur ce site : enchaînez Variables, puis Locals / Outputs ; approfondissez Data sources et le state distant
- Rappel : un provider bien épinglé + un plan relu valent mieux qu’un apply précipité
Maillage série Terraform (P2)
| ← Précédent | Blocs HCL (terraform-blocs-hcl) |
| → Suivant | Variables (terraform-variables) |
| Aussi | Workflow Terraform (terraform-workflow) · Data sources |
| Carte | Overview · Install · Workflow · Blocks · Providers · Variables · Locals · Outputs · State · Data sources · Loops · Conditionals · Dynamic blocks · Modules ×2 · Workspaces · Provisioners · EBS · ELB/ALB · IAM · RDS · VPC · Auto Scaling · Route 53 |
Cas réel — deux régions, un seul alias oublié
Vous créez un bucket en ca-central-1 et un replica dont le provider n’a pas d’alias. Terraform le pose dans la région par défaut. Le plan a l’air cohérent, la console montre l’objet au mauvais endroit. Toujours qualifier provider = aws.us_east (exemple) sur la ressource répliquée.
Piège arguments ForceNew : changer un champ anodin (certaines AZ, certains noms) déclenche -/+. Lisez le plan avant d’accuser le provider. Les data sources ne créent rien : si votre « ressource » n’apparaît que dans un data, elle existait déjà — ne la détruisez pas avec un destroy de lab.
À retenir : provider = comment parler à l’API ; ressource = ce que vous assumez de gérer. La frontière évite les imports accidentels.
Retour parcours Terraform — hub de la série et leçons sœurs.



