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

如何在Azure现有订阅中强制执行VM角色策略并排除特定资源组

在Azure所有订阅强制执行VM角色策略并排除指定资源组的实现方案

PowerShell 预处理:批量获取订阅列表

要覆盖所有现有订阅,先通过PowerShell批量获取订阅ID,导出为JSON文件供Terraform遍历使用:

  • 登录Azure账号:
Connect-AzAccount
  • 获取所有订阅并导出(可按需过滤排除特定订阅):
# 提取订阅ID和名称,可添加Where-Object过滤不需要的订阅
$subscriptions = Get-AzSubscription | Select-Object Id, Name
# 导出到当前目录的subscriptions.json文件
$subscriptions | ConvertTo-Json -Depth 10 | Out-File "./subscriptions.json"

Terraform 核心部署脚本

1. 基础配置

读取订阅列表,定义要排除的资源组,配置Azure Provider:

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">= 3.0.0"
    }
  }
}

# 读取订阅列表
locals {
  subscriptions = jsondecode(file("./subscriptions.json"))
  # 填写需要排除的资源组名称,支持多个
  excluded_resource_groups = ["rg-exclude-prod", "rg-test-01"]
}

provider "azurerm" {
  features {}
}

2. 遍历订阅分配角色(带资源组排除)

使用for_each遍历每个订阅,通过not_scopes参数指定要排除的资源组:

# 给指定主体分配VM相关角色,排除目标资源组
resource "azurerm_role_assignment" "vm_contributor" {
  for_each             = { for sub in local.subscriptions : sub.Id => sub }
  scope                = "/subscriptions/${each.value.Id}"
  role_definition_name = "Virtual Machine Contributor" # 替换为你需要的VM角色
  principal_id         = "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx" # 替换为目标主体ID(用户/组/服务主体)
  
  # 生成要排除的资源组范围列表
  not_scopes = [
    for rg in local.excluded_resource_groups :
    "/subscriptions/${each.value.Id}/resourceGroups/${rg}"
  ]
}

3. 自定义强制执行角色(可选)

如果需要更严格的规则(比如禁止删除VM),可以创建自定义角色再分配:

# 创建自定义VM强制执行角色
resource "azurerm_role_definition" "vm_enforce_role" {
  for_each       = { for sub in local.subscriptions : sub.Id => sub }
  scope          = "/subscriptions/${each.value.Id}"
  name           = "VM-Enforce-Policy"
  description    = "禁止删除VM的强制执行角色"
  permissions {
    actions     = [
      "Microsoft.Compute/virtualMachines/read",
      "Microsoft.Compute/virtualMachines/write",
      # 添加允许的操作
    ]
    not_actions = [
      "Microsoft.Compute/virtualMachines/delete",
      # 添加要禁止的操作,实现强制执行
    ]
  }
  assignable_scopes = ["/subscriptions/${each.value.Id}"]
}

# 分配自定义强制执行角色
resource "azurerm_role_assignment" "vm_enforce_assignment" {
  for_each             = { for sub in local.subscriptions : sub.Id => sub }
  scope                = "/subscriptions/${each.value.Id}"
  role_definition_id   = azurerm_role_definition.vm_enforce_role[each.key].id
  principal_id         = "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
  not_scopes           = [
    for rg in local.excluded_resource_groups :
    "/subscriptions/${each.value.Id}/resourceGroups/${rg}"
  ]
}

执行流程

  1. 运行PowerShell脚本获取订阅列表并导出
  2. 修改Terraform脚本中的principal_id、excluded_resource_groups、角色名称等参数
  3. 执行Terraform命令:
terraform init
terraform plan
terraform apply

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 02:28:21