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
CONFIGURACIÓN

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.

  1. 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).
  2. 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.
  3. Declara el proveedor.

    Define ARM_TENANT_ID y ARM_CLIENT_ID, además de ARM_CLIENT_SECRET para una primera prueba. En un pipeline, usa OpenID Connect en su lugar (más abajo).
    main.tf
    terraform {  required_providers {    microsoft365wp = {      source = "terraprovider/microsoft365wp"    }  }}provider "microsoft365wp" {}
  4. Plan.

    Escribe un recurso, por ejemplo una política de cumplimiento, y ejecuta terraform plan o tofu plan. Nada cambia en el tenant hasta que apliques.
    compliance.tf
    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.

PERMISOS

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.

Los permisos de Graph que solicita
PermisoQué permite
DeviceManagementConfiguration.ReadWrite.AllConfiguración de dispositivos y políticas de Intune
DeviceManagementApps.ReadWrite.AllApps de Intune
DeviceManagementServiceConfig.ReadWrite.AllConfiguración del servicio Intune, como la inscripción
Policy.ReadWrite.ConditionalAccessPolíticas de acceso condicional
Policy.Read.AllLectura de las políticas de tu organización
Application.ReadWrite.AllAplicaciones
Directory.ReadWrite.AllDatos de directorio
Group.ReadWrite.AllGrupos
User.ReadWrite.AllPerfiles completos de usuarios
CloudPC.ReadWrite.AllConfiguración de Windows 365

Fuente: la guía del proveedor "Configuring a Service Principal for managing EntraID".

INICIO DE SESIÓN

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.

La misma configuración de inicio de sesión que el proveedor azuread
MétodoCuándo usarloCómo activarlo
OpenID Connect, GitHub ActionsWorkflows sin un secreto almacenadoARM_USE_OIDC=true
OpenID Connect, Azure DevOpsPipelines con una conexión de servicioARM_USE_OIDC=true
ARM_ADO_PIPELINE_SERVICE_CONNECTION_ID
OpenID Connect, cualquier emisorOtros sistemas de CI que emiten un ID tokenARM_USE_OIDC=true
ARM_OIDC_TOKEN / ARM_OIDC_TOKEN_FILE_PATH
Certificado de clienteRunners que disponen de un certificadoARM_CLIENT_CERTIFICATE / ARM_CLIENT_CERTIFICATE_PATH
Secreto de clienteUna primera prueba, un laboratorioARM_CLIENT_SECRET / ARM_CLIENT_SECRET_FILE_PATH
Identidad administradaRunners en AzureARM_USE_MSI=true
AKS workload identityRunners en Kubernetes en AzureARM_USE_AKS_WORKLOAD_IDENTITY=true
Azure CLITu portátilactivo 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_host or ARM_METADATA_HOSTNAME
DRIFT

Qué vigila el plan

Terraform compara tu configuración con lo que informa el tenant. TerraProvider hace que esa comparación abarque el objeto completo: cada atributo que no defines recibe un valor por defecto, tomado de lo que los portales de Microsoft devuelven al crear el mismo objeto desde allí. Así, una exclusión añadida a una política en el portal, un interruptor activado en el centro de administración de Intune o un ajuste modificado por un script aparece en el siguiente plan, lo mencione o no tu archivo.
  • 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.
Datos de ejemplo.
TENANT EXISTENTE

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.

  1. 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.
  2. Impórtalos.

    La herramienta llama a Terraform o OpenTofu para importar cada objeto exportado al estado.
  3. 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.
  4. Impórtalas.

    La misma herramienta, segunda fase.
  5. 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 GitHub
APPS

Un ú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 = {} }  }]}

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.

TENANTS

Varios tenants desde un único repositorio

Un bloque de proveedor inicia sesión en un tenant. Para varios tenants, declara un bloque por tenant con un alias y su 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.
main.tf
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.