Automation

Infrastructure as Code

Terraform-first workflows for Microsoft Sentinel and the Defender XDR suite, with explicit callouts for the places where Defender configuration is not Terraform-managed.

Terraform Gap Map

Defender XDR has many operational and policy surfaces that are not ARM resources. Use the generated gap page to find those cases before designing a baseline module.

What is NOT TerraformGenerated from capability data
IaC tool choice flow
flowchart TD
  A[Security configuration need] --> B{Azure ARM resource}
  B -->|Stable azurerm support| C[Terraform azurerm]
  B -->|Preview or missing provider resource| D[Terraform AzAPI]
  B -->|Native Azure template baseline| E[Bicep]
  A --> F{Microsoft 365 policy}
  F -->|Exchange Online or Defender policy| G[Microsoft365DSC or PowerShell]
  F -->|Graph policy surface| H[Microsoft Graph automation]
  A --> I{KQL content}
  I --> J[Rules functions saved searches]

Azure Lighthouse Role Matrix

RoleRole definition IDUse case
Microsoft Sentinel Contributorab8e0303-f344-492f-8414-067700c6595fFull rule, playbook, and workspace configuration
Microsoft Sentinel Responder3e3c570f-7880-4494-b620-1e82d7904a08Incident triage, tagging, and assignment
Microsoft Sentinel Reader8d289e81-5878-46d4-8554-54e1e30a3b50Read-only investigation and workbook viewing
Log Analytics Contributor92ecd62a-b1db-4971-b384-542703222453Custom table creation, retention, DCR editing

AzAPI Fallbacks

Use AzAPI when Microsoft.SecurityInsights exposes a preview ARM resource before azurerm has a dedicated resource.

Workspace Manager Assignment

hcl
resource "azapi_resource" "workspace_manager_assignment" {
  type      = "Microsoft.SecurityInsights/workspaceManagerAssignments@2025-07-01-preview"
  name      = "baseline-assignment"
  parent_id = azurerm_log_analytics_workspace.central.id

  body = {
    properties = {
      targetResourceName = "tier-1-customers"
      items = [
        {
          resourceId = azurerm_sentinel_alert_rule_scheduled.suspicious_signin.id
        }
      ]
    }
  }
}

Workspace Manager Group

hcl
resource "azapi_resource" "workspace_manager_group" {
  type      = "Microsoft.SecurityInsights/workspaceManagerGroups@2025-07-01-preview"
  name      = "tier-1-customers"
  parent_id = azurerm_log_analytics_workspace.central.id

  body = {
    properties = {
      displayName         = "Tier 1 Customers"
      description         = "High-touch managed Sentinel workspaces"
      memberResourceNames = ["contoso-prod", "fabrikam-prod"]
    }
  }
}

Sentinel Preview Resource Fallback

hcl
resource "azapi_resource" "anomaly_setting" {
  type      = "Microsoft.SecurityInsights/securityMLAnalyticsSettings@2024-03-01"
  name      = "AnomalyDetectionSetting"
  parent_id = azurerm_log_analytics_workspace.sentinel.id

  body = {
    properties = {
      enabled = true
    }
  }
}
Azure Lighthouse + Terraform provider aliases

Onboard a New Customer Tenant

Delegate access from a customer tenant, keep provider configuration explicit, and bootstrap a per-customer state boundary.

hcl
resource "azurerm_lighthouse_definition" "mssp" {
  name               = "Sentinel baseline delegation"
  managing_tenant_id = var.managing_tenant_id
  scope              = "/subscriptions/${var.customer_subscription_id}"

  authorization {
    principal_id           = var.mssp_group_object_id
    principal_display_name = "MSSP Sentinel Operators"
    role_definition_id     = "b24988ac-6180-42a0-ab88-20f7382dd24c"
  }
}
Terraform azurerm + azapi

Deploy the Sentinel Baseline

Create the workspace, enable Sentinel, assign RBAC, configure retention, and deploy unsupported Sentinel resource kinds through azapi.

hcl
resource "azurerm_log_analytics_workspace" "sentinel" {
  name                = var.workspace_name
  location            = var.location
  resource_group_name = azurerm_resource_group.security.name
  sku                 = "PerGB2018"
  retention_in_days   = 90
}

resource "azapi_resource" "sentinel_onboarding" {
  type      = "Microsoft.SecurityInsights/onboardingStates@2025-09-01"
  name      = "default"
  parent_id = azurerm_log_analytics_workspace.sentinel.id
  body = {
    properties = {
      customerManagedKey = false
    }
  }
}
Terraform module

Deploy Analytics and Automation Rules

Ship a pinned baseline module that deploys scheduled rules, automation rules, watchlists, and documented azapi fallbacks for unsupported rule kinds.

hcl
module "sentinel_baseline" {
  source  = "git::https://github.com/example/security-baselines.git//modules/sentinel-baseline?ref=v1.4.2"

  workspace_id       = azurerm_log_analytics_workspace.sentinel.id
  rule_pack          = "mssp-standard"
  notification_email = var.customer_soc_email
}
azurerm Logic App + Sentinel automation rule

Deploy a Playbook and Wire Automation

Deploy a Logic App playbook and connect it to incident creation or update events with a Sentinel automation rule.

hcl
resource "azurerm_logic_app_workflow" "triage" {
  name                = "sentinel-phishing-triage"
  location            = var.location
  resource_group_name = azurerm_resource_group.security.name
}

resource "azurerm_sentinel_automation_rule" "run_triage" {
  name                       = "run-phishing-triage"
  log_analytics_workspace_id = azurerm_log_analytics_workspace.sentinel.id
  display_name               = "Run phishing triage playbook"
  order                      = 1
  enabled                    = true
}
GitHub Actions or Azure DevOps matrix

Detect Drift Across Tenants

Run scheduled plan-only jobs per customer tenant and surface drifted, failed, or clean status before any approval/apply step.

yaml
strategy:
  matrix:
    customer: [contoso, fabrikam, northwind]

steps:
  - uses: actions/checkout@v4
  - uses: hashicorp/setup-terraform@v3
  - run: terraform init -backend-config=customers/${{ matrix.customer }}/backend.hcl
  - run: terraform plan -var-file=customers/${{ matrix.customer }}/terraform.tfvars -detailed-exitcode