Terraform中能否结合count循环与map值条件跳过资源创建?
当然可以实现!
你只需要通过过滤列表+count遍历的方式,就能轻松结合循环创建和条件跳过的逻辑。核心思路是先把createStorage = false的元素从列表里剔除,再基于过滤后的列表来创建资源。
具体实现步骤:
先定义一个本地值(local),过滤出需要创建存储账户的资源项
用Terraform的for表达式可以快速完成过滤,只保留createStorage为true的元素:locals { # 过滤出需要创建存储账户的资源 storage_resources = [for resource in var.resources : resource if resource.createStorage] }修改存储账户资源的配置,基于过滤后的列表创建
把原来直接引用var.resources的地方改成引用过滤后的local.storage_resources,同时count参数也改为这个过滤后列表的长度:resource "azurerm_storage_account" "test" { name = "test${var.environment}${local.storage_resources[count.index].name}sa" location = var.location resource_group_name = "test-${var.environment}-vnet-rg" account_tier = "Standard" account_replication_type = "GRS" enable_blob_encryption = true count = length(local.storage_resources) }
效果说明:
按照你给出的var.resources示例,local.storage_resources里只会包含kafka和galera两项,最终只会创建对应的两个存储账户,elastic因为createStorage = false会被自动跳过。
兼容旧版本Terraform(0.11及更早)的写法
如果还在使用Terraform 0.11,因为不支持完整的for表达式,可以用compact函数配合条件判断来过滤:
locals { storage_resource_names = compact([ "${var.resources[0].createStorage ? var.resources[0].name : ""}", "${var.resources[1].createStorage ? var.resources[1].name : ""}", "${var.resources[2].createStorage ? var.resources[2].name : ""}" ]) } resource "azurerm_storage_account" "test" { name = "test${var.environment}${element(local.storage_resource_names, count.index)}sa" location = "${var.location}" resource_group_name = "test-${var.environment}-vnet-rg" account_tier = "Standard" account_replication_type = "GRS" enable_blob_encryption = true count = length(local.storage_resource_names) }
不过这种写法不够灵活,列表长度变化时需要手动修改,所以更推荐升级到Terraform 0.12+使用第一种写法。
内容的提问来源于stack exchange,提问作者Setanta




