Azure pour les ingénieurs AWS : comment vos instincts AWS se traduisent (et où ils posent problème)
Vous savez déjà comment organiser des comptes, attribuer des autorisations et amorcer l'état dans AWS. Voici comment faire les mêmes choses dans Azure — les concepts qui se traduisent facilement, et les quatre points où votre mémoire musculaire AWS vous induira activement en erreur.
Si vous maîtrisez AWS et faites maintenant face à Azure, la bonne nouvelle est qu'environ 80 % de vos réflexes se transfèrent directement : il existe une hiérarchie pour organiser les choses, une façon basée sur les rôles d'accorder l'accès, une approche OIDC pour le CI sans clés, et une routine d'amorçage pour un "backend d'état à froid". La mauvaise nouvelle est que les 20 % restants — et ils sont concentrés dans quelques zones très fréquentées où faire les choses à la manière d'AWS produit un refus déroutant plutôt qu'une erreur évidente. Cet article est la couche de traduction : les mêmes tâches que vous effectuez dans AWS, réalisées dans Azure, avec les pièges signalés.
La version courte, si vous ne lisez qu'un seul paragraphe : AWS dispose essentiellement d'un seul plan d'autorisation (IAM), Azure en a trois qui ne communiquent pas entre eux ; les comptes AWS sont des abonnements Azure, mais la facturation se trouve ailleurs entièrement ; et Azure ajoute un conteneur obligatoire (le resource group) pour lequel AWS n'a pas de véritable équivalent. Tout ce qui suit développera ces points.
Le plus grand changement : un plan d'autorisation en devient trois
Dans AWS, IAM est en fait toute l'histoire. Un service régit vos identités, ce qu'elles peuvent faire aux ressources, et — via Organizations — comment les comptes sont créés et groupés. Les autorisations se mélangent d'une manière que vous ne remarquez probablement même pas tant qu'elle n'a pas disparu.
Azure divise délibérément ce plan unique en trois plans distincts, avec trois systèmes de rôles, trois mécanismes d'octroi et presque aucune interférence automatique. Être tout-puissant dans un plan ne vous accorde rien dans les autres. C'est la chose la plus importante à intégrer, car c'est la source de presque chaque instant de "mais je suis administrateur, pourquoi ceci est-il refusé ?".
La règle qui vous sauve : lorsqu'Azure refuse quelque chose qui "devrait" fonctionner, demandez d'abord "à quel plan est-ce que je parle ?" — puis vérifiez les rôles de ce plan. La plupart des refus mystérieux (impossible de lire un abonnement, impossible de lister les management groups, impossible de voir la facturation) ne sont pas une permission manquante au sein d'un plan — c'est vous qui parlez au mauvais plan.
Plan 1 — Entra ID directory roles (identité)
Ce plan gouverne les objets du répertoire : utilisateurs, groupes, service principals / app registrations, Conditional Access, politiques MFA, licences. Il ne gouverne pas les ressources que vous déployez.
- Les rôles ici sont des choses comme Global Administrator, User Administrator, Application Administrator. Ils sont attribués et évalués dans Entra ID et exposés via l'API Microsoft Graph.
- Global Administrator est un dieu du répertoire, pas un dieu des ressources. Cela déroute tout le monde : un Global Admin peut gérer sans problème chaque utilisateur et chaque application de l'organisation et toujours obtenir un échec d'autorisation en essayant simplement de lire un abonnement. L'analogie AWS la plus proche est "la personne qui administre IAM Identity Center et le directory lui-même" — mais elle est imparfaite, précisément parce qu'AWS fusionne l'administration du directory avec l'autorisation des ressources et qu'Azure refuse de le faire.
Plan 2 — Azure RBAC (ressources)
C'est le plan dans lequel vous vivrez, et celui que le provider Terraform azurerm pilote. Il gouverne tout ce que vous déployez : VMs, virtual networks, storage, AKS, et ainsi de suite.
- Un octroi est un triple : (principal, définition de rôle, portée), où la portée est un nœud dans la chaîne
root → management group → subscription → resource group → resource, et elle hérite vers le bas. Les rôles intégrés sont Owner, Contributor, Reader, plus toutes les définitions de rôles personnalisées que vous écrivez. - Voici le piège pour les esprits AWS : il n'y a pas de politiques attachées à l'identité. Dans AWS, vous attachez une politique IAM à un utilisateur ou à un rôle et l'autorisation voyage avec l'identité. Dans Azure, le rôle-à-une-portée est le seul modèle. La forme mentale AWS la plus proche est "une politique IAM attachée à une OU d'Organizations" — l'octroi vit sur le nœud de l'arbre, pas sur le principal.
- Le seul pont autorisé entre les plans 1 et 2 est une mesure délibérée d'accès d'urgence : un Global Administrator peut activer "Access management for Azure resources" (l'opération
elevateAccess) pour s'octroyer le rôle de User Access Administrator à la portée racine. C'est bruyant, réversible et non par défaut — vous l'utilisez une fois pendant l'amorçage pour vous attribuer le rôle Owner à la racine du tenant, ce qui hérite ensuite dans chaque abonnement.
Plan 3 — facturation / commerce (argent)
Ce plan gouverne les billing accounts, les billing profiles, les invoice sections, les payment methods — et, de manière critique, la création d'abonnements.
- Il a son propre ensemble de rôles (Billing account owner, Billing profile owner, Azure subscription creator, …), octroyés à l'intérieur du billing account et stockés dans le système de facturation. Ces rôles n'apparaissent pas dans
az role assignment listou les lames de rôles Entra. Ils constituent un monde complètement séparé. - Vous pouvez heurter ce mur des deux côtés. Des droits maximaux d'identité + ressource (Global Admin + User Access Administrator à la racine + Owner au niveau du management group racine) vous donneront toujours une liste vide de
az billing account listet aucune capacité à créer un abonnement. Inversement, un billing owner peut accorder des droits de facturation en un seul clic. - La partie la plus insidieuse : la facturation est servie via des URL REST de type ARM (
Microsoft.Billing/...), donc cela ressemble au plan des ressources — mais l'autorisation est évaluée par rapport aux rôles de facturation. Même porte, videur différent.
Une conséquence concrète à laquelle AWS ne vous fait jamais penser : la possibilité de créer des abonnements par programmation dépend entièrement de votre type de contrat de facturation. Les comptes legacy pay-as-you-go / web-direct ne peuvent créer des abonnements que manuellement dans le portail, par l'identité d'inscription originale — cette propriété n'est même pas accordable. Le Customer Agreement moderne prend en charge une API de création d'abonnement (avec des plafonds de vente au détail sur les comptes en libre-service — une poignée d'abonnements au total, et une limite de taux par jour), et les accords d'entreprise/partenaires lèvent les plafonds. Dans AWS, CreateAccount fonctionne simplement depuis le management account ; dans Azure, "puis-je créer ce compte avec du code ?" est une question du plan de facturation à laquelle vous devez répondre en premier. C'est pourquoi de nombreuses infrastructures Azure traitent les abonnements comme importés dans Terraform, jamais créés par lui.
Comment les plans s'intersectent en pratique
La plupart des tâches touchent exactement un plan, et quelques-unes en couvrent plusieurs — ce qui est la raison fondamentale pour laquelle la séparation est importante :
- Créer un utilisateur, un groupe ou une app registration → Entra seulement.
- Déployer une VM / un VNet / un storage account → ressources (Azure RBAC) seulement.
- Créer un abonnement → la facturation le crée, il se rattache à un tenant Entra, et il devient une portée Azure RBAC. Trois plans pour une action.
- Exporter les logs d'audit de répertoire vers un Log Analytics workspace → Entra (source) plus ressources (destination).
- Terraform
azurermvsazuread→ l'API de ressource vs l'API Graph — différents endpoints, différentes audiences de jetons.
Ce dernier point a une réelle implication opérationnelle : une seule connexion émet des jetons séparés par audience (un pour le resource manager, un pour Graph, un pour Key Vault). Un jeton émis pour l'API d'un plan est inutile pour celle d'un autre. Si vos outils n'en saisissent qu'un, la moitié de votre Terraform recevra mystérieusement un 401.
"Entra ID," "tenant," et "directory" sont (principalement) la même chose
Trois mots pour un objet vu sous différents angles, plus un renommage pour vous dérouter :
- Entra ID est le produit — le service d'identité. Jusqu'en 2023, c'était Azure Active Directory (Azure AD / AAD), et l'ancien nom est partout : le provider Terraform
azuread, les codes d'erreurAADSTS…, "AAD auth" dans la documentation. C'est la même chose. - Un tenant est l'instance dédiée de votre organisation d'Entra ID — le conteneur et la limite de confiance/isolation, identifié par un GUID et un domaine principal. Les utilisateurs, groupes, applications, Conditional Access et licences vivent tous par tenant et ne traversent pas les tenants.
- Le directory est le contenu d'un tenant — la base de données des objets d'identité. Un tenant équivaut à un directory, donc les gens utilisent les mots de manière interchangeable ; le bouton "Switch directory" du portail change en fait de tenant.
Les règles qui suivent sont là où l'analogie AWS devient plus lâche :
- Un abonnement se rattache à un seul tenant. Ce tenant est son domaine d'authentification et fournit ses principals RBAC. (Les abonnements peuvent être transférés entre les tenants ; la facturation est une association distincte.)
- Une organisation peut posséder plusieurs tenants. Un modèle courant est un tenant de production verrouillé plus un tenant sandbox entièrement isolé — des mondes d'identité distincts où rien de ce que vous faites dans l'un ne peut toucher l'autre. Il n'y a pas d'équivalent AWS à "un second univers d'identité complètement séparé sous la même entreprise".
- Les utilisateurs ont un tenant d'origine et peuvent être invités (B2B) ailleurs. Un invité obtient un object ID local dans le guest tenant tout en conservant son identité d'origine. AWS n'a pas de notion de première classe de "utilisateur invité du directory d'une autre organisation".
L'analogie AWS la plus lâche : un tenant est grossièrement "une AWS Organization fusionnée avec son Identity Center directory" — sauf que les abonnements s'attachent à un tenant uniquement pour l'identité, tandis que le paiement s'attache à un billing account, et les invités inter-organisations sont un concept natif.
Resource groups : le conteneur qu'AWS n'a pas
Un resource group (RG) est un conteneur obligatoire à l'intérieur d'un abonnement — chaque ressource vit dans un seul. C'est la pièce sans équivalent AWS (les "resource groups" AWS ne sont que des requêtes de tags enregistrées ; ignorez la collision de noms).
Un RG est quatre choses à la fois :
- Une portée RBAC — accordez le rôle Reader sur un RG et vous avez limité l'accès exactement à cette workload.
- Une portée de politique — attachez des règles de gouvernance au niveau du RG.
- Une unité de cycle de vie — supprimez le RG et tout ce qu'il contient disparaît avec lui.
- Une limite de coût — une ligne budgétaire naturelle pour les dépenses.
Le modèle idiomatique est un RG par workload (souvent par région), donc un RG devient "le dossier pour cette application dans cette région". Un RG a un emplacement, mais cela indique seulement où ses métadonnées résident — ses ressources peuvent se trouver dans d'autres régions, ne vous focalisez donc pas trop sur l'emplacement du RG.
Les Resource IDs portent du contexte, donc les noms n'ont pas à le faire
Chaque ressource Azure a un Resource ID complet comme /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.App/containerApps/<name>. L'abonnement et le RG voyagent avec chaque enregistrement de log, événement d'audit et appel API — le même travail que le compte et la région d'un ARN font dans AWS.
La conséquence de nommage est l'opposé de votre habitude AWS. Dans AWS, le nom est souvent le seul contexte que vous obtenez, vous y mettez donc tout. Dans Azure, les noms devraient omettre ce que la portée encode déjà : un cluster nommé aks-quest à l'intérieur de rg-quest à l'intérieur de l'abonnement qa est déjà entièrement désambiguïsé, et les mêmes noms de RG/ressource peuvent se répéter en toute sécurité à travers les abonnements dev/qa/prod. Seuls les types de ressources globalement uniques (storage accounts, container registries, Key Vaults) forcent l'org/env/region à revenir dans le nom — et ceux-ci viennent avec des limites strictes de longueur et de caractères, c'est pourquoi vous voyez des noms compressés comme stcwtfstateplatformcus.
(Ce suffixe cus n'est pas inventé, au fait — c'est le géo-code propre à Microsoft pour Central US, issu de la même table officielle qu'Azure utilise pour construire des private-endpoint DNS zones. eus/eus2 sont East US et East US 2. Apprendre la table des géo-codes tôt est payant.)
La carte rapide AWS → Azure
Gardez ceci à portée de main pendant le premier mois :
- Organization → un tenant Entra plus des management groups. L'identité (le tenant) et la structure (les management groups) sont des choses séparées dans Azure, pas une seule.
- Compte → abonnement. Se rattache à un tenant pour l'identité ; facturé par un billing account séparé.
- SCP (garde-fou) → Azure Policy à une portée de management group — avec des effets plus riches que le simple refus (audit, deny, modify, deployIfNotExists).
- Rôle/politique IAM → RBAC role assignment — (principal, rôle, portée). Rappelez-vous : pas de politiques attachées à l'identité.
- Superpouvoirs du compte racine → divisés en trois : Global Admin (identité) + elevateAccess (ressources) + billing owner (argent). Aucun principal unique ne commence avec les trois.
- Organizations
CreateAccount→ l'API d'alias d'abonnement + une portée de facturation — et uniquement sur les types de contrats de facturation qui le permettent. - IRSA (IAM Roles for Service Accounts) → workload identity federation — la même idée OIDC.
- Groupement basé sur les tags → le resource group — structurel et obligatoire, pas une requête de tag.
- ARN dans les logs → le Resource ID (colonne
_ResourceId) — le contexte de portée est structuré, pas encodé par le nom.
Amorçage de l'état Terraform, traduit
Voici un endroit où votre runbook AWS fonctionne presque, puis échoue à l'étape zéro.
L'amorçage AWS que vous connaissez : démarrer à froid un state backend dans le management account (état local, puis migrer le backend dans lui-même), garder l'état des backends par OU dans ce root backend, et créer des member accounts en utilisant leurs propres backends. L'invariant qui rend cela propre est que vous pouvez toujours amorcer depuis le root account, car il existe toujours et peut contenir un bucket S3.
Azure rompt cet invariant à la genèse. L'objet qui existe toujours est le tenant — mais un tenant ne peut pas contenir de ressources. Les storage accounts vivent dans des abonnements, et les abonnements naissent du billing plane. Donc le "root account" d'Azure est l'abonnement que vous couronnez comme racine, et vous devez en couronner un consciemment. En pratique, la plupart des tenants obtiennent un abonnement à l'inscription, donc le parallèle tient la plupart du temps : AWS vous donne un management account, Azure vous donne un premier abonnement.
Le flux traduit, lorsque les abonnements existent déjà (le cas courant) :
- Un seul démarrage à froid, toujours : déployez le state backend dans votre abonnement racine désigné avec l'état local, puis
init -migrate-statedans lui-même. - Backends par abonnement, état stocké dans le backend racine : le composant backend de chaque abonnement supplémentaire épingle son propre état au root backend, donc leur mise en place est un apply normal — plus de démarrages à froid.
- Tout le reste dans chaque abonnement utilise le backend propre à cet abonnement.
À partir de zéro (créer des abonnements avec du code), l'ordre est forcé — abonnement racine d'abord, backend racine ensuite — car un backend est un storage account et un storage account a besoin d'un abonnement pour exister. Notez une subtilité du type œuf ou poule : le provider azurerm lui-même demande un contexte d'abonnement, donc avec zéro abonnement, vous créez ce tout premier abonnement avec un appel impératif (la CLI ou le provider azapi), puis l'importez dans Terraform après coup.
Et voici où Azure est véritablement plus simple que la mémoire musculaire AWS : backend-in-root plus resources-in-member n'a besoin d'aucune des machineries de confiance hub-and-spoke d'AWS — pas de role_arn de backend, pas de assume_role de provider, pas de politiques de confiance bilatérales. Le rôle Owner au niveau du management group racine du tenant hérite dans chaque abonnement, donc un seul jeton fonctionne à l'échelle du tenant ; le provider "saute" entre les abonnements en définissant simplement subscription_id ; et le backend n'est qu'un accès aux blobs du data-plane autorisé par un octroi Storage Blob Data Contributor. Le cross-subscription est un paramètre, pas une négociation de confiance. (Vous renforcerez cela plus tard avec des rôles personnalisés, PIM et des identités CI dédiées — mais même alors ce sont des attributions de rôles à des portées, jamais un handshake de politique de confiance.) Si vous voulez approfondir la codification de l'un ou l'autre côté, l'examen HashiCorp Terraform Authoring & Operations Pro est construit autour de ces mêmes patterns d'état et de provider.
Les quatre points où vos instincts AWS vous induiront activement en erreur
Si vous oubliez tout le reste, souvenez-vous de ces points :
- "Admin" n'est pas global. Global Administrator est uniquement lié à l'identité ; il ne peut pas lire un abonnement tant que quelqu'un ne lui a pas accordé un rôle de ressource. Il n'y a pas de principal "root" unique.
- Les autorisations s'attachent aux portées, pas aux identités. Cessez de chercher la politique sur l'utilisateur — cherchez l'attribution de rôle sur le management group, l'abonnement, le resource group ou la ressource.
- La facturation est un univers distinct des ressources. "Je peux déployer n'importe quoi" ne vous dit rien sur "Je peux créer un abonnement". Plan différent, rôles différents, invisible pour
az role assignment list. - Le resource group est porteur de charge. Ce n'est pas un tag — c'est une portée RBAC, une portée de politique et une limite de suppression. Concevez votre disposition de RG intentionnellement.
Quelles certifications approfondissent chaque côté
La gouvernance du cloud — hiérarchie, identité, garde-fous et état — est la colonne vertébrale des examens d'architecture et d'administration sur les deux clouds, donc les étudier est aussi le moyen le plus rapide de faire adhérer les concepts ci-dessus. Si vous détenez déjà la certification AWS, celle d'Azure sur la même ligne est votre prochaine étape naturelle.
Du côté AWS (les connaissances que vous traduisez depuis) :
- AWS Certified Cloud Practitioner (CLF-C02) — les fondations des comptes, d'IAM et d'Organizations.
- AWS Certified Solutions Architect – Associate (SAA-C03) — IAM, structure multi-compte et architecture de base.
- AWS Certified Solutions Architect – Professional (SAP-C02) — Organizations multi-comptes, SCPs et accès inter-comptes à l'échelle.
- AWS Certified Security – Specialty (SCS-C03) — Approfondissement IAM, SCPs et gestion des clés.
Du côté Azure (les connaissances que vous traduisez vers) :
- Microsoft Certified: Azure Fundamentals (AZ-900) — tenants, abonnements, resource groups et les bases de RBAC.
- Microsoft Certified: Azure Administrator Associate (AZ-104) — le plan quotidien : RBAC, resource groups, abonnements et bases d'Entra.
- Microsoft Certified: Azure Solutions Architect Expert (AZ-305) — management groups, gouvernance et conception de landing zones.
- Microsoft Certified: Azure Security Engineer Associate (AZ-500) — Entra ID, RBAC, Azure Policy, Conditional Access et Key Vault.
Un chemin pragmatique si vous êtes certifié AWS aujourd'hui : commencez par AZ-900 pour cartographier le vocabulaire, puis passez à AZ-104 (qui se trouve dans le plan de ressources que vous utiliserez le plus), et ajoutez AZ-305 ou AZ-500 selon que votre travail penche vers l'architecture ou la sécurité.
En résumé
Azure n'est pas plus difficile qu'AWS — il est structuré différemment. AWS regroupe l'identité, les ressources et l'autorité de facturation en un seul plan et vous donne un management account qui peut tout faire. Azure sépare délibérément ces trois préoccupations, ce qui ressemble à de la friction le premier jour et à des limites claires au troisième mois. Traduisez les concepts une fois — un plan en devient trois, les comptes deviennent des abonnements facturés ailleurs, les politiques s'attachent aux portées plutôt qu'aux identités, et le resource group est une vraie structure — et le reste n'est que vocabulaire. Pratiquez-le avec les certifications ci-dessus, et les parties qui semblaient être des refus arbitraires commenceront à être perçues comme une conception cohérente et délibérée.