我有以下 tf 文件:
locals {
schemas = {
"ODS" = {
usage_roles = ["TRANSFORMER"]
}
"EXT" = {
usage_roles = []
}
"INT" = {
usage_roles = ["REPORTER"]
}
"DW" = {
usage_roles = ["LOADER"]
}
}
}
resource "snowflake_schema" "schema" {
for_each = local.schemas
name = each.key
database = ???????
usage_roles = each.value.usage_roles
}
Run Code Online (Sandbox Code Playgroud)
我想按原样维护本地变量(每个模式有不同的 use_roles 并在此处进行硬编码),同时为每个模式提供多个值作为数据库。在伪代码中它将是:
for database in ['db_1', 'db_2', 'db_3']:
resource "snowflake_schema" "schema" {
for_each = local.schemas
name = each.key
database = database
usage_roles = each.value.usage_roles
}
Run Code Online (Sandbox Code Playgroud)
这样我们在三个不同的数据库中就有相同的模式资源。我读过一些文章,这些文章让我相信可以进行此循环,但预先分配所有值,这意味着我必须将 use_roles 放入列表或其他内容中,而不是在本地中进行硬编码,我认为这是可读性较差。例如: Terraform - 如何在对象列表上使用 for_each 循环来创建资源
我所要求的甚至可能吗?如果是这样,怎么办?预先非常感谢
主要要求for_each
是您提供的映射必须为您要创建的资源的每个实例包含一个元素。就您而言,我认为这意味着您需要一张映射,其中每个数据库和模式组合都有一个元素。
查找两个集合中值的每个组合的操作正式称为笛卡尔积,Terraform 具有执行该操作的函数。setproduct
在您的情况下,要应用它的两个集合是数据库名称集和模式映射中的键集,如下所示:
locals {
databases = toset(["db_1", "db_2", "db_3"])
database_schemas = [
for pair in setproduct(local.databases, keys(local.schemas)) : {
database_name = pair[0]
schema_name = pair[1]
usage_roles = local.schemas[pair[1]].usage_roles
}
]
}
Run Code Online (Sandbox Code Playgroud)
然后,该local.database_schemas
值将包含每个组合的一个对象,如下所示:
[
{
database_name = "db_1"
schema_name = "ODS"
usage_roles = ["TRANSFORMER"]
},
{
database_name = "db_1"
schema_name = "EXT"
usage_roles = []
},
# ...
{
database_name = "db_2"
schema_name = "ODS"
usage_roles = ["TRANSFORMER"]
},
{
database_name = "db_2"
schema_name = "EXT"
usage_roles = []
},
# ...
{
database_name = "db_3"
schema_name = "ODS"
usage_roles = ["TRANSFORMER"]
},
{
database_name = "db_3"
schema_name = "EXT"
usage_roles = []
},
# ...
]
Run Code Online (Sandbox Code Playgroud)
这满足了要创建的每个实例有一个元素的要求,但我们仍然需要将其转换为每个元素具有唯一键的地图,以便为 Terraform 为每个实例提供唯一的跟踪键,因此我们可以for
在论点for_each
:
resource "snowflake_schema" "schema" {
for_each = {
for s in local.database_schemas :
"${s.database_name}:${s.schema_name}" => s
}
name = each.value.schema_name
database = each.value.database_name
usage_roles = each.value.usage_roles
}
Run Code Online (Sandbox Code Playgroud)
Terraform 将使用如下地址跟踪这些实例:
snowflake_schema.schema["db_1:ODS"]
snowflake_schema.schema["db_1:EXT"]
snowflake_schema.schema["db_2:ODS"]
snowflake_schema.schema["db_2:EXT"]
snowflake_schema.schema["db_3:ODS"]
snowflake_schema.schema["db_3:EXT"]
归档时间: |
|
查看次数: |
3425 次 |
最近记录: |