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

如何用Terraform高效管理50个Azure订阅?

批量管理Azure订阅的Terraform高效方案

场景描述

我们团队负责管理Azure核心服务(VPN Gateway、Firewall、Bastion等),同时要为开发团队创建订阅,包括用户/组管理、VNet创建及与中心网络对等互联等操作,开发团队自行管理各自订阅内的其他资源。

目前我还没找到高效的订阅管理IaC方案,现在只能为每个订阅单独运行Terraform——因为Azure Provider必须指定订阅ID,这太繁琐了。我希望能在单个文件里定义所有订阅,一次Terraform运行完成管理,示例配置如下:

subscriptions = {
    "my-subscription-1" = {
        vnet_address_space    = ["10.0.4.0/27"],
        snet_address_prefixes = ["10.0.4.0/27"],
        users = [
            "abc@example.com",
            "def@example.com",
        ],
        groups = [
            "MyAD-Group",
        ]
    },
    "my-subscription-2" = {
        vnet_address_space    = ["10.0.4.32/27"],
        snet_address_prefixes = ["10.0.4.32/27"],
        users = [
            "efg@example.com",
            "hij@example.com",
        ],
        groups = [
            "AnotherAD-Group",
        ]
    }
}

我知道可以定义多个带别名的Azure Provider,但这只适合5-6个订阅的场景,而我需要管理50个订阅。想问有没有遗漏的方案?大家都是怎么管理这类订阅的?


可行解决方案

1. 动态Provider+for_each批量管理(推荐)

Terraform 0.13及以上版本支持动态Provider配置,可以通过for_each遍历订阅配置map,自动生成对应订阅的Provider实例,实现一次运行管理所有订阅。

核心实现步骤:

  • 定义订阅配置变量,对应你给出的结构
  • 动态生成每个订阅的Provider实例,绑定对应的订阅ID
  • 调用通用模块,为每个订阅传递配置并指定对应Provider
变量定义(variables.tf)
variable "subscriptions" {
  type = map(object({
    vnet_address_space    = list(string)
    snet_address_prefixes = list(string)
    users                 = list(string)
    groups                = list(string)
  }))
}
动态Provider配置(providers.tf)
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">= 3.0.0"
    }
    azuread = {
      source  = "hashicorp/azuread"
      version = ">= 2.0.0"
    }
  }
}

# 获取租户下所有订阅(若订阅已预创建)
data "azurerm_subscriptions" "all" {}

# 为每个订阅生成带别名的Provider
provider "azurerm" {
  for_each = var.subscriptions

  alias           = each.key
  subscription_id = data.azurerm_subscriptions.all.subscriptions[each.key].subscription_id
  features {}
}
调用订阅管理模块(main.tf)
module "dev_subscriptions" {
  for_each = var.subscriptions

  source = "./modules/subscription_base"

  # 传递当前订阅的配置参数
  subscription_name     = each.key
  vnet_address_space    = each.value.vnet_address_space
  snet_address_prefixes = each.value.snet_address_prefixes
  users                 = each.value.users
  groups                = each.value.groups

  # 指定对应订阅的Provider
  providers = {
    azurerm = azurerm[each.key]
  }
}
订阅基础模块(modules/subscription_base/main.tf)
# 创建资源组
resource "azurerm_resource_group" "main" {
  name     = "${var.subscription_name}-rg"
  location = "eastus" # 可改为变量灵活配置
}

# 创建VNet
resource "azurerm_virtual_network" "main" {
  name                = "${var.subscription_name}-vnet"
  address_space       = var.vnet_address_space
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
}

# 为用户分配订阅权限
resource "azurerm_role_assignment" "user_contributor" {
  for_each = toset(var.users)

  scope                = data.azurerm_subscription.current.id
  role_definition_name = "Contributor"
  principal_id         = data.azuread_user.users[each.value].object_id
}

# 获取用户对象ID
data "azuread_user" "users" {
  for_each = toset(var.users)
  user_principal_name = each.value
}

2. Terraform Workspaces+脚本批量执行

如果订阅配置模板统一,可借助Terraform Workspaces隔离每个订阅的状态,再通过脚本(PowerShell/Bash)循环切换Workspace并执行terraform apply。这种方式适合配置差异小的批量场景,但灵活性不如动态Provider。

示例PowerShell脚本片段:

$subscriptions = Get-Content .\subscriptions.json | ConvertFrom-Json

foreach ($sub in $subscriptions.PSObject.Properties) {
  terraform workspace new $sub.Name -or-select
  terraform apply -var "subscription_id=$($sub.Value.id)" -auto-approve
}

3. 基于Azure Landing Zones框架

微软Azure Landing Zones(ALZ)提供了规模化订阅管理的原生方案,其Terraform模块支持批量订阅的生命周期管理、权限配置、网络拓扑(如中心辐射VNet对等)等,完全适配企业级多订阅场景。


关键注意事项

  • 确保Terraform版本≥0.13,支持动态Provider和for_each在Provider中的使用
  • 执行Terraform的服务主体需拥有所有目标订阅的Owner/Contributor权限
  • 必须使用远程状态后端(如Azure Blob Storage),避免本地状态文件冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 10:10:22