基于 .tfvars 中的列表有条件创建/更新 for_each 资源

问题描述 投票:0回答:1

我们的模块下有各种 terraform 资源,并且已经通过 for_each 循环创建了 30 多个租户。每当我们执行 terraform 时,所有租户资源都会在任何租户入职期间或在请求任何租户特定更新期间执行。

../modules/
├── function_app
│   ├── main.tf
│   ├── output.tf
│   └── variables.tf
├── monitoring_telemetry
│   ├── main.tf
│   └── variables.tf
├── storage_account
│   ├── main.tf
│   ├── output.tf
│   └── variables.tf
├── storage_containers
│   ├── main.tf
│   ├── output.tf
│   └── variables.tf
├── telemetry
│   ├── main.tf
│   ├── output.tf
│   └── variables.tf
└── tenants
    ├── main.tf
    ├── output.tf
    ├── provider.tf
    └── variables.tf

tfvars:

existing_tenants="alpha,beta"
new_tenants="gamma"
tenant = { 

  "alpha" = {
    "name" = "alpha"
  },
  "beta" = {
    "name" = "beta"
  },
  "gamma" = {
    "name" = "gamma"
  }

}

期望: 期望仅为 **gamma ** 租户创建资源。在这里,我们为每个环境管理单个状态文件,现在很难将 30 多个租户移动到单独的状态文件中。

我们尝试过: 动态忽略生命周期

ignore_changes = contains(local.existing_tenants_list, each.key) ? "[tags]" : "[all]"
即使使用
ignore_changes = local.ignore_changes_static[each.key]

错误:仅需要静态变量引用

resource "example_resource" "tenants" {
for_each = { for tenant in var.tenant : tenant => tenant if !contains(var.existing_tenants, tenant) }
.
.
.
  lifecycle {
    prevent_destroy = true
}
}

错误:lifecycle.prevent_destroy 设置,但计划要求这样做 资源要被破坏。现有租户正试图被摧毁

resource "example_resource" "tenants" {
for_each = var.tenant
count    = contains(var.new_tenants, each.key) ? 1 : 0
}

错误:不能在同一块中同时使用 count 和 for_each

resource "example_resource" "new_tenants" {
for_each = var.new_tenants
}
resource "example_resource" "existing_tenants" {
for_each = var.existing_tenants
}

面临新的/下一个执行的问题,因为 new_tenants 在下一个执行中变成现有的_tenants

我理解 terraform 的目的可能并不相同。

terraform devops multi-tenant terraform-provider-azure
1个回答
0
投票

基于 .tfvars 中的列表有条件创建/更新 for_each 资源

感谢@Marko 通过声明为

local.tenants
来使用同一屋顶上的所有租户,并将他们介绍为当地人,从而强调了正确的方向。其余步骤自行完成。

在您共享的配置中,您提到租户为

existing_tenants
new_tenants
,组合为
lifecycle.ignore_changes = contains(...)
,这通常不起作用。

您可以根据 SO 链接进行检查,其中提到的错误需要

static
变量引用,但您提到的生命周期是
dynamic
且在单个模块中使用
count
foreach
也是不可能的地形。

生命周期应该如下所述。

locals { tenants = merge(var.existing_tenants, var.new_tenants) }
.
.
resource "azurerm_storage_account" "storage" {
  name                     = "${each.key}storageaccount"
 .
 .
 . 
  lifecycle {
    ignore_changes = var.is_new_tenant ? [] : [tags, account_replication_type]
  }
}

resource "azurerm_function_app" "function" {
  name                = "${each.key}-function-app"
  .
  ,

  lifecycle {
    prevent_destroy = !var.is_new_tenant
  }
}

terraform.tfvars:

existing_tenants = {
  "alpha" = {
    name = "alpha"
  },
  "beta" = {
    name = "beta"
  }
}

new_tenants = {
  "gamma" = {
    name = "gamma"
  }
}

tags = {
  environment = "production"
}

更改模块中使用 for_each 和 count 的方式,并在本地引用租户。

参考:

for_each 元参数 - 配置语言 |地形 | HashiCorp 开发商

count 元参数 - 配置语言 |地形 | HashiCorp 开发商

生命周期元参数 - 配置语言 |地形 | HashiCorp 开发商

在 terraform 中构建动态ignore_changes - Stack OverflowMarko E

回答
© www.soinside.com 2019 - 2024. All rights reserved.