如何使用Terraform+Terragrunt在Azure多订阅下部署资源组
解决方案
Azure RM provider 会统一控制名下所有资源的部署订阅,azurerm_resource_group 本身不需要单独指定订阅参数,你可以根据使用场景选择以下两种实现方式:
方案1:按订阅拆分Terragrunt配置(推荐,符合Terragrunt最佳实践)
这种方式不需要修改你现有的资源组模块代码,只需要调整Terragrunt层的组织逻辑:
- 在Terragrunt部署目录下,按部门/订阅拆分独立的部署单元,每个单元对应一个已经创建好的部门订阅
- 在每个部署单元的
terragrunt.hcl中,单独配置azurerm provider的subscription_id参数,指定为对应部门的订阅ID - 每个部署单元调用同一个资源组模块,只需要传入对应部门的参数即可,Terragrunt会自动切换对应订阅上下文完成部署
示例terragrunt.hcl配置片段:
generate "provider" { path = "provider.tf" if_exists = "overwrite_terragrunt" contents = <<EOF provider "azurerm" { subscription_id = "${local.target_subscription_id}" features {} } EOF }
方案2:单部署单元下使用多provider别名
如果你的部门数量不多,希望在同一个部署上下文里完成所有资源组的部署,可以声明多个带别名的azurerm provider,每个provider对应一个订阅,然后在资源声明中指定provider参数关联对应实例:
- 首先更新你的变量配置,给每个部门补充已创建的订阅ID:
inputs = { departments = [ { name = "test", region = "West Europe" email = "something@something.com" subscription_id = "xxxx-xxxx-xxxx-xxxx" # 对应已创建的test部门订阅ID }, { name = "test2" region = "West Europe" email = "someone@something.com" subscription_id = "yyyy-yyyy-yyyy-yyyy" # 对应已创建的test2部门订阅ID } ] }
- 声明带别名的provider实例:
# 对应test部门订阅 provider "azurerm" { alias = "test" subscription_id = "xxxx-xxxx-xxxx-xxxx" features {} } # 对应test2部门订阅 provider "azurerm" { alias = "test2" subscription_id = "yyyy-yyyy-yyyy-yyyy" features {} }
- 改造模块调用逻辑,关联对应provider:
module "test_rg" { source = "./modules/resource_group" providers = { azurerm = azurerm.test } departments = [var.departments[0]] } module "test2_rg" { source = "./modules/resource_group" providers = { azurerm = azurerm.test2 } departments = [var.departments[1]] }
注意事项
- 你需要确保当前登录的Azure账号对所有要部署的订阅都有足够的操作权限
- 第一种方案更适合后续扩展,新增部门/订阅时只需要新增对应的Terragrunt配置目录即可,不需要修改核心模块代码
内容的提问来源于stack exchange,提问作者jonashoye
相关产品推荐
相关产品推荐

