1. Azure Policy 与 Resource Graph 的深度整合实践
作为一名长期在Azure平台上进行云治理的工程师,我经常需要面对这样一个现实问题:当企业Azure环境中的策略定义数量超过百个时,单纯通过Azure门户界面已经难以有效管理这些策略。每次需要查看策略影响范围或导出策略信息时,都要一个个点击查看,效率极低。经过多次实践,我发现Azure Resource Graph(ARG)配合Kusto查询语言(KQL)是解决这一痛点的最佳方案。
Azure Resource Graph是Azure提供的一种高效资源查询服务,它允许用户以接近实时的速度跨所有订阅查询资源数据。与传统的Azure Resource Manager API相比,ARG的最大优势在于它能够快速执行跨订阅、跨资源组的复杂查询,而无需逐个订阅进行轮询。对于策略管理场景,ARG特别有价值,因为它将策略定义、策略分配和合规状态数据都纳入了可查询范围。
在实际工作中,我总结了三种最常用的策略查询场景,它们覆盖了策略管理的核心需求:
- 快速获取所有已分配策略的详细信息(包括分配范围、执行模式等)
- 统计不合规资源数量并按策略分组,识别影响最大的策略
- 获取策略定义的完整详情,包括效果类型和分类信息
这些查询不仅解决了基本的导出需求,更重要的是为策略治理提供了数据支持。例如,通过分析不合规资源统计,我们可以优先处理影响范围最大的策略;通过策略定义详情查询,可以系统性地梳理策略库,避免重复或冲突的策略定义。
2. 策略分配信息的全面获取方法
2.1 核心查询解析
让我们深入分析第一个核心查询——获取所有已分配策略的KQL语句:
kql复制policyresources
| where type == "microsoft.authorization/policyassignments"
| project
assignmentName = name,
scope = tostring(properties.scope),
policyDefinitionId = tostring(properties.policyDefinitionId),
displayName = tostring(properties.displayName),
enforcementMode = tostring(properties.enforcementMode),
assignedBy = tostring(properties.metadata.assignedBy),
createdBy = tostring(properties.metadata.createdBy)
| order by scope asc
这个查询从policyresources表开始,筛选出类型为策略分配(microsoft.authorization/policyassignments)的记录。project操作符选择了我们需要的关键字段,并对每个字段进行了重命名和类型转换:
scope字段显示了策略分配的范围,可能是管理组、订阅或特定资源组policyDefinitionId是策略定义的唯一标识,可用于关联策略定义详情enforcementMode显示策略是处于强制模式(Enabled)还是仅审计模式(Disabled)assignedBy和createdBy记录了策略分配的操作者和创建者,对于审计追踪非常重要
提示:在实际使用中,我建议添加
| take 1000限制结果数量,特别是在大型Azure环境中,避免返回过多数据导致查询超时。
2.2 查询结果的应用场景
这个查询的输出结果可以直接导出为CSV文件,在Excel中进一步分析。根据我的经验,这些数据在以下场景特别有用:
-
策略影响范围分析:通过scope字段可以快速了解哪些订阅或资源组被应用了特定策略,避免策略的过度分配或遗漏。
-
策略责任人确认:当发现某个策略可能造成问题时,assignedBy字段可以帮助快速定位责任人进行确认。
-
策略执行模式审查:检查enforcementMode字段可以识别哪些策略处于仅审计模式,评估是否应该转为强制模式。
-
策略定义标准化:通过policyDefinitionId可以统计哪些策略定义被频繁使用,考虑将其纳入标准策略库。
在我的一个客户案例中,我们使用这个查询发现了一个订阅中有超过50个重复的策略分配,都是因为不同团队独立分配了相同策略。通过集中管理策略分配,不仅简化了管理,还提高了策略评估的性能。
3. 不合规资源的统计与分析技术
3.1 不合规统计查询详解
第二个核心查询专注于识别不合规资源,这是日常策略管理中最常用的查询之一:
kql复制policyresources
| where type == "microsoft.policyinsights/policystates"
| where properties.complianceState == "NonCompliant"
| summarize blockedCount=count() by
policyDefinitionName = tostring(properties.policyDefinitionName),
resourceType = tostring(properties.resourceType)
| order by blockedCount desc
这个查询从策略状态表(microsoft.policyinsights/policystates)中筛选出不合规(NonCompliant)的记录,然后按策略名称和资源类型进行分组统计。summarize操作符计算每组的记录数,并以blockedCount命名结果列。
注意:在实际环境中,这个查询可能会返回大量结果。我通常会在最后添加
| where blockedCount > 10来只显示影响较大的策略,避免被大量小问题分散注意力。
3.2 不合规数据分析实践
通过这个查询获得的数据,我们可以进行深入的合规性分析:
-
识别高频问题策略:按blockedCount降序排列可以立即看到哪些策略造成了最多的不合规情况。在我的经验中,网络相关策略(如NSG规则限制)和存储账户配置策略(如必须启用加密)通常名列前茅。
-
资源类型分析:结合resourceType字段,可以识别哪些类型的资源最常出现合规问题。例如,可能会发现虚拟机相关的合规问题远多于其他资源类型。
-
趋势分析:定期运行此查询并保存结果,可以建立合规性趋势图,观察策略治理的效果。
在一个实际案例中,我们发现"允许的虚拟机SKU"策略导致了大量不合规情况。进一步分析显示,开发团队经常使用不在允许列表中的SKU进行测试。基于这一发现,我们调整了策略,为开发环境创建了单独的允许列表,既满足了生产环境的严格限制,又给了开发团队必要的灵活性。
4. 策略定义详情的深度查询方法
4.1 策略定义查询解析
第三个核心查询获取策略定义的完整详情,这对于理解策略行为和构建策略库至关重要:
kql复制policyresources
| where type == "microsoft.authorization/policydefinitions"
| extend
policyDefinitionId = id,
displayName = tostring(properties.displayName),
description = tostring(properties.description),
effectType = tostring(properties.policyRule.then.effect)
| project
properties,
name,
policyDefinitionId,
displayName,
description,
effectType,
category = tostring(properties.metadata.category)
| order by category asc
这个查询从策略定义表(microsoft.authorization/policydefinitions)获取数据,使用extend创建了新字段,然后通过project选择输出字段。关键字段包括:
effectType:策略的效果类型,如deny、audit、append等,决定了策略的执行行为category:策略分类,如"Compute"、"Security"等,来自策略的metadataproperties:完整的策略属性,包含策略规则的详细定义
4.2 策略定义管理的专业技巧
基于这个查询结果,我们可以进行深入的策略定义管理:
-
策略效果分析:通过effectType字段可以快速识别哪些策略是阻止性(deny)的,哪些仅是审计(audit)性质的。在策略优化时,我们通常会先将新策略设置为audit模式,观察影响后再决定是否转为deny。
-
策略分类整理:category字段允许我们按分类筛选策略。我经常使用
| where category == "Security"来快速查看所有安全相关策略。 -
策略规则研究:properties字段包含完整的策略规则定义。在Azure门户中查看单个策略定义时,这些信息是分散在多个标签页中的,而通过ARG查询可以一次性获取所有细节。
一个特别有用的技巧是将此查询与第一个查询结合使用,通过policyDefinitionId关联分配信息和定义详情。例如,可以识别哪些deny效果的策略被分配到了生产环境,哪些仅用于开发环境。
5. 高级查询技巧与实战经验分享
5.1 多表关联查询实践
在实际工作中,我们经常需要将不同查询的结果关联起来进行分析。例如,将策略分配与不合规统计关联:
kql复制let assignments = policyresources
| where type == "microsoft.authorization/policyassignments"
| project assignmentName=name, policyDefinitionId=tostring(properties.policyDefinitionId);
let nonCompliant = policyresources
| where type == "microsoft.policyinsights/policystates"
| where properties.complianceState == "NonCompliant"
| summarize blockedCount=count() by policyDefinitionId=tostring(properties.policyDefinitionId);
assignments
| join kind=inner nonCompliant on policyDefinitionId
| project assignmentName, policyDefinitionId, blockedCount
| order by blockedCount desc
这个查询使用KQL的let语句创建了两个临时表(assignments和nonCompliant),然后通过join操作将它们关联起来。结果显示了每个策略分配及其导致的不合规资源数量,对于策略影响分析非常有价值。
5.2 查询性能优化技巧
在大型Azure环境中,ARG查询可能会遇到性能问题。以下是我总结的几个优化技巧:
-
时间范围过滤:添加时间范围条件可以显著减少处理的数据量。例如:
kql复制| where properties.timestamp > ago(30d) -
字段选择优化:只选择必要的字段,避免使用
*通配符。project操作比extend更高效。 -
分批查询:对于超大规模环境,可以按订阅或资源组分批查询,然后合并结果。
-
使用物化视图:对于频繁执行的查询,考虑创建ARG物化视图提高性能。
5.3 常见问题排查指南
在使用ARG查询策略信息时,可能会遇到以下常见问题:
-
查询返回空结果:
- 确认有足够的权限(需要Resource Policy Reader角色)
- 检查type字段值是否正确拼写
- 确认查询的时间范围是否合适
-
查询超时:
- 添加更严格的where条件限制数据量
- 减少project的字段数量
- 尝试在非高峰时段运行查询
-
字段值显示为null:
- 某些策略可能没有某些元数据字段
- 使用
isnotempty()或isnotnull()函数过滤掉空值
-
策略状态不是最新的:
- ARG数据通常有少量延迟(约15分钟)
- 对于实时合规状态,需要使用Policy Insights API
6. 自动化与集成实践
6.1 将查询集成到自动化流程中
ARG查询不仅可以在门户中运行,还可以通过Azure CLI、PowerShell或REST API集成到自动化流程中。以下是一个使用Azure CLI运行查询并导出结果的示例:
bash复制az graph query -q "
policyresources
| where type == 'microsoft.authorization/policyassignments'
| project name, properties.displayName, properties.scope
" --output table
对于更复杂的自动化场景,可以将查询设置为Azure Automation定期运行,结果发送到Log Analytics或存储账户,甚至触发Azure Monitor警报。
6.2 使用PowerShell处理查询结果
PowerShell提供了更灵活的结果处理能力。以下脚本运行查询并将结果导出为CSV:
powershell复制$query = @"
policyresources
| where type == 'microsoft.authorization/policyassignments'
| project name, displayName=tostring(properties.displayName), scope=tostring(properties.scope)
"@
$results = az graph query -q "$query" | ConvertFrom-Json
$results.data | Export-Csv -Path "PolicyAssignments.csv" -NoTypeInformation
这个脚本可以进一步扩展,例如添加邮件通知功能,当发现关键策略变更时自动通知管理员。
6.3 与Azure DevOps集成
在CI/CD流程中,我们可以使用ARG查询验证环境合规状态。例如,在部署前检查目标订阅的策略合规情况:
yaml复制- task: AzureCLI@2
displayName: 'Check Policy Compliance'
inputs:
azureSubscription: '$(serviceConnection)'
scriptType: 'ps'
scriptLocation: 'inlineScript'
inlineScript: |
$query = @"
policyresources
| where type == 'microsoft.policyinsights/policystates'
| where properties.complianceState == 'NonCompliant'
| summarize count() by tostring(properties.policyDefinitionName)
"@
$result = az graph query -q "$query" | ConvertFrom-Json
if ($result.data.count -gt 0) {
Write-Host "##vso[task.logissue type=error]Environment has $($result.data.count) non-compliant policies"
exit 1
}
这种集成可以防止将应用部署到不合规的环境中,提前发现潜在问题。