You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为资源组内新建VM自动授予Azure Storage Account访问权限

实现Azure资源组内新建VM自动获取存储账户访问权限

方案1:使用Azure Policy自动分配角色

通过自定义deployIfNotExists类型的Policy,在资源组内新建VM(且启用系统分配托管身份)时,自动为其授予目标存储账户的Blob数据访问权限。

步骤说明

  1. 准备Policy定义:创建如下自定义Policy(可根据需求调整权限角色),保存为policy.json:
{
  "properties": {
    "displayName": "自动为资源组内VM分配存储账户Blob访问权限",
    "policyType": "Custom",
    "mode": "Indexed",
    "description": "为目标资源组内新建、启用系统分配托管身份的VM,自动分配Storage Blob Data Contributor角色,使其可访问指定存储账户",
    "parameters": {
      "storageAccountId": {
        "type": "String",
        "metadata": {
          "description": "目标存储账户的资源ID"
        }
      },
      "roleDefinitionId": {
        "type": "String",
        "defaultValue": "/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe",
        "metadata": {
          "description": "Storage Blob Data Contributor角色的ID"
        }
      }
    },
    "policyRule": {
      "if": {
        "allOf": [
          {
            "field": "type",
            "equals": "Microsoft.Compute/virtualMachines"
          },
          {
            "field": "resourceGroup",
            "equals": "[resourceGroup().name]"
          },
          {
            "field": "identity.type",
            "contains": "SystemAssigned"
          }
        ]
      },
      "then": {
        "effect": "deployIfNotExists",
        "details": {
          "type": "Microsoft.Authorization/roleAssignments",
          "roleDefinitionId": "[parameters('roleDefinitionId')]",
          "existenceCondition": {
            "allOf": [
              {
                "field": "Microsoft.Authorization/roleAssignments/principalId",
                "equals": "[reference(field('id'), '2021-03-01').identity.principalId]"
              },
              {
                "field": "Microsoft.Authorization/roleAssignments/scope",
                "equals": "[parameters('storageAccountId')]"
              }
            ]
          },
          "deployment": {
            "properties": {
              "mode": "incremental",
              "template": {
                "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
                "contentVersion": "1.0.0.0",
                "parameters": {
                  "storageAccountId": {
                    "type": "string"
                  },
                  "roleDefinitionId": {
                    "type": "string"
                  },
                  "vmPrincipalId": {
                    "type": "string"
                  }
                },
                "resources": [
                  {
                    "type": "Microsoft.Authorization/roleAssignments",
                    "apiVersion": "2020-04-01-preview",
                    "name": "[guid(parameters('storageAccountId'), parameters('roleDefinitionId'), parameters('vmPrincipalId'))]",
                    "scope": "[parameters('storageAccountId')]",
                    "properties": {
                      "roleDefinitionId": "[parameters('roleDefinitionId')]",
                      "principalId": "[parameters('vmPrincipalId')]",
                      "principalType": "ServicePrincipal"
                    }
                  }
                ]
              },
              "parameters": {
                "storageAccountId": {
                  "value": "[parameters('storageAccountId')]"
                },
                "roleDefinitionId": {
                  "value": "[parameters('roleDefinitionId')]"
                },
                "vmPrincipalId": {
                  "value": "[reference(field('id'), '2021-03-01').identity.principalId]"
                }
              }
            }
          }
        }
      }
    }
  }
}
  1. 创建并分配Policy:
    • 通过Azure CLI执行az policy definition create --name "AutoAssignStorageAccessToVM" --display-name "自动为VM分配存储账户权限" --rules policy.json --mode Indexed创建Policy定义
    • 执行az policy assignment create --name "AssignAutoStorageAccessPolicy" --policy "AutoAssignStorageAccessToVM" --resource-group <你的资源组名称> --params "{\"storageAccountId\": {\"value\": \"/subscriptions/<订阅ID>/resourceGroups/<资源组名称>/providers/Microsoft.Storage/storageAccounts/<存储账户名称>\"}}",将Policy绑定到目标资源组
  2. 强制VM启用系统托管身份:可额外创建一个Policy,确保资源组内新建VM默认启用系统分配托管身份,避免因未启用MI导致权限分配失败。

方案2:使用Event Grid + Azure Function触发权限分配

通过监听资源组内的VM创建事件,触发Azure Function自动完成角色分配操作,灵活性更高。

步骤说明

  1. 创建Event Grid订阅:

    • 在Azure Portal进入目标资源组,创建Event Grid订阅
    • 事件类型选择Microsoft.Resources.ResourceWriteSuccess,添加筛选条件:resourceType等于Microsoft.Compute/virtualMachines
    • 端点类型选择Azure Function,关联新建的Function
  2. 编写Azure Function逻辑:
    以下是Python版本的Function示例,需为Function的系统托管身份授予"角色分配管理员"权限(或仅在目标存储账户上的角色分配权限):

import os
import azure.functions as func
from azure.mgmt.authorization import AuthorizationManagementClient
from azure.mgmt.compute import ComputeManagementClient
from azure.identity import DefaultAzureCredential

def main(event: func.EventGridEvent):
    event_data = event.get_json()
    vm_resource_id = event_data['resourceUri']
    vm_name = vm_resource_id.split('/')[-1]
    resource_group = os.environ['RESOURCE_GROUP_NAME']
    
    # 获取VM的系统托管身份Principal ID
    credential = DefaultAzureCredential()
    compute_client = ComputeManagementClient(credential, os.environ['AZURE_SUBSCRIPTION_ID'])
    vm = compute_client.virtual_machines.get(resource_group, vm_name)
    
    if not vm.identity or 'SystemAssigned' not in vm.identity.type:
        print(f"VM {vm_name}未启用系统托管身份,跳过权限分配")
        return
    
    principal_id = vm.identity.principal_id
    
    # 为VM的MI分配存储账户Blob访问角色
    auth_client = AuthorizationManagementClient(credential, os.environ['AZURE_SUBSCRIPTION_ID'])
    role_definition_id = "/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe"
    storage_account_id = os.environ['STORAGE_ACCOUNT_ID']
    
    role_assignment_name = os.urandom(16).hex()
    auth_client.role_assignments.create(
        scope=storage_account_id,
        role_assignment_name=role_assignment_name,
        parameters={
            'role_definition_id': role_definition_id,
            'principal_id': principal_id,
            'principal_type': 'ServicePrincipal'
        }
    )
    
    print(f"已成功为VM {vm_name}的托管身份分配存储账户访问权限")
  1. 配置Function应用设置:添加AZURE_SUBSCRIPTION_ID、RESOURCE_GROUP_NAME、STORAGE_ACCOUNT_ID三个环境变量,对应你的Azure订阅ID、目标资源组名称、存储账户资源ID。

注意事项

  • 权限最小化:优先使用Storage Blob Data Contributor角色,避免授予过高权限
  • 托管身份依赖:两种方案均要求VM启用系统分配托管身份,若需支持无MI的VM,可改为使用用户分配托管身份
  • 测试验证:新建VM后,前往存储账户的"访问控制(IAM)"页面,检查是否存在对应VM托管身份的角色分配

内容的提问来源于stack exchange,提问作者Serge Br

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 09:25:37