跨订阅Azure Policy部署:自动关联Application Insights与AMPLS
跨订阅自动关联Application Insights到AMPLS的Azure Policy问题
需求背景
- 编写DeployIfNotExists类型的Azure Policy,自动将所有Application Insights资源关联到指定的AMPLS实例
- 检查逻辑:当Application Insights的
Microsoft.Insights/components/PrivateLinkScopedResources[*].ResourceId字段未包含目标AMPLS资源ID时,触发部署 - 需创建的资源:
Microsoft.Insights/privateLinkScopes/scopedResources(属于AMPLS的子资源,而非Application Insights)
目标部署模板示例
{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "resources": [ { "type": "Microsoft.Insights/privateLinkScopes/scopedResources", "apiVersion": "2021-07-01-preview", "name": "[format('{0}/{1}', 'my-ampls', 'my-test-app-insights')]", "properties": { "linkedResourceId": "/subscriptions/<sub ID here>/resourceGroups/<resource group here>/providers/microsoft.insights/components/my-test-app-insights" } } ] }
核心问题
AMPLS与Application Insights处于不同订阅,但Azure Policy的DeploymentScope仅支持ResourceGroup和Subscription两个值,无法直接指定跨订阅/资源组的部署目标。当前策略会在Application Insights所在订阅/资源组中查找AMPLS,导致部署失败。
现有策略定义
{ "mode": "Indexed", "policyRule": { "if": { "field": "type", "equals": "microsoft.insights/components" }, "then": { "effect": "[parameters('effect')]", "details": { "type": "microsoft.insights/components", "existenceCondition": { "field": "Microsoft.Insights/components/PrivateLinkScopedResources[*].ResourceId", "equals": "[parameters('ampls')]" }, "roleDefinitionIds": [ "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c" ], "deployment": { "properties": { "mode": "Incremental", "template": { "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "resourceName": { "type": "String" }, "ampls": { "type": "String" }, "location": { "type": "String" }, "resourceId": { "type": "String" } }, "variables": {}, "resources": [ { "type": "Microsoft.Insights/privateLinkScopes/scopedResources", "apiVersion": "2021-07-01-preview", "name": "[format('{0}/{1}', '[parameters('amplsName')]', 'parameters('resourceName')')]", "location": "Global", "dependsOn": [], "properties": { "linkedResourceId": "[parameters('resourceId')]" } } ], "outputs": {} }, "parameters": { "ampls": { "value": "[parameters('ampls')]" }, "location": { "value": "[field('location')]" }, "resourceName": { "value": "[field('name')]" }, "resourceId": { "value": "[field('id')]" } } } } } } }, "parameters": { "ampls": { "type": "String", "metadata": { "displayName": "AMPLS Resource ID", "description": "Enter AMPLS Resource ID", "strongType": "Microsoft.Insights/privateLinkScopes" } }, "effect": { "type": "String", "metadata": { "displayName": "Effect", "description": "Enable or disable the execution of the policy" }, "allowedValues": [ "DeployIfNotExists", "Disabled" ], "defaultValue": "DeployIfNotExists" } } }
解决方案
核心思路
通过嵌套部署指定AMPLS所在的订阅和资源组,将scopedResources资源定向部署到目标位置;同时拆分AMPLS资源ID提取必要参数,补充跨订阅部署所需权限。
修改后的完整策略定义
{ "mode": "Indexed", "policyRule": { "if": { "field": "type", "equals": "microsoft.insights/components" }, "then": { "effect": "[parameters('effect')]", "details": { "type": "microsoft.insights/components", "existenceCondition": { "field": "Microsoft.Insights/components/PrivateLinkScopedResources[*].ResourceId", "equals": "[parameters('ampls')]" }, "roleDefinitionIds": [ "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c", "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635" ], "deployment": { "properties": { "mode": "Incremental", "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "resourceName": { "type": "String" }, "amplsSubscriptionId": { "type": "String" }, "amplsResourceGroupName": { "type": "String" }, "amplsName": { "type": "String" }, "resourceId": { "type": "String" } }, "resources": [ { "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", "name": "deployToAmplsSubscription", "subscriptionId": "[parameters('amplsSubscriptionId')]", "resourceGroup": "[parameters('amplsResourceGroupName')]", "properties": { "mode": "Incremental", "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "amplsName": { "type": "String" }, "resourceName": { "type": "String" }, "resourceId": { "type": "String" } }, "resources": [ { "type": "Microsoft.Insights/privateLinkScopes/scopedResources", "apiVersion": "2021-07-01-preview", "name": "[format('{0}/{1}', parameters('amplsName'), parameters('resourceName'))]", "location": "Global", "properties": { "linkedResourceId": "[parameters('resourceId')]" } } ] }, "parameters": { "amplsName": { "value": "[parameters('amplsName')]" }, "resourceName": { "value": "[parameters('resourceName')]" }, "resourceId": { "value": "[parameters('resourceId')]" } } } } ] }, "parameters": { "resourceName": { "value": "[field('name')]" }, "amplsSubscriptionId": { "value": "[split(parameters('ampls'), '/')[2]]" }, "amplsResourceGroupName": { "value": "[split(parameters('ampls'), '/')[4]]" }, "amplsName": { "value": "[split(parameters('ampls'), '/')[8]]" }, "resourceId": { "value": "[field('id')]" } } } } } } }, "parameters": { "ampls": { "type": "String", "metadata": { "displayName": "AMPLS资源ID", "description": "输入目标AMPLS的资源ID", "strongType": "Microsoft.Insights/privateLinkScopes" } }, "effect": { "type": "String", "metadata": { "displayName": "策略效果", "description": "启用或禁用策略执行" }, "allowedValues": [ "DeployIfNotExists", "Disabled" ], "defaultValue": "DeployIfNotExists" } } }
关键修改说明
- 嵌套跨订阅部署:通过
Microsoft.Resources/deployments资源,显式指定subscriptionId和resourceGroup属性,将部署定向到AMPLS所在的订阅和资源组 - 自动参数拆分:使用
split函数从AMPLS资源ID中提取订阅ID、资源组名称和AMPLS名称,无需额外配置多个参数 - 权限补充:新增资源组参与者角色(ID:
8e3af657-a8ff-443c-a75c-2fe8c4bcb635),确保策略身份拥有在目标资源组创建部署和scopedResources的权限
内容的提问来源于stack exchange,提问作者Iokanaan Iokan
相关产品推荐
相关产品推荐

