Summary
Git-Ape should automatically discover whether the target Azure environment is governed by a Landing Zone (e.g., Azure Landing Zone / ALZ, Sovereign Landing Zone / SLZ, Financial Services LZ, or a custom/CAF-aligned variant) and echo what it finds to the user before entering the deployment pipeline. When auto-detection is ambiguous or intentionally bypassed, users should be able to force a specific landing zone context via repo-level (and optionally org-level) configuration.
This is foundational for downstream agents/skills (Requirements Gatherer, Template Generator, Security Analyzer, Principal Architect, Role Selector) so that generated ARM templates, naming, policies, networking, and RBAC align with the LZ's guardrails instead of fighting them.
Motivation
Today @git-ape generates ARM templates and runs security/preflight/cost checks without awareness that the subscription may sit under an ALZ management group hierarchy with deployIfNotExists policies, mandated diagnostic settings, hub-spoke networking, required tags, custom RBAC, or Private DNS zones in a central subscription. This causes:
- Preflight/
what-if surprises (policy denies, modify effects).
- Security analyzer findings that are already handled by the LZ (noise).
- Template Generator proposing networking that conflicts with the hub.
- Naming drift vs. the LZ's enforced CAF abbreviations.
Detecting and echoing the LZ context early lets the pipeline adapt (and tells the user why).
Scope
Add a new skill (and supporting agent hook) that:
- Discovers landing zone signals in the current Azure context.
- Classifies the environment as one of:
alz, slz, caf-custom, none, or unknown.
- Echoes a human-readable summary + a structured record saved under
.azure/deployments/ for reuse.
- Honors a repo/org-level override that forces a specific LZ profile or disables detection entirely.
Proposed skill name: /azure-landing-zone-detector (sits alongside /prereq-check as a Pre-Deploy/context skill, runs early — before azure-naming-research).
Detection strategy (discovery heuristics)
The skill should combine multiple signals rather than relying on a single check. Confidence score = weighted sum; echo signals found.
A. Management group hierarchy
az account management-group list + show --expand --recursive
- Look for canonical ALZ MG names/IDs:
alz, Tenant Root Group children named Platform, Landing Zones, Decommissioned, Sandbox, Connectivity, Identity, Management, Corp, Online.
- Detect SLZ markers:
Confidential Corp, Confidential Online, sovereignty-related naming.
B. Policy assignments at MG/subscription scope
az policy assignment list --scope <mg-or-sub>
- Match known ALZ initiative definition IDs / display names (e.g.,
Deploy-MDFC-Config, Deploy-Diagnostics-*, Enforce-*, Audit-* initiatives published by the ALZ reference implementation).
- Presence of
Microsoft Cloud Security Benchmark + ALZ custom initiatives = strong signal.
C. Known platform resource groups / resources
- Look in connectivity/management/identity subscriptions (or current sub) for:
rg-*-connectivity-*, rg-*-management-*, rg-*-identity-*, rg-hub-*
- Central Log Analytics workspace, Automation Account, hub VNet + Azure Firewall / VWAN, Private DNS zones following ALZ list.
D. Tags and subscription metadata
- Subscription display name patterns (
sub-<env>-<lz>-<workload>).
- Required tags coming from policy
modify effects (e.g., Environment, CostCenter, Owner).
E. Deployment/IaC fingerprints
- Look for
ALZ / AVM deployment stamps (Bicep/Terraform module metadata on resource groups), ALZ Accelerator tags, managedBy fields.
- Check for Azure Verified Modules (AVM) module outputs if present in state.
F. Optional agentic signal
- Delegate a probe to the Azure MCP server or a lightweight sub-skill to query the hierarchy. Azure MCP is already a prerequisite per docs/AZURE_MCP_SETUP.md, so reuse it.
- Consider delegating to
azure-principal-architect for ambiguous cases (human-in-the-loop classification).
Output contract
Emit both:
- User echo (chat) — e.g.:
🦍 Detected Azure Landing Zone (ALZ) context
• Management group path: Tenant Root > alz > Landing Zones > Corp > sub-corp-prod-01
• 27 ALZ policy assignments in scope (3 deny, 19 deployIfNotExists, 5 audit)
• Central Log Analytics: /subscriptions/.../rg-alz-management-prod/providers/.../log-alz-prod
• Hub VNet detected in connectivity subscription
Confidence: high (0.92) — I'll align naming, networking, and RBAC to ALZ guardrails.
- Structured record saved to
.azure/deployments/landing-zone.json:
{
"profile": "alz",
"confidence": 0.92,
"detectedAt": "2026-04-21T12:34:56Z",
"source": "auto",
"managementGroupPath": ["Tenant Root", "alz", "Landing Zones", "Corp"],
"policyInitiatives": ["Deploy-MDFC-Config", "Enforce-ALZ-Decomm", "..."],
"platformSubscriptions": { "connectivity": "...", "management": "...", "identity": "..." },
"hub": { "vnetId": "...", "firewall": "azfw", "privateDnsZones": 47 },
"requiredTags": ["Environment", "CostCenter", "Owner"],
"namingConvention": "caf"
}
Override / force mechanism
Multiple layers, with clear precedence (highest wins):
- Interactive chat flag — e.g.
@git-ape deploy ... --landing-zone=alz or /landing-zone set alz.
- Environment variable —
GIT_APE_LANDING_ZONE=alz|slz|caf-custom|none|auto. Useful in headless/Actions mode.
- Repo-level config — new file
.azure/git-ape.yml (or extend plugin.json consumer config):
landingZone:
mode: force # auto | force | disabled
profile: alz # alz | slz | caf-custom | none
customProfile: # only when profile: caf-custom
managementGroupRoot: "contoso"
namingConvention: "caf"
requiredTags: [Environment, CostCenter, Owner]
hubSubscriptionId: "..."
detection:
skipSignals: [policy] # optional: skip expensive probes
minConfidence: 0.6
- Org-level default — fall back to a
.github repo in the same org that ships an git-ape.yml, or an org variable GIT_APE_LANDING_ZONE_PROFILE. Org overrides apply only when the repo config is absent or sets mode: inherit.
- Auto-detection (default) — runs the heuristics above.
Precedence: chat flag > env var > repo config > org default > auto-detect.
When mode: force, skip detection entirely and just echo "Landing zone forced to alz by .azure/git-ape.yml (repo config)". When mode: disabled, echo "Landing zone detection disabled" and continue with no LZ-aware behavior.
Open design questions / options to elaborate
- Should the skill live in
.github/skills/azure-landing-zone-detector/ or be merged into /prereq-check? (Leaning: its own skill, invoked by the orchestrator and by /prereq-check summary.)
- Which agents consume the result?
azure-requirements-gatherer → pre-fill region/tags/naming.
azure-template-generator → prefer hub-spoke peering vs. standalone VNet.
azure-security-analyzer → suppress findings already enforced by LZ policy.
azure-role-selector → pick from LZ custom roles when available.
azure-principal-architect → include LZ alignment in WAF review.
- Caching: how long is a detection result valid? Invalidate on subscription change or on explicit
/landing-zone refresh.
- Multi-subscription deployments: detect per-subscription and warn on mismatch.
- Should we ship a small catalog of known LZ profiles (ALZ, SLZ, FSI LZ, Sovereign, custom) with their fingerprints, versioned in the repo under
docs/landing-zones/?
- Sovereign/air-gapped clouds: ensure detection works against Azure Government / China endpoints.
- Telemetry/privacy: detection reads tenant/MG metadata — ensure nothing sensitive is written to logs or committed artifacts beyond IDs already in
.azure/deployments/.
Reuse from microsoft/azure-skills
Rather than reimplement detection heuristics from scratch, compose the new /azure-landing-zone-detector skill on top of existing MIT-licensed skills in microsoft/azure-skills:
azure-enterprise-infra-planner — LZ/hub-spoke/CAF reference patterns + WAF checklist + MCP tools (get_azure_bestpractices_get, microsoft_docs_search, bicepschema_get).
azure-compliance — policy assignment / initiative discovery (heuristic B).
azure-resource-lookup — platform resource discovery (heuristic C).
azure-rbac — LZ custom role detection for azure-role-selector alignment.
azure-diagnostics — confirm central Log Analytics / DINE wiring.
Integration options to decide:
- Vendor subset into
.github/skills/ (tight coupling, offline-friendly).
- Reference via
.mcp.json so Copilot agents call them as MCP tools (loose coupling, auto-updates).
- Hybrid: vendor the LZ detection reference data (
references/), MCP-call the live probes.
Acceptance criteria
References
Summary
Git-Ape should automatically discover whether the target Azure environment is governed by a Landing Zone (e.g., Azure Landing Zone / ALZ, Sovereign Landing Zone / SLZ, Financial Services LZ, or a custom/CAF-aligned variant) and echo what it finds to the user before entering the deployment pipeline. When auto-detection is ambiguous or intentionally bypassed, users should be able to force a specific landing zone context via repo-level (and optionally org-level) configuration.
This is foundational for downstream agents/skills (Requirements Gatherer, Template Generator, Security Analyzer, Principal Architect, Role Selector) so that generated ARM templates, naming, policies, networking, and RBAC align with the LZ's guardrails instead of fighting them.
Motivation
Today
@git-apegenerates ARM templates and runs security/preflight/cost checks without awareness that the subscription may sit under an ALZ management group hierarchy with deployIfNotExists policies, mandated diagnostic settings, hub-spoke networking, required tags, custom RBAC, or Private DNS zones in a central subscription. This causes:what-ifsurprises (policy denies, modify effects).Detecting and echoing the LZ context early lets the pipeline adapt (and tells the user why).
Scope
Add a new skill (and supporting agent hook) that:
alz,slz,caf-custom,none, orunknown..azure/deployments/for reuse.Proposed skill name:
/azure-landing-zone-detector(sits alongside/prereq-checkas a Pre-Deploy/context skill, runs early — beforeazure-naming-research).Detection strategy (discovery heuristics)
The skill should combine multiple signals rather than relying on a single check. Confidence score = weighted sum; echo signals found.
A. Management group hierarchy
az account management-group list+show --expand --recursivealz,Tenant Root Groupchildren namedPlatform,Landing Zones,Decommissioned,Sandbox,Connectivity,Identity,Management,Corp,Online.Confidential Corp,Confidential Online, sovereignty-related naming.B. Policy assignments at MG/subscription scope
az policy assignment list --scope <mg-or-sub>Deploy-MDFC-Config,Deploy-Diagnostics-*,Enforce-*,Audit-*initiatives published by the ALZ reference implementation).Microsoft Cloud Security Benchmark+ ALZ custom initiatives = strong signal.C. Known platform resource groups / resources
rg-*-connectivity-*,rg-*-management-*,rg-*-identity-*,rg-hub-*D. Tags and subscription metadata
sub-<env>-<lz>-<workload>).modifyeffects (e.g.,Environment,CostCenter,Owner).E. Deployment/IaC fingerprints
ALZ/AVMdeployment stamps (Bicep/Terraform module metadata on resource groups), ALZ Accelerator tags,managedByfields.F. Optional agentic signal
azure-principal-architectfor ambiguous cases (human-in-the-loop classification).Output contract
Emit both:
.azure/deployments/landing-zone.json:{ "profile": "alz", "confidence": 0.92, "detectedAt": "2026-04-21T12:34:56Z", "source": "auto", "managementGroupPath": ["Tenant Root", "alz", "Landing Zones", "Corp"], "policyInitiatives": ["Deploy-MDFC-Config", "Enforce-ALZ-Decomm", "..."], "platformSubscriptions": { "connectivity": "...", "management": "...", "identity": "..." }, "hub": { "vnetId": "...", "firewall": "azfw", "privateDnsZones": 47 }, "requiredTags": ["Environment", "CostCenter", "Owner"], "namingConvention": "caf" }Override / force mechanism
Multiple layers, with clear precedence (highest wins):
@git-ape deploy ... --landing-zone=alzor/landing-zone set alz.GIT_APE_LANDING_ZONE=alz|slz|caf-custom|none|auto. Useful in headless/Actions mode..azure/git-ape.yml(or extendplugin.jsonconsumer config):.githubrepo in the same org that ships angit-ape.yml, or an org variableGIT_APE_LANDING_ZONE_PROFILE. Org overrides apply only when the repo config is absent or setsmode: inherit.Precedence: chat flag > env var > repo config > org default > auto-detect.
When
mode: force, skip detection entirely and just echo "Landing zone forced toalzby.azure/git-ape.yml(repo config)". Whenmode: disabled, echo "Landing zone detection disabled" and continue with no LZ-aware behavior.Open design questions / options to elaborate
.github/skills/azure-landing-zone-detector/or be merged into/prereq-check? (Leaning: its own skill, invoked by the orchestrator and by/prereq-checksummary.)azure-requirements-gatherer→ pre-fill region/tags/naming.azure-template-generator→ prefer hub-spoke peering vs. standalone VNet.azure-security-analyzer→ suppress findings already enforced by LZ policy.azure-role-selector→ pick from LZ custom roles when available.azure-principal-architect→ include LZ alignment in WAF review./landing-zone refresh.docs/landing-zones/?.azure/deployments/.Reuse from
microsoft/azure-skillsRather than reimplement detection heuristics from scratch, compose the new
/azure-landing-zone-detectorskill on top of existing MIT-licensed skills inmicrosoft/azure-skills:azure-enterprise-infra-planner— LZ/hub-spoke/CAF reference patterns + WAF checklist + MCP tools (get_azure_bestpractices_get,microsoft_docs_search,bicepschema_get).azure-compliance— policy assignment / initiative discovery (heuristic B).azure-resource-lookup— platform resource discovery (heuristic C).azure-rbac— LZ custom role detection forazure-role-selectoralignment.azure-diagnostics— confirm central Log Analytics / DINE wiring.Integration options to decide:
.github/skills/(tight coupling, offline-friendly)..mcp.jsonso Copilot agents call them as MCP tools (loose coupling, auto-updates).references/), MCP-call the live probes.Acceptance criteria
/azure-landing-zone-detectorexists under.github/skills/with a prompt + shell helpers.@git-apeinvokes it in Stage 1 (Requirements) beforeazure-naming-research..azure/deployments/landing-zone.jsonand a user-facing chat echo.alz,slz,caf-custom,none,unknownwith a confidence score and listed signals..azure/git-ape.yml→ org.github/git-ape.yml→ auto.docs/LANDING_ZONES.mdwith examples of each profile and override config./prereq-checksurfaces the landing-zone status line in its summary.azoutputs (ALZ hierarchy, non-ALZ flat sub, SLZ).References