DevOps Elastic Hayway
Document

SUBSCRIBE TO GET FULL ACCESS TO THE E-BOOKS FOR FREE 🎁SUBSCRIBE NOW

Professional Dropdown with Icon

SUBSCRIBE NOW TO GET FREE ACCESS TO EBOOKS

TerraformLesson 5 / 2410 min readUpdated September 13, 2026

Blocs HCL Terraform : syntaxe, terraform, provider et resource

À la fin de ce tutoriel, vous saurez lire et écrire la syntaxe HCL de base : arguments, blocs, commentaires, puis les blocs terraform, provider et resource, avec un aperçu de variable / output / locals et data, une organisation multi-fichiers propre, et un lab minimal en Region ca-central-1 validé par fmt / validate.

Niveau : Débutant · Temps estimé : 30–40 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-blocs-hcl · Série : Terraform · Remplace / fusionne : #1620, #1607

Prérequis

  • Avoir suivi Découvrir Terraform (terraform-overview) — IaC, state, providers
  • Avoir suivi Installer Terraform (installer-terraform) : binaire ≥ 1.9, profil AWS prêt
  • Avoir suivi Workflow Terraform (terraform-workflow) : init → plan → apply → destroy
  • AWS CLI v2 : aws sts get-caller-identity OK avec votre profil de lab

Coût estimé : 0 € dans ce tuto si vous vous arrêtez à fmt / validate (recommandé). Un apply éventuel créerait un bucket S3 (Free Tier / faible coût) : dans ce cas, destroy obligatoire. Aucun secret dans le HCL.

Auth sans secrets. Utilisez AWS_PROFILE / SSO comme dans Install et Workflow. Jamais d'access_key dans les .tf.

Ce que nous allons construire

Lab blocs HCL (ca-central-1)
  ├── versions.tf   → bloc terraform (required_version + required_providers)
  ├── providers.tf  → bloc provider "aws"
  ├── main.tf       → resource S3 + tags (+ aperçu locals)
  ├── variables.tf / outputs.tf (aperçu, détail = tutos suivants)
  ├── terraform init → fmt → validate
  └── Lecture des erreurs HCL fréquentes (virgules, guillemets, labels)

(Schéma à remplacer par une image locale Excalidraw / draw.io, alt : « Blocs HCL Terraform : terraform, provider, resource et fichiers ».)

Fusion de #1620 et #1607 : syntaxe HCL + blocs essentiels, sans répéter apply/destroy du Workflow.

Étape 1 — HCL en bref : arguments, blocs, commentaires

HCL (HashiCorp Configuration Language) est le langage des fichiers .tf. Trois idées suffisent pour démarrer.

1. Arguments — paire nom = valeur à l'intérieur d'un bloc :

region = "ca-central-1"
bucket = "mon-bucket-exemple"

Les chaînes utilisent des guillemets doubles. Les nombres et booléens (true / false) n'en ont pas. Les listes et maps s'écrivent avec [] et {}.

2. Blocs — structure nommée avec des accolades. Un bloc a un type, éventuellement un ou deux labels, puis un corps d'arguments (et parfois de blocs imbriqués) :

# type      label1   label2
resource "aws_s3_bucket" "lab_hcl" {
  bucket = "deh-lab-hcl-SUFFIXE-UNIQUE"
}

3. Commentaires — # en fin de ligne, ou / … /. Expliquez le pourquoi ; jamais de secrets.

Règles utiles : 2 espaces (terraform fmt), pas de virgule entre arguments (contrairement au JSON), labels snake_case.

Étape 2 — Bloc terraform : version, providers, backend

Le bloc terraform configure le moteur lui-même, pas une ressource cloud. Placez-le typiquement dans versions.tf :

terraform {
  required_version = ">= 1.9.0"

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

  # backend "s3" { ... }  # mention : state distant — détail dans le tuto State
}
  • required_version : refuse un binaire trop ancien au init (série lab ≥ 1.9).
  • required_providers : source registry (hashicorp/aws) et contrainte (~> 5.0 = 5.x compatible).
  • backend (aperçu) : où stocker le state (local par défaut ; S3 + lock en équipe). Pas de backend distant ici — ce sera le tuto State.

Sans ce bloc, Terraform fonctionne, mais sans garde-fou de version ni reproductibilité des providers.

Étape 3 — Bloc provider

Le provider est le plugin qui parle à une API (ici AWS). Un bloc provider configure comment Terraform contacte ce cloud :

provider "aws" {
  region = "ca-central-1"
  # Auth via AWS_PROFILE / SSO / env — jamais access_key / secret_key ici
}

