FONCTIONNEMENT
Configure TerraProvider dans ton tenant et ton pipeline.
Ce que doit savoir l'ingénieur qui configure TerraProvider : comment il se connecte, quelles autorisations il demande, à quoi ressemble le premier plan et comment un tenant existant passe sous forme de code.
- terraprovider/microsoft365wp
- Terraform et OpenTofu
- 10 binaires
- version 0.20.2
Ton premier plan en quatre étapes
À peu près aussi long que la configuration de n'importe quel autre provider Azure, car la connexion fonctionne de la même façon.
Inscris une application dans Entra ID.
Locataire unique, aucun URI de redirection nécessaire. Note l'ID d'application (client) et l'ID de l'annuaire (locataire).Accorde les autorisations Graph.
Ajoute les autorisations d'application pour les objets que tu veux gérer (voir le tableau ci-dessous) et accorde le consentement administrateur.Déclare le provider.
DéfinisARM_TENANT_IDetARM_CLIENT_ID, plusARM_CLIENT_SECRETpour un premier test. Dans un pipeline, utilise plutôt OpenID Connect (voir plus bas).terraform { required_providers { microsoft365wp = { source = "terraprovider/microsoft365wp" } }}provider "microsoft365wp" {}
Lance le plan.
Écris une ressource, une stratégie de conformité par exemple, et lanceterraform planoutofu plan. Rien ne change dans le tenant tant que tu n'appliques pas.resource "microsoft365wp_device_compliance_policy" "windows_defender" { display_name = "Windows - Defender for Endpoint" windows10 = { device_threat_protection_enabled = true } scheduled_actions_for_rule = [{ scheduled_action_configurations = [{ action_type = "block" grace_period_hours = 6 }] }] assignments = [{ target = { all_licensed_users = {} } }]}
Données d'exemple.
Les autorisations Graph qu'il demande
Des autorisations d'application, accordées avec le consentement administrateur. N'accorde que celles des objets que tu gères ; une ressource absente de cette liste indique ses autorisations sur sa page de documentation.
| Autorisation | Ce qu'elle permet |
|---|---|
| DeviceManagementConfiguration.ReadWrite.All | Configuration et stratégies des appareils Intune |
| DeviceManagementApps.ReadWrite.All | Applications Intune |
| DeviceManagementServiceConfig.ReadWrite.All | Configuration du service Intune, comme l'enrôlement |
| Policy.ReadWrite.ConditionalAccess | Stratégies d'accès conditionnel |
| Policy.Read.All | Lecture des stratégies de ton organisation |
| Application.ReadWrite.All | Applications |
| Directory.ReadWrite.All | Données de l'annuaire |
| Group.ReadWrite.All | Groupes |
| User.ReadWrite.All | Profils complets des utilisateurs |
| CloudPC.ReadWrite.All | Configuration de Windows 365 |
Source : le guide du provider « Configuring a Service Principal for managing EntraID ».
Les mêmes paramètres de connexion que le provider azuread
Le provider lit les mêmes paramètres ARM_* que le provider azuread. Définis ARM_TENANT_ID et ARM_CLIENT_ID, puis choisis une méthode.
| Méthode | Quand l'utiliser | Comment l'activer |
|---|---|---|
| OpenID Connect, GitHub Actions | Workflows sans secret stocké | ARM_USE_OIDC=true |
| OpenID Connect, Azure DevOps | Pipelines avec une connexion de service | ARM_USE_OIDC=trueARM_ADO_PIPELINE_SERVICE_CONNECTION_ID |
| OpenID Connect, tout émetteur | Autres systèmes de CI qui délivrent un jeton d'ID | ARM_USE_OIDC=trueARM_OIDC_TOKEN / ARM_OIDC_TOKEN_FILE_PATH |
| Certificat client | Runners qui détiennent un certificat | ARM_CLIENT_CERTIFICATE / ARM_CLIENT_CERTIFICATE_PATH |
| Secret client | Un premier test, un labo | ARM_CLIENT_SECRET / ARM_CLIENT_SECRET_FILE_PATH |
| Identité managée | Runners sur Azure | ARM_USE_MSI=true |
| Identité de charge de travail AKS | Runners sur Kubernetes dans Azure | ARM_USE_AKS_WORKLOAD_IDENTITY=true |
| Azure CLI | Ton portable | activée par défaut ; ARM_USE_CLI=false la désactive |
Chaque paramètre existe aussi comme argument du provider (use_oidc, client_certificate_path, etc.). Le guide OpenID Connect du provider montre comment faire en sorte qu'Entra ID fasse confiance à un dépôt GitHub. En une ligne : OpenID Connect (GitHub Actions, Azure DevOps, tout jeton OIDC), certificat client, secret client, identité managée, identité de charge de travail AKS, Azure CLI.
Quatre clouds
Définis environment ou ARM_ENVIRONMENT. Le provider s'adresse alors au point de terminaison Microsoft Graph de ce cloud : mondial, US Government L4, US Government L5 (DoD), Chine.
Environnement
- global (ou public)
- Le cloud commercial, par défaut
- usgovernmentl4 (ou usgovernment)
- US Government L4
- usgovernmentl5 (ou dod)
- US Government L5 (DoD)
- china
- Le cloud de Microsoft en Chine
- Ton propre point de terminaison
metadata_hostouARM_METADATA_HOSTNAME
Ce que le plan surveille
- Les collections que tu omets sont vides par défaut, si bien qu'un membre, une exclusion ou une application ajoutés sont visibles.
- Une nouvelle stratégie d'accès conditionnel dont l'état n'est pas défini est créée en
enabledForReportingButNotEnforced. - La valeur par défaut de chaque attribut figure sur la page de documentation de la ressource, marquée comme valeur par défaut du provider.
Le revers : un paramètre que quelqu'un a activé puis désactivé dans un portail peut revenir à false au lieu de non défini, et apparaît une fois comme une modification. Un apply règle la question.
Dans le portail : Aucune modification depuis le dernier apply.
microsoft365wp_conditional_access_policy.require_mfa_admins: Refreshing state... [id=2b7f9c3e-8d41-4f6a-b0e2-5c9a1d7e3f80]No changes. Your infrastructure matches the configuration.
resource "microsoft365wp_conditional_access_policy" "require_mfa_admins" { display_name = "Require MFA for admins" state = "enabled" conditions = { users = { include_roles = ["62e90394-69f5-4237-9190-012177145e10"] } applications = { include_applications = ["All"] } } grant_controls = { operator = "OR" built_in_controls = ["mfa"] }}
Exporter et importer un tenant existant en deux phases
Le dépôt quickstart contient une configuration de référence avec des modules, des workflows GitHub Actions et un export PowerShell. L'export se fait en deux phases, car les stratégies font référence à des groupes et à des filtres.
Exporte les groupes, les filtres et les modèles de notification.
Ils sont écrits dans les modules du quickstart, avec un fichier de correspondance par type. Les groupes à extension messagerie sont laissés de côté, sauf si tu les demandes.Importe-les.
L'outil appelle Terraform ou OpenTofu pour importer chaque objet exporté dans l'état Terraform.Exporte les stratégies de conformité et de configuration.
Les stratégies du catalogue des paramètres et de sécurité des points de terminaison comptent comme stratégies de configuration. Chaque export conserve aussi un dump JSON brut de ce que Graph a renvoyé.Importe-les.
Même outil, deuxième phase.Lance le plan.
Le plan montre ce qui diffère encore. Tous les attributs ne peuvent pas être exportés, alors prévois un court nettoyage avant le premier plan propre.
Un objet à la fois
Pour tout ce que l'export ne couvre pas, un petit script écrit un fichier Terraform pour un objet de n'importe quel type de ressource, à partir de son id. Il utilise la génération de configuration propre à Terraform, si bien que le fichier contient ce que le provider lit lui-même dans le tenant.
Le quickstart sur GitHubUne seule ressource contient l'application, son package et ses attributions
microsoft365wp_mobile_app couvre 21 types d'applications. Pour les packages .intunewin, MSI, APPX/MSIX, DMG, PKG, le provider chiffre le fichier et le téléverse dans Intune, et ne recommence que si source_sha256 change. Les attributions se trouvent dans la même ressource : tous les appareils, tous les utilisateurs disposant d'une licence, un groupe ou un groupe d'exclusion, chacun avec un filtre d'inclusion ou d'exclusion.locals { agent_package = "${path.module}/packages/contoso-agent-4.2.1.intunewin" agent_meta = provider::microsoft365wp::parse_intunewin_metadata(local.agent_package)}resource "microsoft365wp_mobile_app" "contoso_agent" { display_name = "Contoso Agent" publisher = "Contoso" win32_lob = { file_name = local.agent_meta.file_name setup_file_path = local.agent_meta.setup_file install_command_line = "setup.exe /quiet" uninstall_command_line = "setup.exe /uninstall /quiet" detection_rules = [{ filesystem = { detection_type = "exists" path = "C:\\Program Files\\Contoso\\Agent" file_or_folder_name = "agent.exe" } }] source_file = local.agent_package source_sha256 = filesha256(local.agent_package) } assignments = [{ target = { group = { group_id = "3d9b2f61-7a4e-4c18-9e05-6f2a8b1c4d93" } } settings = { win32_lob = {} } }]}
microsoft365wp_mobile_app.contoso_agent: Refreshing state... [id=5e0c8a17-2d94-4b6f-a3e1-9c7d0f2b8a46]No changes. Your infrastructure matches the configuration.
# microsoft365wp_mobile_app.contoso_agent will be updated in-place ~ resource "microsoft365wp_mobile_app" "contoso_agent" { ~ win32_lob = { ~ source_file = "./packages/contoso-agent-4.2.1.intunewin" -> "./packages/contoso-agent-4.3.0.intunewin" ~ source_sha256 = "9f2c41d0…" -> "b71e05aa…" # (6 unchanged attributes hidden) } # (4 unchanged attributes hidden) }Plan: 0 to add, 1 to change, 0 to destroy.
Données d'exemple.
Windows
Win32 (.intunewin), MSI, APPX/MSIX, Microsoft Store (nouveau, via WinGet), Microsoft Store (hérité), Microsoft Edge, Microsoft 365 Apps, liens web.
macOS
DMG, PKG, Microsoft Edge, Microsoft Defender, Microsoft 365 Apps, clips web.
iOS et iPadOS
Applications de l'App Store, applications iOS gérées du store, clips web.
Android
Applications du Google Play Store, applications Google Play gérées, applications Android gérées du store.
Toutes les plateformes
Liens web.
Plusieurs tenants depuis un seul dépôt
tenant_id, écris la configuration de référence comme un module et appelle-le une fois par tenant. Chaque bloc se connecte séparément, si bien que chaque tenant peut avoir son propre principal de service avec ses propres autorisations.- Les différences entre tenants sont des variables du module, visibles dans la relecture.
- Un nouveau tenant, c'est un bloc provider, un appel de module et un plan.
provider "microsoft365wp" { alias = "contoso" tenant_id = "8a1f3c2e-5b7d-4e90-a6c4-2d9e7f1b0c35"}provider "microsoft365wp" { alias = "fabrikam" tenant_id = "e4c27b91-0d3a-4f86-b5e2-7a1c9d0f6b48"}module "baseline_contoso" { source = "./baseline" providers = { microsoft365wp = microsoft365wp.contoso }}module "baseline_fabrikam" { source = "./baseline" providers = { microsoft365wp = microsoft365wp.fabrikam } allow_byod = true}
Données d'exemple.
Comment il gère la limitation de Graph
Microsoft Graph limite le nombre de requêtes qu'un client peut envoyer, et un plan sur un grand tenant en envoie beaucoup. Le provider attend et réessaie de lui-même.
Nouvelles tentatives
- Nouvelles tentatives par requête
- jusqu'à 10
- Attente entre deux tentatives
- 3 à 60 secondes
- Un Retry-After à zéro
- Porté au délai d'attente progressif, car Graph répond souvent ainsi et une nouvelle tentative immédiate aide rarement
Commence par le quickstart.
Clone-le, fais-le pointer vers un tenant de test et lance un plan. Community Edition est gratuite pour les organisations jusqu'à 99 utilisateurs.