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

如何在Terraform中使用for_each批量创建多个Azure Policy?

批量创建Azure Policy的两种实现方案

方法一:Terraform 使用 for_each 批量定义

将所有策略的配置整合到一个本地集合中,通过for_each遍历实现批量创建,避免重复编写资源块。

步骤1:定义策略配置集合

先把所有策略的参数整理为结构化的本地值:

locals {
  policy_definitions = {
    "require-tag-owner-on-rg" = {
      display_name        = "Require tag 'owner' on resource group"
      policy_type         = "Custom"
      mode                = "All"
      management_group_ref = var.management-group-name
      metadata = jsonencode({
        version = "1.0.0"
        category = "Custom"
      })
      policy_rule = jsonencode({
        if = {
          allOf = [
            {
              field = "type"
              equals = "Microsoft.Resources/subscriptions/resourceGroups"
            },
            {
              field = "tags['owner']"
              exists = false
            }
          ]
        },
        then = {
          effect = "deny"
        }
      })
    },
    "only-deploy-in-eastus" = {
      display_name        = "only-deploy-in-eastus"
      policy_type         = "Custom"
      mode                = "All"
      management_group_ref = data.azurerm_management_group.parent-mg.id
      metadata = jsonencode({
        version = "1.0.0"
        category = "Custom"
      })
      policy_rule = jsonencode({
        if = {
          not = {
            field = "location"
            equals = "eastus"
          }
        },
        then = {
          effect = "Deny"
        }
      })
    }
  }
}

步骤2:通过for_each批量创建资源

用遍历逻辑生成所有策略定义:

resource "azurerm_policy_definition" "custom_policies" {
  for_each            = local.policy_definitions
  name                = each.key
  policy_type         = each.value.policy_type
  mode                = each.value.mode
  display_name        = each.value.display_name
  
  # 根据管理组引用类型自动匹配参数
  management_group_name = can(each.value.management_group_ref) && length(regexall("^[a-zA-Z0-9-]+$", each.value.management_group_ref)) > 0 ? each.value.management_group_ref : null
  management_group_id   = can(each.value.management_group_ref) && length(regexall("^/providers/Microsoft.Management/managementGroups/", each.value.management_group_ref)) > 0 ? each.value.management_group_ref : null

  metadata    = each.value.metadata
  policy_rule = each.value.policy_rule
}

优势:后续新增策略只需在local.policy_definitions中添加新的键值对,无需重复编写资源块,配置更易维护。


方法二:PowerShell 批量部署

如果不用Terraform,可通过PowerShell结合JSON配置文件实现批量创建。

步骤1:编写策略配置文件

创建policies.json,存储所有策略的参数:

[
  {
    "Name": "require-tag-owner-on-rg",
    "DisplayName": "Require tag 'owner' on resource group",
    "PolicyType": "Custom",
    "Mode": "All",
    "ManagementGroupName": "<你的管理组名称>",
    "Metadata": {
      "version": "1.0.0",
      "category": "Custom"
    },
    "PolicyRule": {
      "if": {
        "allOf": [
          {
            "field": "type",
            "equals": "Microsoft.Resources/subscriptions/resourceGroups"
          },
          {
            "field": "tags['owner']",
            "exists": false
          }
        ]
      },
      "then": {
        "effect": "deny"
      }
    }
  },
  {
    "Name": "only-deploy-in-eastus",
    "DisplayName": "only-deploy-in-eastus",
    "PolicyType": "Custom",
    "Mode": "All",
    "ManagementGroupId": "<你的管理组ID>",
    "Metadata": {
      "version": "1.0.0",
      "category": "Custom"
    },
    "PolicyRule": {
      "if": {
        "not": {
          "field": "location",
          "equals": "eastus"
        }
      },
      "then": {
        "effect": "Deny"
      }
    }
  }
]

步骤2:编写PowerShell部署脚本

创建Deploy-Policies.ps1:

# 读取配置文件
$policies = Get-Content -Path "./policies.json" | ConvertFrom-Json

foreach ($policy in $policies) {
    $params = @{
        Name               = $policy.Name
        DisplayName        = $policy.DisplayName
        PolicyType         = $policy.PolicyType
        Mode               = $policy.Mode
        Metadata           = $policy.Metadata | ConvertTo-Json -Depth 10
        PolicyRule         = $policy.PolicyRule | ConvertTo-Json -Depth 10
    }

    # 匹配管理组参数
    if ($policy.ManagementGroupName) {
        $params["ManagementGroupName"] = $policy.ManagementGroupName
    } elseif ($policy.ManagementGroupId) {
        $params["ManagementGroupId"] = $policy.ManagementGroupId
    }

    # 创建策略定义
    New-AzPolicyDefinition @params
    Write-Host "已创建策略: $($policy.DisplayName)"
}

使用说明:

  1. 先登录Azure账号:Connect-AzAccount
  2. 替换配置文件中的占位符(管理组名称/ID)
  3. 执行脚本:./Deploy-Policies.ps1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 03:45:33