<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged landingzone</title>
<link>https://coderlegion.com/tag/landingzone</link>
<description>Powered by Question2Answer</description>
<item>
<title>Azure Landing Zone - Policy at Scale</title>
<link>https://coderlegion.com/8100/azure-landing-zone-policy-at-scale</link>
<description>&lt;h2 id=&quot;azure-policy-in-real-landing-zones&quot;&gt;Azure Policy in Real Landing Zones&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;Onboard multiple Azure subscriptions into a real landing zone using Azure Policy, management groups, and policy-as-code for enterprise governance.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;introduction&quot;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;On paper, Azure Landing Zones and Azure Policy look clean and deterministic. In reality, you're onboarding dozens or hundreds of subscriptions with existing workloads, legacy configurations, and multiple teams that all think they're special.&lt;/p&gt;
&lt;p&gt;This article focuses on &lt;strong&gt;using Azure Policy to onboard multiple subscriptions into a real, enterprise-grade landing zone&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How to structure &lt;strong&gt;management groups&lt;/strong&gt; and &lt;strong&gt;policy initiatives&lt;/strong&gt; for scalable governance&lt;/li&gt;
&lt;li&gt;How to onboard &lt;strong&gt;brownfield&lt;/strong&gt; and &lt;strong&gt;greenfield&lt;/strong&gt; subscriptions safely&lt;/li&gt;
&lt;li&gt;How to use &lt;strong&gt;policy as code&lt;/strong&gt; and CI/CD to operate this at scale&lt;/li&gt;
&lt;li&gt;How to balance &lt;strong&gt;security, reliability, and delivery velocity&lt;/strong&gt; when policies start denying real traffic&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The scope is Azure-first, but the patterns map naturally to AWS Organizations + SCPs and GCP Organization policies.&lt;/p&gt;
&lt;h3 id=&quot;core-concepts&quot;&gt;Core Concepts&lt;/h3&gt;
&lt;h4 id=&quot;azure-landing-zone-in-governance-terms&quot;&gt;Azure Landing Zone in Governance Terms&lt;/h4&gt;
&lt;p&gt;Forget marketing. In governance terms, an &lt;strong&gt;Azure Landing Zone&lt;/strong&gt; is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;management group hierarchy&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;A set of &lt;strong&gt;policy initiatives&lt;/strong&gt; (built-in and custom)&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;baseline of guardrails&lt;/strong&gt; for networking, identity, security, and operations&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;repeatable way&lt;/strong&gt; to onboard subscriptions and apps into that baseline&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Key Azure building blocks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Management groups (MGs)&lt;/strong&gt; – hierarchical containers for subscriptions; policies applied here flow down&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Azure Policy definitions&lt;/strong&gt; – rules for what is allowed, denied, audited, or automatically deployed&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Policy initiatives&lt;/strong&gt; – logical bundles of policy definitions (e.g., CAF &quot;Azure Landing Zone&quot; initiatives)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Assignments&lt;/strong&gt; – binding a definition/initiative to a scope (management group, subscription, resource group)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Effects&lt;/strong&gt; – &lt;code&gt;Deny&lt;/code&gt;, &lt;code&gt;Audit&lt;/code&gt;, &lt;code&gt;DeployIfNotExists&lt;/code&gt;, &lt;code&gt;Modify&lt;/code&gt;, &lt;code&gt;Append&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remediation tasks&lt;/strong&gt; – jobs created to apply &lt;code&gt;DeployIfNotExists&lt;/code&gt;/&lt;code&gt;Modify&lt;/code&gt; to existing resources&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;management-group-hierarchy-for-real-landing-zones&quot;&gt;Management Group Hierarchy for Real Landing Zones&lt;/h4&gt;
&lt;p&gt;A pragmatic, enterprise-friendly hierarchy often looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Tenant Root ( / )
 ├─ Platform
 │   ├─ Identity
 │   ├─ Management
 │   ├─ Connectivity
 ├─ LandingZones
 │   ├─ Corp
 │   │   ├─ Corp-Prod
 │   │   ├─ Corp-NonProd
 │   ├─ Online
 │       ├─ Online-Prod
 │       ├─ Online-NonProd
 └─ Sandbox
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Patterns:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Platform&lt;/strong&gt; MGs host shared services: identity, networking, management&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LandingZones&lt;/strong&gt; MGs host application subscriptions grouped by business domain / criticality&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sandbox&lt;/strong&gt; MG for low-governance experimental spaces&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Policy is usually bound at &lt;strong&gt;Platform&lt;/strong&gt;, &lt;strong&gt;LandingZones&lt;/strong&gt;, and specific &lt;strong&gt;child MGs&lt;/strong&gt; such as &lt;code&gt;Corp-Prod&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&quot;policy-as-code-and-devsecops&quot;&gt;Policy as Code and DevSecOps&lt;/h4&gt;
&lt;p&gt;Azure Policy without automation becomes unmaintainable as soon as you pass 5 subscriptions.&lt;/p&gt;
&lt;p&gt;Treat Azure Policy as code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Definitions and initiatives&lt;/strong&gt; stored as JSON in Git (or Bicep/ARM modules, or Terraform)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pipelines&lt;/strong&gt; (Azure DevOps or GitHub Actions) that:&lt;ul&gt;
&lt;li&gt;Validate policies (linting, schema checks)&lt;/li&gt;
&lt;li&gt;Publish definitions to the management group scope&lt;/li&gt;
&lt;li&gt;Assign initiatives with parameter values per environment (dev/test/prod)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PR-based change control&lt;/strong&gt; for all policy changes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security and platform teams&lt;/strong&gt; collaborate on policy sets and exemptions through Git, not the portal&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;High-level mapping of key services:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DevOps tooling:&lt;/strong&gt; Azure DevOps Pipelines / GitHub Actions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Governance:&lt;/strong&gt; Azure Policy, Management Groups, Azure Blueprints (phasing out), CAF landing zone initiatives&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security:&lt;/strong&gt; Defender for Cloud, Key Vault, Managed Identities, Entra ID (Azure AD)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Observability:&lt;/strong&gt; Azure Monitor, Log Analytics, Application Insights&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;step-by-step-guide&quot;&gt;Step-by-Step Guide&lt;/h3&gt;
&lt;h4 id=&quot;1-prerequisites-and-roles&quot;&gt;1. Prerequisites and Roles&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tenant-level setup&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Management group hierarchy defined and approved&lt;/li&gt;
&lt;li&gt;Tenant Root Group locked down to a small platform/governance team&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Access&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Platform team with &lt;code&gt;Owner&lt;/code&gt; or &lt;code&gt;Contributor&lt;/code&gt; + &lt;code&gt;Resource Policy Contributor&lt;/code&gt; at key MGs&lt;/li&gt;
&lt;li&gt;Security team with &lt;code&gt;Security Admin&lt;/code&gt; + rights to define/approve policies&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tools&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Git repository for policy-as-code&lt;/li&gt;
&lt;li&gt;CI/CD pipelines (Azure DevOps or GitHub Actions)&lt;/li&gt;
&lt;li&gt;Landing zone reference (CAF-aligned) selected and tailored&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Team ownership:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Platform team:&lt;/strong&gt; management groups, policy initiatives, CI/CD&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security team:&lt;/strong&gt; security controls, approvals, exceptions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;App teams:&lt;/strong&gt; subscription ownership, remediation work, exception requests&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;2-design-the-management-group-strategy&quot;&gt;2. Design the Management Group Strategy&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Define environments&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Separate &lt;strong&gt;Prod&lt;/strong&gt; and &lt;strong&gt;NonProd&lt;/strong&gt; at MG level where possible (&lt;code&gt;Corp-Prod&lt;/code&gt;, &lt;code&gt;Corp-NonProd&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Critical workloads can have their own branch (&lt;code&gt;Payments-Prod&lt;/code&gt; MG)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Align policies with MG scopes&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tenant root: only minimal guardrails (e.g., logging, naming, maybe region restrictions)&lt;/li&gt;
&lt;li&gt;Platform MG: policies for shared services (diagnostics, DDoS plan requirements, etc.)&lt;/li&gt;
&lt;li&gt;LandingZones MG: baseline security, networking, and operational standards for all app subscriptions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Key rule:&lt;/strong&gt; &lt;strong&gt;You should not assign policies directly to individual subscriptions unless there is a strong, documented reason.&lt;/strong&gt; Use management groups as default.&lt;/p&gt;
&lt;h4 id=&quot;3-define-and-version-your-policy-library&quot;&gt;3. Define and Version Your Policy Library&lt;/h4&gt;
&lt;p&gt;Use a structure like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;policies/
  definitions/
    security/
      allowed-locations.json
      vm-require-managed-disks.json
    operations/
      deploy-diagnostics-to-log-analytics.json
    networking/
      require-private-endpoints.json
  initiatives/
    alz-core.json
    alz-security.json
    alz-networking.json
  assignments/
    Corp-NonProd/
      alz-core.json
      alz-security.json
    Corp-Prod/
      alz-core.json
      alz-security.json
      alz-networking.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Example &lt;strong&gt;Terraform&lt;/strong&gt; snippet for an initiative assignment:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-hcl&quot;&gt;resource &quot;azurerm_policy_set_definition&quot; &quot;alz_core&quot; {
  name         = &quot;alz-core&quot;
  display_name = &quot;ALZ Core Baseline&quot;
  policy_type  = &quot;Custom&quot;
  management_group_id = data.azurerm_management_group.landingzones.id

  policy_definitions = [
    {
      policy_definition_id = data.azurerm_policy_definition.allowed_locations.id
      parameters           = jsonencode({ listOfAllowedLocations = { value = [&quot;westeurope&quot;, &quot;northeurope&quot;] } })
    },
    {
      policy_definition_id = data.azurerm_policy_definition.deploy_diagnostics.id
      parameters           = jsonencode({ logAnalytics = { value = &quot;/subscriptions/.../resourceGroups/rg-logs/providers/Microsoft.OperationalInsights/workspaces/lz-logs-weu&quot; } })
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then assign that initiative to a specific management group:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-hcl&quot;&gt;resource &quot;azurerm_policy_set_definition&quot; &quot;alz_core&quot; {
  # as above
}

resource &quot;azurerm_policy_assignment&quot; &quot;alz_core_corp_prod&quot; {
  name                 = &quot;alz-core-corp-prod&quot;
  display_name         = &quot;ALZ Core for Corp Prod&quot;
  policy_definition_id = azurerm_policy_set_definition.alz_core.id
  scope                = data.azurerm_management_group.corp_prod.id

  identity {
    type = &quot;SystemAssigned&quot;
  }

  location = &quot;westeurope&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;4-build-ci-cd-for-policies&quot;&gt;4. Build CI/CD for Policies&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Example: GitHub Actions workflow for policy deployment (simplified):&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;name: Deploy Azure Policies

on:
  push:
    branches: [ main ]
    paths:
      - 'policies/**'

jobs:
  deploy-policies:
    runs-on: ubuntu-latest
    env:
      AZURE_MG_ID: /providers/Microsoft.Management/managementGroups/landingzones
    steps:
      - uses: actions/checkout@v4

      - uses: azure/login@v2
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: Validate policy JSON
        run: |
          python scripts/validate_policies.py policies/definitions
          python scripts/validate_initiatives.py policies/initiatives

      - name: Deploy policy definitions
        run: |
          az deployment mg create \
            --management-group-id ${AZURE_MG_ID##*/} \
            --template-file infra/policies/definitions.bicep \
            --parameters definitionsPath=policies/definitions

      - name: Deploy policy initiatives and assignments
        run: |
          az deployment mg create \
            --management-group-id ${AZURE_MG_ID##*/} \
            --template-file infra/policies/initiatives.bicep \
            --parameters initiativesPath=policies/initiatives assignmentsPath=policies/assignments
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Key points:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;service principals with least privilege&lt;/strong&gt; for policy deployment&lt;/li&gt;
&lt;li&gt;Validate JSON / Bicep / Terraform as part of the pipeline&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;separate pipelines&lt;/strong&gt; or stages for dev vs prod MGs&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;5-onboard-subscriptions-brownfield-vs-greenfield&quot;&gt;5. Onboard Subscriptions: Brownfield vs Greenfield&lt;/h4&gt;
&lt;h5 id=&quot;5-1-greenfield-subscriptions&quot;&gt;5.1 Greenfield subscriptions&lt;/h5&gt;
&lt;p&gt;For new subscriptions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create subscription via &lt;strong&gt;automation&lt;/strong&gt; (e.g., Azure Deployment Environments, Azure DevOps pipeline, Terraform, custom portal)&lt;/li&gt;
&lt;li&gt;Ensure the new subscription is placed in the correct &lt;strong&gt;management group&lt;/strong&gt; (&lt;code&gt;Corp-NonProd&lt;/code&gt;, &lt;code&gt;Corp-Prod&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;Policies auto-apply from the MG&lt;/li&gt;
&lt;li&gt;Validate:&lt;ul&gt;
&lt;li&gt;Subscription appears in management group&lt;/li&gt;
&lt;li&gt;Policy assignments list inherited initiatives&lt;/li&gt;
&lt;li&gt;First deployments from app team resources comply with policy&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id=&quot;5-2-brownfield-subscriptions-existing-workloads-&quot;&gt;5.2 Brownfield subscriptions (existing workloads)&lt;/h5&gt;
&lt;p&gt;Onboarding existing subscriptions is where Azure Policy meets reality.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Process:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Discovery&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Move subscription into a temporary MG (e.g., &lt;code&gt;Brownfield-Quarantine&lt;/code&gt;) where only &lt;strong&gt;Audit&lt;/strong&gt; policies are applied&lt;/li&gt;
&lt;li&gt;Run compliance scans and export non-compliance via Azure Resource Graph or &lt;code&gt;az policy state&lt;/code&gt; CLI&lt;/li&gt;
&lt;li&gt;Classify findings: high-risk (public IPs, missing encryption, no backups), medium, low&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Define migration strategy&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Agree with app owners on timelines and responsibility for remediation&lt;/li&gt;
&lt;li&gt;For some controls, use &lt;code&gt;DeployIfNotExists&lt;/code&gt; or &lt;code&gt;Modify&lt;/code&gt; to auto-remediate&lt;/li&gt;
&lt;li&gt;For hard-breaking changes, schedule maintenance windows&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gradual enforcement&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Phase 1: Audit-only policies at target landing zone MG&lt;/li&gt;
&lt;li&gt;Phase 2: Switch selected controls to &lt;strong&gt;Deny&lt;/strong&gt; for new deployments, keep existing resources under &lt;code&gt;Audit&lt;/code&gt;/&lt;code&gt;DeployIfNotExists&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Phase 3: Fully enforce policies including existing resources (if realistic)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Move subscription into its final MG&lt;/strong&gt; once:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Critical non-compliances are addressed or excepted&lt;/li&gt;
&lt;li&gt;Auto-remediation jobs have run and are monitored&lt;/li&gt;
&lt;li&gt;App team acknowledges and accepts the landing zone guardrails&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;6-operationalizing-policy-remediation-and-exceptions&quot;&gt;6. Operationalizing Policy: Remediation and Exceptions&lt;/h4&gt;
&lt;h5 id=&quot;6-1-remediation&quot;&gt;6.1 Remediation&lt;/h5&gt;
&lt;p&gt;For &lt;code&gt;DeployIfNotExists&lt;/code&gt; / &lt;code&gt;Modify&lt;/code&gt; policies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enable &lt;strong&gt;system-assigned managed identity&lt;/strong&gt; on policy assignments to perform changes&lt;/li&gt;
&lt;li&gt;Trigger remediation tasks via portal or CLI:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;az policy remediation create \
  --name fix-diag-settings \
  --policy-assignment &quot;/subscriptions/&amp;lt;subId&amp;gt;/providers/Microsoft.Authorization/policyAssignments/alz-core-corp-prod&quot; \
  --resource-group rg-app-prod
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Monitor remediation status via:&lt;ul&gt;
&lt;li&gt;Azure Policy compliance dashboard&lt;/li&gt;
&lt;li&gt;Azure Monitor alerts on failed remediation tasks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&quot;6-2-exceptions-and-exemptions&quot;&gt;6.2 Exceptions and Exemptions&lt;/h5&gt;
&lt;p&gt;Not everything can be compliant on day one.&lt;/p&gt;
&lt;p&gt;Use &lt;strong&gt;Azure Policy exemptions&lt;/strong&gt; instead of deleting or bypassing policies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scope exemptions to the smallest possible asset (resource group or resource)&lt;/li&gt;
&lt;li&gt;Make them &lt;strong&gt;time-bound&lt;/strong&gt; where possible (expiration date)&lt;/li&gt;
&lt;li&gt;Track exemptions in Git (YAML/JSON manifest) to avoid &quot;exception sprawl&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;architecture-overview&quot;&gt;Architecture Overview&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=15030704013584984996&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;This shows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Policy-as-code flowing through CI/CD into MG scopes&lt;/li&gt;
&lt;li&gt;Subscriptions inheriting initiatives from their MGs&lt;/li&gt;
&lt;li&gt;Clear ownership separation between platform, security, and app teams&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;best-practices&quot;&gt;Best Practices&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Start with management groups, not subscriptions&lt;/strong&gt;&lt;br&gt;
Design and agree your MG hierarchy before onboarding more subscriptions&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bundle policies into coherent initiatives&lt;/strong&gt;&lt;br&gt;
Organize by domain: &lt;code&gt;alz-core&lt;/code&gt;, &lt;code&gt;alz-security&lt;/code&gt;, &lt;code&gt;alz-networking&lt;/code&gt;, &lt;code&gt;alz-ops&lt;/code&gt; rather than hundreds of standalone assignments&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Audit-first, then Deny&lt;/strong&gt;&lt;br&gt;
Introduce policies as &lt;code&gt;Audit&lt;/code&gt;, analyze impact, then promote selected controls to &lt;code&gt;Deny&lt;/code&gt; for new deployments&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Separate baselines for Prod vs NonProd&lt;/strong&gt;&lt;br&gt;
NonProd can have more permissive policies (e.g., broader locations, less strict SKUs). Prod should be tightly controlled&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Make policy-as-code mandatory&lt;/strong&gt;&lt;br&gt;
Disallow manual creation or modification of policy assignments outside pipelines (and detect them via drift monitoring)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Minimize tenant root scope policies&lt;/strong&gt;&lt;br&gt;
Place most policies at Landing Zone MG scope; keep tenant root focused on tenant-wide essentials (e.g., disallowed regions, high-level logging)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automate subscription creation and placement&lt;/strong&gt;&lt;br&gt;
Never create subscriptions manually via portal for production scenarios. Use pipelines + APIs to enforce correct MG placement and tags&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integrate policy results into observability&lt;/strong&gt;&lt;br&gt;
Export compliance and remediation metrics to Log Analytics, build dashboards and alerts (e.g., % compliance per landing zone, per team)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Align policy with security standards&lt;/strong&gt;&lt;br&gt;
Map initiatives to CIS, NIST, ISO controls; use Defender for Cloud and CAF recommendations to inform baseline&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;common-pitfalls&quot;&gt;Common Pitfalls&lt;/h3&gt;
&lt;h4 id=&quot;1-deny-everything-from-day-one&quot;&gt;1. &quot;Deny Everything&quot; From Day One&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Deploying a large set of &lt;code&gt;Deny&lt;/code&gt; policies to all subscriptions at once.&lt;br&gt;
&lt;strong&gt;Impact:&lt;/strong&gt; Broken pipelines, blocked deployments, emergency bypasses, political fallout.&lt;br&gt;
&lt;strong&gt;Detection:&lt;/strong&gt; Sudden spike in policy evaluation failures and deployment errors (HTTP 403) across subscriptions.&lt;br&gt;
&lt;strong&gt;Fix:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Roll back to &lt;code&gt;Audit&lt;/code&gt; for high-impact controls&lt;/li&gt;
&lt;li&gt;Reintroduce &lt;code&gt;Deny&lt;/code&gt; gradually with prior impact analysis and communication&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;2-no-separation-between-baseline-and-app-specific-policies&quot;&gt;2. No Separation Between Baseline and App-Specific Policies&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; App-specific requirements mixed into global initiatives.&lt;br&gt;
&lt;strong&gt;Impact:&lt;/strong&gt; Baseline becomes cluttered, unmanageable, and difficult to update.&lt;br&gt;
&lt;strong&gt;Detection:&lt;/strong&gt; Initiatives that reference specific resource names, SKUs, or app tags.&lt;br&gt;
&lt;strong&gt;Fix:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Keep platform baseline initiatives generic&lt;/li&gt;
&lt;li&gt;Manage app-specific policies at subscription or dedicated MG branches&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;3-manual-policy-drift&quot;&gt;3. Manual Policy Drift&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Changes made via the portal that are not reflected in Git.&lt;br&gt;
&lt;strong&gt;Impact:&lt;/strong&gt; Unknown behaviors, inconsistent environments, broken expectations between teams.&lt;br&gt;
&lt;strong&gt;Detection:&lt;/strong&gt; Regular export and diff between current assignments and Git repo.&lt;br&gt;
&lt;strong&gt;Fix:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enforce policy-as-code&lt;/li&gt;
&lt;li&gt;Introduce a &quot;drift detection&quot; pipeline that compares actual state to desired state and raises alerts&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;4-overuse-of-tenant-root-policies&quot;&gt;4. Overuse of Tenant Root Policies&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Assigning almost everything at tenant root MG.&lt;br&gt;
&lt;strong&gt;Impact:&lt;/strong&gt; No flexibility for different landing zones, high blast radius for mistakes.&lt;br&gt;
&lt;strong&gt;Detection:&lt;/strong&gt; Tenant root has dozens of initiatives; lower MGs have almost none.&lt;br&gt;
&lt;strong&gt;Fix:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Move most initiatives down to LandingZone / domain MGs&lt;/li&gt;
&lt;li&gt;Keep root very thin&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;5-ignoring-remediation-identity-permissions&quot;&gt;5. Ignoring Remediation Identity Permissions&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Policy assignments use &lt;code&gt;DeployIfNotExists&lt;/code&gt; but the managed identity doesn't have required permissions.&lt;br&gt;
&lt;strong&gt;Impact:&lt;/strong&gt; Remediation tasks fail silently or partially.&lt;br&gt;
&lt;strong&gt;Detection:&lt;/strong&gt; Errors in remediation jobs, non-compliant resources not fixed.&lt;br&gt;
&lt;strong&gt;Fix:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Assign appropriate RBAC roles (e.g., &lt;code&gt;Contributor&lt;/code&gt; on target scopes) to the policy assignment identities&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;6-poor-exception-governance&quot;&gt;6. Poor Exception Governance&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Exceptions created ad-hoc, without expiry or documentation.&lt;br&gt;
&lt;strong&gt;Impact:&lt;/strong&gt; Hidden risk, compliance gaps, and audit failures.&lt;br&gt;
&lt;strong&gt;Detection:&lt;/strong&gt; Large number of exemptions with no clear owner or reason.&lt;br&gt;
&lt;strong&gt;Fix:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implement a standardized exception workflow (ticket + PR + approval)&lt;/li&gt;
&lt;li&gt;Require owner, reason, scope, and expiry for every exemption&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;faq&quot;&gt;FAQ&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;1. How does this compare to AWS and GCP?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AWS equivalent: &lt;strong&gt;AWS Organizations + SCPs + Config&lt;/strong&gt;; Azure Policy is closer to Config rules + some SCP-like deny behavior&lt;/li&gt;
&lt;li&gt;GCP equivalent: &lt;strong&gt;Organization policies + Constraints&lt;/strong&gt; at org/folder/project scopes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The pattern—policy at hierarchy nodes, inheritance to accounts/subscriptions/projects—is the same.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. How do I integrate security and compliance without blocking delivery?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Use a &lt;strong&gt;progressive rollout&lt;/strong&gt;: start with &lt;code&gt;Audit&lt;/code&gt;, expose non-compliance to teams, set SLAs for fixes, then enforce &lt;code&gt;Deny&lt;/code&gt; only on well-understood controls. Add policy checks into CI (pre-merge) as well as at runtime.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. How do I scale this across dozens of teams and subscriptions?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Standardize &lt;strong&gt;landing zones&lt;/strong&gt; per domain&lt;/li&gt;
&lt;li&gt;Centralize &lt;strong&gt;policy-as-code&lt;/strong&gt; in a platform-owned repo&lt;/li&gt;
&lt;li&gt;Provide self-service &lt;strong&gt;subscription provisioning&lt;/strong&gt; that automatically places subscriptions into the right MG with the correct initiatives&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;4. What about multi-region and DR landing zones?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ensure allowed locations and networking policies support your DR regions. Create separate MGs if DR regions have different constraints, or parameterize initiatives with region-specific settings (e.g., different Log Analytics workspaces).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. How do I integrate with legacy stacks and on-prem?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Focus your policies on &lt;strong&gt;connectivity and security&lt;/strong&gt; first: VPN/ExpressRoute, private endpoints, NSGs, and logging. Ensure that hybrid connectivity does not bypass landing zone controls (e.g., enforcing private-only paths for PaaS services).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. How do I measure success of my landing zone governance?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Track KPIs such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;% of subscriptions onboarded to landing zones&lt;/li&gt;
&lt;li&gt;Policy compliance rate per MG / per team&lt;/li&gt;
&lt;li&gt;Mean time to remediate non-compliant resources&lt;/li&gt;
&lt;li&gt;Number of active exemptions and their trend&lt;/li&gt;
&lt;li&gt;Deployment failure rates caused by policy (should decrease over time as baselines stabilize)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;7. How do I deal with app teams who need special policies?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Use &lt;strong&gt;branching MGs&lt;/strong&gt; under landing zones or subscription-scoped initiatives for special cases, but keep them managed via the same policy-as-code pipeline and documented exceptions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;8. Do I need Azure Blueprints?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Blueprints are being superseded by &lt;strong&gt;ARM/Bicep/Terraform + policy-as-code&lt;/strong&gt;. Prefer those, unless you have a strong reason to keep existing Blueprint-based implementations.&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Onboarding multiple subscriptions into a real Azure Landing Zone is fundamentally a &lt;strong&gt;governance and operations&lt;/strong&gt; problem, not a button in the portal. Azure Policy gives you the enforcement engine; management groups give you the structure; policy-as-code and CI/CD give you repeatability.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key takeaways:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Design a &lt;strong&gt;management group hierarchy&lt;/strong&gt; that reflects your organization&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;policy initiatives&lt;/strong&gt; aligned to CAF domains (core, security, networking, ops)&lt;/li&gt;
&lt;li&gt;Treat Azure Policy as &lt;strong&gt;code&lt;/strong&gt;, integrated with pipelines and reviews&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Phase in enforcement&lt;/strong&gt;: audit, analyze, remediate, then deny&lt;/li&gt;
&lt;li&gt;Manage &lt;strong&gt;exceptions and remediation&lt;/strong&gt; with discipline, not one-off hacks&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Next steps:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Draft your &lt;strong&gt;MG hierarchy&lt;/strong&gt; and get cross-team buy-in&lt;/li&gt;
&lt;li&gt;Stand up a &lt;strong&gt;policy-as-code repo and CI/CD pipeline&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Start with a &lt;strong&gt;non-prod landing zone&lt;/strong&gt;, onboard a few subscriptions, and refine&lt;/li&gt;
&lt;li&gt;Gradually extend to prod and high-criticality workloads&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/&quot;&gt;Microsoft Azure Landing Zone documentation (CAF)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://learn.microsoft.com/azure/governance/policy/overview&quot;&gt;Azure Policy documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Azure/Enterprise-Scale&quot;&gt;Azure landing zones reference implementation on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>CI/CD Pipelines</category>
<guid isPermaLink="true">https://coderlegion.com/8100/azure-landing-zone-policy-at-scale</guid>
<pubDate>Tue, 02 Dec 2025 23:47:52 +0000</pubDate>
</item>
</channel>
</rss>