Module 4 — Providers : configuration avancée et authentification CI
Durée indicative du cours : 1h15–1h30 (après-midi Jour 1 ; suite possible Jour 2)
Durée indicative de l’atelier : — (atelier à venir)
Durée totale (cours + atelier) : ~1h15–1h45 selon lab
Objectif du module
Ce module démarre typiquement l’après-midi du Jour 1 : le matin a aligné le socle (concepts, HCL, workflow).
Au module 2 de Terraform Basics (et ce matin en Associate), vous avez déjà déclaré un provider AzureRM, un required_providers et un lockfile.
Ici, on passe au niveau professionnel : plusieurs configurations du même provider, arguments avancés, et authentification de pipeline sans secret long terme.
À l’issue de ce module, vous serez capables de :
- brancher plusieurs souscriptions ou tenants via des aliases ;
- choisir un mode d’auth adapté (interactif, MSI, Service Principal, OIDC / WIF) ;
- expliquer pourquoi le bloc
featuresexiste et ce qu’il contrôle ; - lire un plan lancé depuis Azure DevOps avec une identité fédérée.
Rappel express — ce que fait un provider
Un provider est le plugin qui parle à une API (Azure, AWS, DNS, etc.).
Terraform télécharge la version demandée pendant terraform init, puis s’en sert pour lire et écrire le cloud.
terraform {
required_version = ">= 1.10.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.0"
}
}
}
provider "azurerm" {
features {}
}
Le fichier .terraform.lock.hcl fige les versions exactes des providers.
Ce n’est pas le même verrou que le state lock du backend distant (module 5).
Réflexe Associate
En lab solo, l’auth Azure CLI (az login) suffit souvent.
En équipe et en CI, on vise une identité éphémère ou fédérée, pas un client_secret versionné.
Plusieurs configurations : les aliases
Par défaut, Terraform crée une configuration implicite par type de provider.
Dès qu’il faut deux souscriptions, deux tenants, ou deux « contextes » Azure, on déclare un second bloc avec un alias.
provider "azurerm" {
features {}
# configuration par défaut (lab / shared)
}
provider "azurerm" {
alias = "prod"
features {}
subscription_id = var.prod_subscription_id
tenant_id = var.prod_tenant_id
}
Sur une ressource (ou un module), on pointe vers l’alias :
resource "azurerm_resource_group" "prod" {
provider = azurerm.prod
name = "rg-demo-prod-shared"
location = var.location
}
| Situation | Approche |
|---|---|
| Une seule souscription lab | Un seul provider "azurerm" (pas d’alias) |
| Lab + prod dans le même root module | Alias (azurerm.prod) + provider = … sur les ressources concernées |
| Envs très séparés (droits, cadence) | Souvent plusieurs stacks / repos plutôt qu’un seul root multi-alias |
Piège fréquent
Oublier provider = azurerm.prod sur une ressource la rattache à la config par défaut.
Le plan peut créer dans la mauvaise souscription sans erreur de syntaxe.
Documentation officielle : Multiple provider configurations (alias).
Arguments avancés du provider AzureRM
Selon le scénario, le bloc provider "azurerm" peut préciser :
| Argument / levier | Rôle |
|---|---|
subscription_id / tenant_id |
Cible Azure explicite (sinon souvent déduite de l’auth) |
environment |
Cloud public vs souverains (public, usgovernment, …) |
auxiliary_tenant_ids |
Accès cross-tenant (scénarios avancés) |
Variables d’environnement ARM_* |
Auth et cible sans secrets dans le HCL |
features { … } |
Comportements provider (voir section suivante) |
Modes d’authentification courants
| Mode | Quand l’utiliser | Idée |
|---|---|---|
Azure CLI (az login) |
Poste formateur / élève | Simple ; pas idéal en CI non interactive |
| Managed Identity (MSI) | VM / App Service / runners Azure | Identité liée à la ressource d’exécution |
| Service Principal + secret | CI « classique » | Fonctionne, mais secret à rotation |
| OIDC / WIF | Pipelines modernes (ADO, GitHub Actions…) | Token court ; pas de client_secret durable |
Les variables d’environnement typiques côté AzureRM incluent ARM_CLIENT_ID, ARM_TENANT_ID, ARM_SUBSCRIPTION_ID, et selon le mode ARM_CLIENT_SECRET ou ARM_USE_OIDC / jetons OIDC.
Secrets
Ne placez jamais un client_secret dans un fichier .tf versionné.
Preferez l’environnement, un coffre, ou une federation OIDC.
Documentation provider : AzureRM — Authenticating to Azure (guides SP, MSI, OIDC).
Le bloc features en profondeur
Depuis plusieurs majeures AzureRM, le bloc features {} est obligatoire, même vide.
Il ne « active » pas Azure : il configure le comportement du provider pour certaines ressources.
provider "azurerm" {
features {
key_vault {
purge_soft_delete_on_destroy = true
recover_soft_deleted_key_vaults = true
}
resource_group {
prevent_deletion_if_contains_resources = false
}
virtual_machine {
delete_os_disk_on_deletion = true
}
}
}
Zone features (exemples) |
Effet typique |
|---|---|
key_vault |
Soft-delete / purge à la destruction Terraform |
resource_group |
Refuser de détruire un RG encore peuplé |
virtual_machine |
Comportement disques à la suppression de la VM |
En formation
Pour un lab, un features {} vide suffit souvent.
En prod, documentez chaque option non par défaut : elle change le résultat d’un destroy.
Auth CI sans secret long terme — WIF, App Registration, Azure DevOps
Le problème
Un Service Principal avec client_secret dans un variable group ADO fonctionne.
Mais le secret expire, fuit facilement, et laisse une longue fenêtre d’abus s’il fuite.
La solution : Workload Identity Federation (WIF / OIDC)
- Une App Registration existe dans Microsoft Entra ID.
- On y ajoute une federated credential liée au pipeline (issuer, subject, audience).
- Azure DevOps utilise une service connection ARM en mode Workload Identity federation.
- Au run, le pipeline obtient un token OIDC court.
- Terraform / le provider AzureRM s’authentifie avec ce token (
ARM_USE_OIDC,ARM_CLIENT_ID, etc.).
sequenceDiagram
participant ADO as Azure DevOps
participant Entra as Entra ID
participant TF as Terraform + azurerm
participant Az as Azure APIs
ADO->>Entra: Demande token OIDC (federated)
Entra-->>ADO: Token court
ADO->>TF: Injecte env ARM_* / token
TF->>Entra: Échange / présentation OIDC
TF->>Az: Plan / apply avec droits RBAC
Comparer les deux approches
| Critère | SP + client_secret |
WIF / OIDC |
|---|---|---|
| Secret durable | Oui | Non (jeton éphémère) |
| Rotation | Manuelle / scriptée | Portée par la fédération |
| Fuite | Haute impacte | Fenêtre courte |
| Setup initial | Plus simple | Plus de pièces (App Reg + ADO) |
| Audit | Possible | Traçabilité liée au pipeline |
Côté Terraform (idée)
Selon la tâche ADO et la version du provider, l’environnement peut ressembler à :
# Indicatif — les tâches ADO modernes injectent souvent une partie
export ARM_USE_OIDC=true
export ARM_CLIENT_ID="<app-id>"
export ARM_TENANT_ID="<tenant-id>"
export ARM_SUBSCRIPTION_ID="<sub-id>"
# ARM_OIDC_TOKEN peut être fourni par la tâche / le runner
terraform plan
Documentation utile :
Démonstration formateur (cible)
Créer App Registration + federated credential, service connection ADO WIF, puis un terraform plan depuis un pipeline.
Les élèves observent : pas de secret dans le repo, droits RBAC sur la souscription lab.
À enrichir plus tard
Capture d’écran du flux ADO, checklist pas à pas Entra, et variantes GitHub Actions OIDC.
Atelier élève guidé (si le lab partagé le permet).
Bonnes pratiques à retenir
- Le HCL décrit quoi déployer ; l’identité d’exécution vient de l’extérieur (CLI, MSI, OIDC).
- Un alias = une configuration provider, pas un « environnement magique » à lui seul.
- Distinguez lockfile providers (
.terraform.lock.hcl) et lock state (backend) — module suivant. - Pour l’examen TA-004 : savoir pourquoi on configure un provider, le rôle de
required_providers, et qu’on peut avoir plusieurs configs viaalias.
Suite
Poursuivre avec le module 5 — Gestion de l’état.
Théorie suivante : backend distant, drift, import, workspaces CLI et verrouillage du state.