Azure上Terraform:保留现有资源组,仅创建不存在的新资源组
解决方案
问题根源是Terraform通过资源地址(如azurerm_resource_group.example)绑定资源状态,修改var.name后,Terraform会认为要替换现有资源组(因为资源组名称不可修改),所以会销毁旧资源再创建新的。要实现仅创建不存在的资源组,可采用以下几种方法:
方法一:用for_each批量管理资源组(推荐)
修改Terraform代码,通过列表变量定义要创建的资源组名称,用for_each遍历生成独立的资源实例,每个实例在状态中单独跟踪:
# 定义资源组名称列表变量 variable "resource_group_names" { type = list(string) description = "要创建的Azure资源组名称列表" } # 遍历列表创建资源组 resource "azurerm_resource_group" "example" { for_each = toset(var.resource_group_names) name = each.value location = "Your_Location" # 可改为变量支持自定义位置 }
在Azure Pipelines中:
- 首次创建ABC1时,设置参数
resource_group_names = ["ABC1"],执行init->plan->apply - 后续创建ABC2时,更新参数为
resource_group_names = ["ABC1", "ABC2"],再次执行流程。此时Terraform只会检查并创建不存在的ABC2,不会改动已存在的ABC1。
方法二:用Terraform工作区隔离资源状态
每个资源组对应一个独立的Terraform工作区,工作区之间状态完全隔离,互不影响:
在Azure Pipelines的TerraformTaskV4@4任务中添加工作区操作:
- 创建并切换到新工作区(以ABC2为例):
- task: TerraformTaskV4@4 inputs: command: 'workspace' workspaceSubcommand: 'new' workspaceName: 'ABC2' backendServiceArm: '<你的Azure服务连接>' backendAzureRmResourceGroupName: '<状态存储资源组>' backendAzureRmStorageAccountName: '<状态存储账户>' backendAzureRmContainerName: '<状态存储容器>' backendAzureRmKey: 'terraform.tfstate' - 设置
var.name = 'ABC2',执行init->plan->apply
每个工作区对应一个资源组,后续创建新资源组只需创建新工作区即可,不会删除旧资源组。
方法三:手动移除旧资源的状态(不推荐)
如果必须单次传递一个名称,可先手动将旧资源从Terraform状态中移除,使其不再被跟踪:
执行命令:
terraform state rm azurerm_resource_group.example
之后设置var.name = 'ABC2'执行apply,此时Terraform会创建ABC2,不会删除ABC1。但此方法需手动操作状态,容易出错,且无法统一管理多个资源组,仅适合临时场景。
内容的提问来源于stack exchange,提问作者Buda Florin
相关产品推荐
相关产品推荐

