CÓMO FUNCIONA
Configura TerraProvider en tu tenant y pipeline.
Lo que el ingeniero que configura TerraProvider necesita saber: cómo inicia sesión, qué permisos solicita, cómo es el primer plan y cómo se lleva un tenant existente al código.
- terraprovider/microsoft365wp
- Terraform and OpenTofu
- 10 builds
- versión 0.20.2
Tu primer plan en cuatro pasos
Más o menos lo mismo que configurar cualquier otro proveedor de Azure, porque el inicio de sesión funciona igual.
Registra una aplicación en Entra ID.
Un único tenant, sin URI de redirección. Anota el ID de aplicación (cliente) y el ID de directorio (tenant).Concede permisos de Graph.
Añade los permisos de aplicación para los objetos que quieras gestionar (consulta la tabla más abajo) y otorga el consentimiento de administrador.Declara el proveedor.
DefineARM_TENANT_IDyARM_CLIENT_ID, además deARM_CLIENT_SECRETpara una primera prueba. En un pipeline, usa OpenID Connect en su lugar (más abajo).terraform { required_providers { microsoft365wp = { source = "terraprovider/microsoft365wp" } }}provider "microsoft365wp" {}
Plan.
Escribe un recurso, por ejemplo una política de cumplimiento, y ejecutaterraform planotofu plan. Nada cambia en el tenant hasta que apliques.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 = {} } }]}
Datos de ejemplo.
Los permisos de Graph que solicita
Permisos de aplicación, concedidos con consentimiento de administrador. Concede únicamente los que correspondan a los objetos que gestionas; un recurso no listado aquí indica sus permisos en su página de documentación.
| Permiso | Qué permite |
|---|---|
| DeviceManagementConfiguration.ReadWrite.All | Configuración de dispositivos y políticas de Intune |
| DeviceManagementApps.ReadWrite.All | Apps de Intune |
| DeviceManagementServiceConfig.ReadWrite.All | Configuración del servicio Intune, como la inscripción |
| Policy.ReadWrite.ConditionalAccess | Políticas de acceso condicional |
| Policy.Read.All | Lectura de las políticas de tu organización |
| Application.ReadWrite.All | Aplicaciones |
| Directory.ReadWrite.All | Datos de directorio |
| Group.ReadWrite.All | Grupos |
| User.ReadWrite.All | Perfiles completos de usuarios |
| CloudPC.ReadWrite.All | Configuración de Windows 365 |
Fuente: la guía del proveedor "Configuring a Service Principal for managing EntraID".
La misma configuración de inicio de sesión que el proveedor azuread
El proveedor lee la misma configuración ARM_* que el proveedor azuread. Define ARM_TENANT_ID y ARM_CLIENT_ID, luego elige un método.
| Método | Cuándo usarlo | Cómo activarlo |
|---|---|---|
| OpenID Connect, GitHub Actions | Workflows sin un secreto almacenado | ARM_USE_OIDC=true |
| OpenID Connect, Azure DevOps | Pipelines con una conexión de servicio | ARM_USE_OIDC=trueARM_ADO_PIPELINE_SERVICE_CONNECTION_ID |
| OpenID Connect, cualquier emisor | Otros sistemas de CI que emiten un ID token | ARM_USE_OIDC=trueARM_OIDC_TOKEN / ARM_OIDC_TOKEN_FILE_PATH |
| Certificado de cliente | Runners que disponen de un certificado | ARM_CLIENT_CERTIFICATE / ARM_CLIENT_CERTIFICATE_PATH |
| Secreto de cliente | Una primera prueba, un laboratorio | ARM_CLIENT_SECRET / ARM_CLIENT_SECRET_FILE_PATH |
| Identidad administrada | Runners en Azure | ARM_USE_MSI=true |
| AKS workload identity | Runners en Kubernetes en Azure | ARM_USE_AKS_WORKLOAD_IDENTITY=true |
| Azure CLI | Tu portátil | activo por defecto; ARM_USE_CLI=false lo desactiva |
Cada configuración existe también como argumento del proveedor (use_oidc, client_certificate_path, etc.). La guía de OpenID Connect del proveedor muestra cómo hacer que Entra ID confíe en un repositorio de GitHub. En resumen: OpenID Connect (GitHub Actions, Azure DevOps, cualquier token OIDC), certificado de cliente, secreto de cliente, identidad administrada, AKS workload identity, Azure CLI.
Cuatro clouds
Define environment o ARM_ENVIRONMENT. El proveedor se comunicará entonces con el endpoint de Microsoft Graph de ese cloud: global, US Government L4, US Government L5 (DoD), China.
Entorno
- global (también public)
- El cloud comercial, el valor por defecto
- usgovernmentl4 (también usgovernment)
- US Government L4
- usgovernmentl5 (también dod)
- US Government L5 (DoD)
- china
- El cloud de Microsoft en China
- Tu propio endpoint
metadata_hostorARM_METADATA_HOSTNAME
Qué vigila el plan
- Las colecciones que omites tienen como valor por defecto vacío, por lo que un miembro, exclusión o app añadidos son visibles.
- Una nueva política de acceso condicional sin estado se crea como
enabledForReportingButNotEnforced. - El valor por defecto de cada atributo está en la página de documentación del recurso, marcado como el valor por defecto del proveedor.
La otra cara: un ajuste que alguien activó y desactivó en un portal puede volver como false en lugar de no estar definido, y aparece una vez como un cambio. Un apply lo resuelve.
En el portal: Sin cambios desde el último 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"] }}
Exporta e importa un tenant existente en dos fases
El repositorio quickstart incluye una configuración de referencia con módulos, workflows de GitHub Actions y una exportación en PowerShell. La exportación funciona en dos fases, porque las políticas hacen referencia a grupos y filtros.
Exporta grupos, filtros y plantillas de notificación.
Se escriben en los módulos del quickstart, con un archivo de mapeo para cada tipo. Los grupos con correo habilitado se excluyen salvo que los solicites expresamente.Impórtalos.
La herramienta llama a Terraform o OpenTofu para importar cada objeto exportado al estado.Exporta las políticas de cumplimiento y configuración.
Las políticas del catálogo de configuración y las políticas de seguridad de endpoint cuentan como políticas de configuración. Cada exportación también conserva un volcado JSON sin procesar de lo que devolvió Graph.Impórtalas.
La misma herramienta, segunda fase.Plan.
El plan muestra lo que aún difiere. No todos los atributos se pueden exportar, así que espera una pequeña limpieza antes del primer plan limpio.
Un objeto a la vez
Para lo que la exportación no cubre, un pequeño script escribe un archivo Terraform para un objeto de cualquier tipo de recurso, dado su id. Utiliza la generación de configuración propia de Terraform, por lo que el archivo contiene lo que el proveedor mismo lee del tenant.
El quickstart en GitHubUn único recurso agrupa la app, su paquete y sus asignaciones
microsoft365wp_mobile_app cubre 21 tipos de app. Para los paquetes de .intunewin, MSI, APPX/MSIX, DMG, PKG, el proveedor cifra el archivo y lo sube a Intune, y lo repite únicamente cuando cambia source_sha256. Las asignaciones están en el mismo recurso: todos los dispositivos, todos los usuarios con licencia, un grupo o un grupo de exclusión, cada uno con un filtro de inclusión o exclusión.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.
Datos de ejemplo.
Windows
Win32 (.intunewin), MSI, APPX/MSIX, Microsoft Store (nuevo, vía WinGet), Microsoft Store (legacy), Microsoft Edge, Microsoft 365 Apps, enlaces web.
macOS
DMG, PKG, Microsoft Edge, Microsoft Defender, Microsoft 365 Apps, web clips.
iOS y iPadOS
Apps de App Store, apps administradas de la tienda de iOS, web clips.
Android
Apps de Google Play Store, apps administradas de Google Play, apps administradas de la tienda de Android.
Cualquier plataforma
Enlaces web.
Varios tenants desde un único repositorio
tenant_id, escribe la configuración base como módulo y llámalo una vez por tenant. Cada bloque inicia sesión de forma independiente, por lo que cada tenant puede tener su propio service principal con sus propios permisos.- Las diferencias entre tenants son variables del módulo, visibles en la revisión.
- Un nuevo tenant equivale a un bloque de proveedor, una llamada al módulo y 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}
Datos de ejemplo.
Cómo gestiona el throttling de Graph
Microsoft Graph limita el número de solicitudes que un cliente puede enviar, y un plan sobre un tenant grande envía muchas. El proveedor espera y reintenta por su cuenta.
Reintentos
- Reintentos por solicitud
- hasta 10
- Espera entre reintentos
- 3 a 60 segundos
- Un Retry-After de cero
- Se extiende al backoff, porque Graph suele responder así y un reintento inmediato raramente ayuda
Empieza con el quickstart.
Clónalo, apúntalo a un tenant de prueba y ejecuta un plan. La Community Edition es gratuita para organizaciones de hasta 99 usuarios.