用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/tools-only/X-Skills --skill name-displayname-displayname命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| applyTo | **/04-governance-constraints.md, **/04-governance-constraints.json |
| description | MANDATORY Azure Policy discovery requirements for governance constraints |
CRITICAL: Governance constraints MUST be discovered from the live Azure environment, NOT assumed from best practices. GATE: This is a mandatory gate. If Azure connectivity fails or policies cannot be retrieved, STOP and inform the user. Do NOT generate governance constraints from assumptions.
Assumed governance constraints cause deployment failures. Example:
Management group-inherited policies are invisible to basic queries. Example:
az policy assignment list: Returns only 5 subscription-scoped policiesMCAPSGov Deny Policies, Block Azure RM Resource Creation — actual deployment blockers!Before any policy queries, verify Azure CLI authentication:
az account show --query "{name:name, id:id, tenantId:tenantId}" -o json
If this fails, STOP. Azure connectivity is required. Do NOT proceed with assumed policies.
[!CAUTION]
az policy assignment listmisses management group-inherited policies. The Azure Portal "Policy | Assignments" view shows ALL effective policies including those inherited from management groups. The CLI commandaz policy assignment listonly returns subscription-scoped assignments by default, even with--disable-scope-strict-match.ALWAYS use the REST API to get the complete picture matching the portal view.
# MANDATORY: Use REST API to list ALL effective policy assignments
# This includes subscription-scoped AND management group-inherited policies
az rest --method GET \
--url "https://management.azure.com/subscriptions/\
{subscription-id}/providers/Microsoft.Authorization/\
policyAssignments?api-version=2022-06-01" \
--query "value[].{name:name, \
displayName:properties.displayName, \
scope:properties.scope, \
enforcementMode:properties.enforcementMode, \
policyDefinitionId:properties.policyDefinitionId}" \
-o json
Validation: Compare the count returned by REST API with the total shown in Azure Portal (Policy > Assignments). If they don't match, investigate missing policies.
MANDATORY: Before creating 04-governance-constraints.md, query ALL effective Azure Policy
assignments in the target subscription using the REST API (Step 0 above).
Do NOT rely on `az policy assignment list` alone — it misses management group-inherited policies.
Use the REST API approach from Step 0, then for each policy with Deny or DeployIfNotExists effects, query the actual policy definition JSON to verify impact.
For Azure Resource Graph queries (supplemental, NOT primary):
Use az graph query (Azure CLI) or Azure MCP azure-mcp/search with intent:
Query ALL Azure Policy assignments including their display names, effects (deny/audit/modify),
enforcement mode, and the actual parameter values - specifically tag names that are enforced
NEVER trust policy display names alone. Misleading names cause false positives.
Example: Policy named "Block Azure RM Resource Creation" actually blocks Classic resources only.
MANDATORY: For ALL policies with Deny or DeployIfNotExists effects, query the actual policy definition to verify impact.
Use Azure CLI az graph query command with KQL to join policy assignments with definitions:
# Query Deny policies with policyRule JSON
az graph query -q "
policyresources
| where type =~ 'microsoft.authorization/policyassignments'
| extend policyDefId = tostring(properties.policyDefinitionId)
| join kind=inner (
policyresources
| where type =~ 'microsoft.authorization/policydefinitions'
| extend policyDefId = tolower(id)
| project policyDefId,
policyRule = properties.policyRule,
description = properties.description
) on policyDefId
| where tostring(policyRule['then'].effect) =~ 'deny' or tostring(policyRule['then'].effect) =~ 'deployIfNotExists'
| project assignmentName = name,
displayName = tostring(properties.displayName),
policyDefinitionId = policyDefId,
effect = tostring(policyRule['then'].effect),
policyRule,
description
" --management-groups "<your-management-group-id>" -o json
# Or scope to subscription
az graph query -q "<KQL>" --subscriptions "<subscription-id>" -o json
Example ARG Query (KQL):
policyresources
| where type =~ 'microsoft.authorization/policyassignments'
| extend policyDefId = tostring(properties.policyDefinitionId)
| join kind=inner (
policyresources
| where type =~ 'microsoft.authorization/policydefinitions'
| extend policyDefId = tolower(id)
| project policyDefId,
policyRule = properties.policyRule,
description = properties.description
) on policyDefId
| where tostring(policyRule['then'].effect) =~ 'deny' or tostring(policyRule['then'].effect) =~ 'deployIfNotExists'
| project assignmentName = name,
displayName = tostring(properties.displayName),
policyDefinitionId = policyDefId,
effect = tostring(policyRule['then'].effect),
policyRule,
description
[!WARNING]
az policy assignment listonly returns subscription-scoped assignments. Management group-inherited policies (often the most critical — Deny policies, tag enforcement) are NOT returned. Always use the REST API from Step 0 as the primary discovery method. Use CLI only for drilling into individual policy definitions after REST API discovery.
# Step 1: Get all Deny/DeployIfNotExists policy assignments
az policy assignment list \
--query "[?enforcementMode=='Default'].{\
name:name, displayName:displayName, \
definitionId:policyDefinitionId, scope:scope}" \
-o json > policy-assignments.json
# Step 2: For each assignment, fetch the policy definition
for assignment in $(jq -r '.[].definitionId' policy-assignments.json); do
# Check if custom (management group) or built-in policy
if [[ $assignment == *"/managementGroups/"* ]]; then
# Custom policy - extract management group ID
mgId=$(echo $assignment | grep -oP '/managementGroups/\K[^/]+')
policyId=$(echo $assignment | grep -oP '/policyDefinitions/\K.*')
az policy definition show \
--name "$policyId" \
--management-group "$mgId" \
--query "{displayName:displayName, description:description, policyRule:policyRule, parameters:parameters}" \
-o json
else
# Built-in policy
policyId=$(echo $assignment | grep -oP '/policyDefinitions/\K.*')
az policy definition show \
--name "$policyId" \
--query "{displayName:displayName, description:description, policyRule:policyRule, parameters:parameters}" \
-o json
fi
done
When analyzing policyRule.if conditions, extract:
Resource Types Affected:
"field": "type",
"equals": "Microsoft.Storage/storageAccounts" // Only affects Storage Accounts
Conditional Logic:
"allOf": [ // ALL conditions must be true
{"field": "type", "equals": "Microsoft.ClassicCompute/virtualMachines"},
{"value": "[resourceGroup().tags['ringValue']]", "in": "[parameters('ringValue')]"}
]
// Policy only applies if BOTH resource is Classic VM AND RG has ringValue tag
Configuration Checks:
"field": "Microsoft.Storage/storageAccounts/allowBlobPublicAccess",
"equals": "true" // Denies if public access is enabled
Red Flags for Misleading Names:
| Policy Name Pattern | Likely Actual Behavior | Verify By Checking |
|---|---|---|
| "Block Azure RM..." | May only block Classic resources | policyRule.if contains "ClassicCompute", "ClassicStorage", etc. |
| "Require [feature]" | May only apply to specific resource types | policyRule.if.field == "type" |
| "Deny [action]" with tag reference | May only apply if specific tags exist | policyRule.if contains resourceGroup().tags |
| "Enforce [setting]" | May only modify, not deny | policyRule.then.effect == "modify" or "deployIfNotExists" |
Validation Checklist (complete before documenting policy impact):
Query specifically for tag policies:
Get all policy assignments with their display names and actual parameter values -
specifically looking for tag enforcement policies with names containing 'tag' or 'Tag'
Expected output includes:
tagName1, tagName2, etc. with actual required tag namesQuery Azure Policy assignments related to security - TLS versions, HTTPS requirements,
public access restrictions, encryption requirements, authentication methods
Query Azure Policy assignments for allowed/denied resource types, SKU restrictions,
allowed locations, and naming conventions
The 04-governance-constraints.md file MUST include:
## Discovery Source
> [!IMPORTANT]
> Governance constraints discovered via REST API including management group-inherited policies.
| Query | Result | Timestamp |
| ------------------ | ---------------------- | ---------- |
| REST API Total | {X} assignments total | {ISO-8601} |
| Subscription-scope | {X} direct assignments | {ISO-8601} |
| MG-inherited | {X} inherited policies | {ISO-8601} |
| Deny-effect | {X} blockers found | {ISO-8601} |
| Tag Policies | {X} tags required | {ISO-8601} |
| Security Policies | {X} constraints | {ISO-8601} |
**Discovery Method**: REST API (`/providers/Microsoft.Authorization/policyAssignments`)
**Subscription**: {subscription-name} (`{subscription-id}`)
**Tenant**: {tenant-id}
**Scope**: All effective (subscription + management group inherited)
**Portal Validation**: {X} assignments shown in Portal — matches REST API count: {Y/N}
GATE CHECK: If Portal Validation shows a mismatch, STOP and investigate.
All policies visible in the Portal must be captured in the governance document.
If Azure REST API or Resource Graph is unavailable:
az rest --method GET --url "https://management.azure.com/subscriptions/{id}/providers/Microsoft.Authorization/policyAssignments?api-version=2022-06-01" -o jsonaz policy assignment list --disable-scope-strict-match -o tableBefore completing governance constraints, verify:
{requirement} remain❌ Assumption-based constraints:
## Required Tags
Based on Azure best practices, the following tags are recommended...
✅ Discovery-based constraints:
## Required Tags
Discovered from Azure Policy assignment "JV-Inherit Multiple Tags" (effect: modify):
- environment, owner, costcenter, application, workload, sla, backup-policy, maint-window, tech-contact
# List ALL effective policy assignments
# (subscription + management group inherited)
SUB_ID=$(az account show --query id -o tsv)
az rest --method GET \
--url "https://management.azure.com/subscriptions/\
${SUB_ID}/providers/Microsoft.Authorization/\
policyAssignments?api-version=2022-06-01" \
--query "value[].{name:name, \
displayName:properties.displayName, \
scope:properties.scope, \
enforcementMode:properties.enforcementMode, \
policyDefinitionId:properties.policyDefinitionId}" \
-o json
# For policy SETS (initiatives), get the policy count and individual policies
az policy set-definition show \
--name "{policySetDefinitionGuid}" \
--query "{displayName:displayName, \
policyCount:policyDefinitions | length(@), \
policies:policyDefinitions[].{id:policyDefinitionReferenceId}}" \
-o json
# For individual policy definitions, get the actual policyRule
az policy definition show --name "{policyDefinitionGuid}" \
--query "{displayName:displayName, effect:policyRule.then.effect, conditions:policyRule.if}" \
-o json
# For management group-scoped custom policies
az policy definition show --name "{policyDefinitionGuid}" \
--management-group "{managementGroupId}" \
--query "{displayName:displayName, effect:policyRule.then.effect, conditions:policyRule.if}" \
-o json
[!WARNING] ARG queries only return policies stored in the subscription's resource graph. Management group-inherited policies may not appear. Use REST API above as primary.
policyresources
| where type =~ 'microsoft.authorization/policyassignments'
| extend displayName = tostring(properties.displayName)
| extend effect = tostring(properties.parameters.effect.value)
| extend enforcementMode = tostring(properties.enforcementMode)
| project id, displayName, effect, enforcementMode, scope = properties.scope
policyresources
| where type =~ 'microsoft.authorization/policyassignments'
| extend displayName = tostring(properties.displayName)
| where displayName contains 'tag' or displayName contains 'Tag'
| project displayName, parameters = properties.parameters
policyresources
| where type =~ 'microsoft.authorization/policyassignments'
| join kind=inner (
policyresources
| where type =~ 'microsoft.authorization/policydefinitions'
| where tostring(properties.metadata.category) in ('Security', 'Network', 'Storage')
| project definitionId = tolower(id), category = tostring(properties.metadata.category)
) on $left.policyDefinitionId == $right.definitionId
| project displayName = properties.displayName, category, effect = properties.parameters.effect.value
CRITICAL: Discovered policies MUST influence the implementation plan, not just be documented.
| Policy Effect | Impact | Required Action |
|---|---|---|
| Deny | Deployment blocked if non-compliant | Adapt architecture OR flag exemption requirement |
| DeployIfNotExists | Missing resources auto-deployed | Include expected resources in plan |
| Modify | Resources auto-modified at deployment | Document expected modifications |
| Audit | Non-compliance logged but allowed | Document compliance expectations |
| Disabled | Policy not enforced | Note for awareness |
Policy with Deny Effect Discovered
↓
Extract: Policy Name, Scope, Enforcement Mode
↓
Does it apply to this deployment?
↓
├─ NO → Document for awareness, proceed
└─ YES → Does it block proposed architecture?
↓
├─ NO → Document compliance, proceed
└─ YES → Can architecture be adapted to comply?
↓
├─ YES → Update implementation plan with compliant alternative
│ Document adaptation in "## Plan Adaptations" section
│ Example: Public storage → Private endpoints
└─ NO → Flag as DEPLOYMENT BLOCKER
Add to "## Deployment Blockers" section
Status: "⚠️ CANNOT PROCEED WITHOUT EXEMPTION"
Document exemption request details
Example 1: Storage Public Access Denied
## Plan Adaptations Based on Policies
### Architectural Changes
| Original Design | Blocking Policy | Effect | Adaptation Applied |
| ------------------- | ------------------------------ | ------ | ------------------------------------ |
| Public blob storage | "Deny public storage accounts" | Deny | Private endpoints + vNet integration |
Example 2: Required Diagnostic Settings
## Plan Adaptations Based on Policies
### Auto-Applied Resources
| Policy | Effect | Auto-Applied Resource |
| ---------------------------------------- | ----------------- | --------------------------------- |
| "Deploy diagnostic settings for Storage" | DeployIfNotExists | Log Analytics diagnostic settings |
Example 3: Deployment Blocker
## Deployment Blockers
🚫 **CRITICAL**: The following policies BLOCK this deployment:
### Policy: "Block Azure RM Resource Creation"
- **ID**: `918465337cff47588b23a6e9`
- **Effect**: Deny
- **Scope**: Management Group (root) - applies to all subscriptions
- **Enforcement Mode**: Default (enabled)
- **Impact**: Prevents ALL ARM template deployments (Bicep compiles to ARM)
- **Assessment Date**: 2026-02-05
**Resolution Options**:
1. **Request Policy Exemption** (Recommended):
- **Justification**: E2E validation of Agentic InfraOps workflow
- **Duration**: Temporary (7 days)
- **Risk Level**: Low (dev/test subscription)
- **Approval Process**: Submit via Azure Portal or contact governance team
2. **Alternative Architecture**:
- Use Azure CLI/PowerShell scripts instead of Bicep
- **Not Recommended**: Defeats purpose of IaC validation
**Status**: ⚠️ **DEPLOYMENT CANNOT PROCEED WITHOUT EXEMPTION APPROVAL**
**Next Steps**:
- [ ] User confirms exemption is in place
- [ ] OR User provides exemption approval timeline
- [ ] OR User selects alternative deployment method