Aller au contenu

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 features existe 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)

  1. Une App Registration existe dans Microsoft Entra ID.
  2. On y ajoute une federated credential liée au pipeline (issuer, subject, audience).
  3. Azure DevOps utilise une service connection ARM en mode Workload Identity federation.
  4. Au run, le pipeline obtient un token OIDC court.
  5. 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 via alias.

Suite

Poursuivre avec le module 5 — Gestion de l’état.
Théorie suivante : backend distant, drift, import, workspaces CLI et verrouillage du state.