英文:
Materialize a Set of String From flatten()
问题
这是尝试从对复杂对象调用flatten()的调用中返回一个集合(字符串)的挣扎。
我的尝试:
在 dev.tfvars 中
    source_endpoints = [
    	{
    		name = "DBSERVER01",
    		ip_address = "xxx.xx.x.xxx"
    		port = "1433",
    		client_databases = [
    			"DB01",
    			"DB02"    		   	
    		]
    	},
    	{
    		name = "DBSERVER02",
    		ip_address = "xxx.xx.x.xxx"
    		port = "1433",
    		client_databases = [
    			"DB03",
    			"DB04"
    		]
    	}
    ]
在 locals.tf 中
locals {
  database_names = flatten([
    for x, source_endpoint in var.source_endpoints : [
       for y, client_database in source_endpoint.client_databases : [      
                client_database 
      ]
    ]   
  ])
}
应用于资源:
    resource "aws_s3_object" "bronze-cdc" {
      for_each     = local.database_names
      bucket       = module.s3_bronze.bucket.id
      key          = "${each.value}/cdc-files/"
      content_type = "application/x-directory"
    }
Terraform Plan 错误:
> 错误: 无效的 for_each 参数
> 
>   在 s3-folders.tf 的第 19 行, 在资源 "aws_s3_object" "silver-dbo" 中: 
> 19:   for_each     = local.database_names
>     ├────────────────
>     │ local.database_names is tuple with 4 elements
> 
> 所提供的 "for_each" 参数值不适用: "for_each" 参数必须是映射或字符串集,并且您提供了
> 类型为元组的值。
local.database_names 的期望结果:
["DB01","DB02","DB03","DB04"]
我知道肯定有一种方法将结果投影到一个集合(字符串)中,我只是还没有碰到任何示例。欢迎任何建议。
英文:
It has been a struggle to attempt to return a set(string) from a call to flatten() against a complex object.
My Attempt:
In dev.tfvars
    source_endpoints = [
    	{
    		name = "DBSERVER01",
    		ip_address = "xxx.xx.x.xxx"
    		port = "1433",
    		client_databases = [
    			"DB01",
    			"DB02"    		   
    		]
    	},
    	{
    		name = "DBSERVER02",
    		ip_address = "xxx.xx.x.xxx"
    		port = "1433",
    		client_databases = [
    			"DB03",
    			"DB04"
    		]
    	}
    ]
In locals.tf
locals {
  database_names = flatten([
    for x, source_endpoint in var.source_endpoints : [
       for y, client_database in source_endpoint.client_databases : [      
                client_database 
      ]
    ]   
  ])
}
Applied To Resource:
    resource "aws_s3_object" "bronze-cdc" {
      for_each     = local.database_names
      bucket       = module.s3_bronze.bucket.id
      key          = "${each.value}/cdc-files/"
      content_type = "application/x-directory"
    }
Terraform Plan Error :
> Error: Invalid for_each argument
> 
>   on s3-folders.tf line 19, in resource "aws_s3_object" "silver-dbo": 
> 19:   for_each     = local.database_names
>     ├────────────────
>     │ local.database_names is tuple with 4 elements
> 
> The given "for_each" argument value is unsuitable: the "for_each"
> argument must be a map, or set of strings, and you have provided a
> value of type tuple.
Desired Result of local.database_names:
["DB01","DB02","DB03","DB04"]
I know there must be a way to project the result to a set(string), I just have not stumbled across any example. Any Advice is welcomed.
答案1
得分: 1
基于错误输出:
“for_each”参数必须是一个映射或字符串集,而您提供的是元组类型的值。
本地变量的列表类型可以通过使用内置的 toset [1] 函数转换为集合(与 for_each 一起使用):
resource "aws_s3_object" "bronze-cdc" {
  for_each     = toset(local.database_names)
  bucket       = module.s3_bronze.bucket.id
  key          = "${each.value}/cdc-files/"
  content_type = "application/x-directory"
}
[1] https://developer.hashicorp.com/terraform/language/functions/toset
英文:
Based on the error output:
"for_each" argument must be a map, or set of strings, and you have provided a value of type tuple.
The list type of the local variable can be converted to a set (which works with for_each) by using the built-in toset [1] function:
resource "aws_s3_object" "bronze-cdc" {
  for_each     = toset(local.database_names)
  bucket       = module.s3_bronze.bucket.id
  key          = "${each.value}/cdc-files/"
  content_type = "application/x-directory"
}
[1] https://developer.hashicorp.com/terraform/language/functions/toset
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论