Points clés :

  • Le label "aws" correspond au nom déclaré dans required_providers.
  • La Region doit être explicite et alignée sur votre lab (ca-central-1).
  • Auth via chaîne CLI (profil, env, SSO) — zéro clé en clair.
  • Alias multi-Region / multi-compte : détail dans Providers et ressources.

Le provider ne crée rien seul : contexte pour resource et data.

Étape 4 — Bloc resource : type, nom local, arguments, meta-arguments

Une resource déclare un objet d'infrastructure géré par Terraform (créer, maj, détruire) :

resource "aws_s3_bucket" "lab_hcl" {
  bucket = "deh-lab-hcl-SUFFIXE-UNIQUE"

  tags = {
    Project   = "devopselastichayway"
    ManagedBy = "terraform"
    Stage     = "hcl-blocks"
  }
}

Décryptage :

Élément Exemple Rôle
Type aws_s3_bucket Famille de ressource du provider AWS
Nom local lab_hcl Identifiant dans votre module (pas l'ID cloud)
Adresse aws_s3_bucket.lab_hcl Référence ailleurs (id, arn, etc.)
Arguments bucket, tags Propriétés de la ressource

Meta-arguments (aperçu) : count, for_each, depends_on, lifecycle, provider (alias) — comportement Terraform, pas champs API AWS. Un exemplaire suffit ici ; boucles dans Loops / Dynamic blocks.

Nom local unique par type dans le module. Suffixe S3 unique : buckets globalement uniques.

Étape 5 — Aperçu variable, output et locals

Trois blocs structurants, traités en profondeur dans les tutos dédiés :

  • variable — entrée paramétrable (variable "environment" { type = string … }) ; évite de durcir Region / noms / tags.
  • output — valeur exposée après apply (ex. ARN) pour humains, CI ou modules parents.
  • locals — calculs / constantes internes (locals { common_tags = { … } }), sans polluer l'interface du module.

Exemple minimal :

variable "project" {
  type    = string
  default = "devopselastichayway"
}

locals {
  common_tags = {
    Project   = var.project
    ManagedBy = "terraform"
  }
}

output "bucket_name" {
  value = aws_s3_bucket.lab_hcl.bucket
}

variables = entrée, locals = calcul interne, outputs = sortie. Types / validation / sensitive : tutos suivants.

Étape 6 — Bloc data en une phrase

Un bloc data lit une info existante (AMI, VPC, compte…) sans la créer — détail dans Data sources.

Étape 7 — Organisation multi-fichiers

Terraform charge tous les .tf du répertoire (root module) : découpage pour les humains, pas un ordre d'exécution magique.

Fichier Contenu typique
versions.tf Bloc terraform (version + providers)
providers.tf Blocs provider
variables.tf Déclarations variable
locals.tf locals partagés
main.tf (ou fichiers par domaine) resource / data
outputs.tf Blocs output

Bonnes pratiques : un dossier = un lab ; .gitignore .terraform/ et .tfstate ; committer .terraform.lock.hcl ; pas d'override.tf inutile.

Étape 8 — Lab cohérent ca-central-1 : fichiers + fmt / validate

Créez le dossier et l'environnement :

mkdir -p ~/terraform-hcl-lab && cd ~/terraform-hcl-lab
export AWS_PROFILE=lab
export AWS_REGION=ca-central-1
aws sts get-caller-identity

versions.tf — bloc terraform étape 2 (>= 1.9.0, aws ~> 5.0).

providers.tf — provider AWS ca-central-1 sans clés (étape 3).

main.tf — bucket + public access block (esprit Workflow), suffixe unique :

resource "aws_s3_bucket" "lab_hcl" {
  bucket = "deh-lab-hcl-SUFFIXE-UNIQUE"

  tags = {
    Project     = "devopselastichayway"
    ManagedBy   = "terraform"
    Stage       = "hcl-blocks"
    Environment = "lab"
  }
}

resource "aws_s3_bucket_public_access_block" "lab_hcl" {
  bucket = aws_s3_bucket.lab_hcl.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

Puis :

terraform init
terraform fmt -recursive
terraform validate

Sortie attendue : Success! The configuration is valid. Syntaxe validée sans apply obligatoire ; si apply, destroy ensuite (Workflow).

Étape 9 — Checklist syntaxe HCL

  1. Guillemets doubles pour les chaînes ; pas de virgules entre arguments.
  2. Labels resource / data : type provider + nom local snake_case.
  3. Bloc terraform avec required_version et required_providers dès le premier projet.
  4. Region explicite ca-central-1 ; auth via profil / env / SSO.
  5. Découpage versions.tf / providers.tf / main.tf / variables.tf / outputs.tf.
  6. fmt + validate avant toute PR ou partage.
  7. Variables, locals, outputs, data : aperçu seulement — détail ensuite.
  8. Zéro secret dans le HCL ; noms S3 uniques ; tags Project / ManagedBy.

Nettoyage

Si vous n'avez fait que init / fmt / validate :

cd ~ && rm -rf ~/terraform-hcl-lab

Si apply : terraform destroy, vérifiez l'absence du bucket en ca-central-1, puis supprimez le dossier.

Erreurs fréquentes HCL

Symptôme Cause Correction
Erreur de parse près d'une , Virgule style JSON entre arguments Supprimez les virgules ; HCL sépare par des retours ligne
Invalid character / chaîne cassée Guillemets simples ou oubliés Utilisez "…" pour les strings
Duplicate resource / label invalide Même type+nom local, ou tirets / majuscules bizarres Un seul aws_s3_bucket.lab_hcl ; snake_case
Missing required argument Argument obligatoire du type resource omis Lisez l'erreur + doc registry du type
validate avant init Providers absents terraform init d'abord
Confusion nom local ≠ nom cloud lab_hcl n'est pas le bucket = "…" Le label est logique ; l'argument porte le nom AWS
Clés AWS collées dans provider Anti-pattern Profil / AWS_PROFILE / SSO uniquement

Quiz (3 questions)

1. Dans resource "aws_s3_bucket" "lab_hcl", que désigne lab_hcl ?

  • A. L'ID AWS définitif du bucket
  • B. Le nom local dans le module Terraform
  • C. La Region ca-central-1

2. Où place-t-on typiquement required_version et required_providers ?

  • A. Dans un bloc terraform (souvent versions.tf)
  • B. Dans le fichier terraform.tfstate
  • C. Uniquement dans la console AWS

3. Quelle affirmation sur HCL est correcte ?

  • A. Les arguments d'un bloc doivent être séparés par des virgules comme en JSON
  • B. Les chaînes utilisent des guillemets doubles ; fmt normalise l'indentation
  • C. Le bloc data crée toujours une ressource facturable

Réponses : 1‑B · 2‑A · 3‑B

Pourquoi / quand solidifier les blocs HCL

Les blocs terraform, provider et resource sont le squelette de toute config. Si vous les lisez mal, variables, modules et dynamic blocks resteront flous. Revenez ici dès qu’un message d’erreur parle de « Unsupported block type » ou de labels manquants.

Pièges de syntaxe utiles à mémoriser

  • Virgules style JSON dans un .tf natif : HCL n’en veut pas entre arguments.
  • Guillemets simples : préférez "…".
  • Mélanger plusieurs blocs terraform incompatibles ou plusieurs backends.
  • Nommer une resource avec des majuscules ou des tirets interdits : suivez les identifiants HCL.
  • Secrets dans versions.tf / providers.tf : jamais ; auth via profil, Region ca-central-1, TF ≥ 1.9.

FAQ blocs HCL

Faut-il un fichier par type de bloc ? Convention utile (versions.tf, providers.tf, main.tf), pas une obligation du moteur : Terraform fusionne tous les .tf du dossier.

locals remplace-t-il variable ? Non. variable = entrée ; locals = valeurs calculées internes.

Où déclarer le backend ? Dans le bloc terraform ; détail opérationnel dans le tuto State backend S3.

Pour aller plus loin

  • Doc officielle : Configuration Language, Resources, AWS provider 5.x
  • Sur ce site : enchaînez Providers et ressources, puis Variables / Locals / Outputs et Data sources
  • Rappel : validate ≠ plan relu — le workflow précédent reste le filet de sécurité

Maillage série Terraform (P2)

← Précédent Workflow Terraform (terraform-workflow)
→ Suivant Providers et ressources (terraform-providers-ressources)
Aussi Variables · Découvrir Terraform (terraform-overview)
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 — un bloc terraform oublié et un provider flottant

Sans required_providers, init choisit « la dernière 5.x » un lundi et une autre le vendredi. Le lock file rattrape, mais seulement s’il est commité. Un collègue sans lock se retrouve avec un schema différent et un plan qui remplace des ressources. Déclarez source + contrainte ~> 5.0 dès le premier fichier.

Piège : mélanger un backend incomplet dans le bloc terraform « pour plus tard » et un state local. Terraform refuse souvent l’init à moitié configuré. Soit backend distant complet, soit rien — pas un backend "s3" {} vide en commentaire ambigu.

À retenir : chaque type de bloc a un rôle (réglages, provider, ressource, data, variable, output). Si vous ne savez pas dans quel bloc mettre une valeur, ce n’est probablement pas une ressource.

Retour parcours Terraform — hub de la série et leçons sœurs.

Share your love

Leave a Reply

Your email address will not be published. Required fields are marked *