首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用for循环连接Terraform输出中的字符串?

如何用for循环连接Terraform输出中的字符串?
EN

Stack Overflow用户
提问于 2021-11-12 14:36:11
回答 1查看 1.5K关注 0票数 0

我有多个aws_glue_catalog_table资源,我希望创建一个遍历所有资源的output,以显示每个资源的S3桶位置。这样做的目的是测试是否对Terratest中的每个资源使用正确的location (因为它是变量的级联)。我不能使用aws_glue_catalog_table.*aws_glue_catalog_table.[],因为Terraform不允许在不指定资源名称的情况下引用它。

所以我用r1r2rx创建了一个r2。然后,我可以循环这些名字。我想动态地创建字符串aws_glue_catalog_table.r1.storage_descriptor[0].location,这样我就可以检查location是否正确。

代码语言:javascript
运行
复制
resource "aws_glue_catalog_table" "r1" {
  name          = "r1"
  database_name = var.db_name
  storage_descriptor {
    location      = "s3://${var.bucket_name}/${var.environment}-config/r1"
  }
...
}
resource "aws_glue_catalog_table" "rX" {
  name          = "rX"
  database_name = var.db_name
  storage_descriptor {
    location      = "s3://${var.bucket_name}/${var.environment}-config/rX"
  }
}

variable "table_names" {
  description = "The list of Athena table names"
  type        = list(string)
  default     = ["r1", "r2", "r3", "rx"]
}
output "athena_tables" {
  description = "Athena tables"
  value = [for n in var.table_names : n]
}

第一次尝试:我尝试用语法aws_glue_catalog_table.${table}创建output "athena_tables_location",但确实这样做了。

代码语言:javascript
运行
复制
output "athena_tables_location" {
  // HOW DO I ITERATE OVER ALL TABLES?
  value = [for t in var.table_names : aws_glue_catalog_table.${t}.storage_descriptor[0].location"]
}

第二次尝试:我尝试创建一个variable "table_name_locations",但是IntelliJ已经在for循环[for t in var.table_names : "aws_glue_catalog_table.${t}.storage_descriptor[0].location"]中显示了一个错误${t}

代码语言:javascript
运行
复制
variable "table_name_locations" {
  description = "The list of Athena table locations"
  type        = list(string)
  // THIS ALSO DOES NOT WORK
  default     = [for t in var.table_names : "aws_glue_catalog_table.${t}.storage_descriptor[0].location"]
}

如何列出output中的所有表位置,然后用Terratest进行测试?一旦我可以迭代这些表并收集S3位置,我就可以使用Terratest进行以下测试:

代码语言:javascript
运行
复制
athenaTablesLocation := terraform.Output(t, terraformOpts, "athena_tables_location")
assert.Contains(t, athenaTablesLocation, "s3://rX/test-config/rX",)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-12 17:30:49

这里似乎有一个不寻常的静态和动态组合:静态地定义了固定数量的aws_glue_catalog_table资源,但是您希望根据输入变量的值动态地使用它们。

Terraform不允许对资源的动态引用,因为它的执行模型需要在所有对象之间构建一个依赖关系图,因此它需要知道特定表达式涉及哪些确切的资源。但是,原则上您可以构建包含所有这些对象的单个值,然后动态地从中选择:

代码语言:javascript
运行
复制
locals {
  tables = {
    r1 = aws_glue_catalog_table.r1
    r2 = aws_glue_catalog_table.r2
    r3 = aws_glue_catalog_table.r3
    # etc
  }
}

output "table_locations" {
  value = {
    for t in var.table_names : t => local.tables[t].storage_descriptor[0].location
  }
}

通过这种结构,Terraform可以看到output "table_locations"依赖于local.tableslocal.tables依赖于所有相关资源,因此计算顺序将是正确的。

但是,您的表定义似乎是基于var.table_names的系统定义,因此可能会从动态本身中受益。您可以使用resource for_each特性来声明单个资源的多个实例:

代码语言:javascript
运行
复制
variable "table_names" {
  description = "Athena table names to create"
  type        = set(string)
  default     = ["r1", "r2", "r3", "rx"]
}

resource "aws_glue_catalog_table" "all" {
  for_each = var.table_names

  name          = each.key
  database_name = var.db_name
  storage_descriptor {
    location      = "s3://${var.bucket_name}/${var.environment}-config/${each.key}"
  }
  ...
}

output "table_locations" {
  value = {
    for k, t in aws_glue_catalog_table.all : k => t.storage_descriptor[0].location
  }
}

在本例中,aws_glue_catalog_table.all将所有表一起表示为具有多个实例的单个资源,每个实例都由表名标识。for_each资源以映射的形式出现在表达式中,因此这将声明具有如下地址的资源实例:

  • aws_glue_catalog_table.all["r1"]
  • aws_glue_catalog_table.all["r2"]
  • aws_glue_catalog_table.all["r3"]
  • ...

因为这已经是一个映射,所以这次我们不需要在本地值中构造映射的额外步骤,而可以直接访问此映射来构建输出值,这将是从表名到存储位置的映射:

代码语言:javascript
运行
复制
{
  r1 = "s3://BUCKETNAME/ENVNAME-config/r1"
  r2 = "s3://BUCKETNAME/ENVNAME-config/r2"
  r3 = "s3://BUCKETNAME/ENVNAME-config/r3"
  # ...
}

在这个例子中,我假设除了它们的名称之外,所有的表都是相同的,我希望这在实践中是不正确的,但是我只考虑了问题中包含的内容。如果表确实需要有不同的设置,那么您可以将var.table_names改为一个variable "tables",它的类型是一个对象类型的映射,其中的值描述了表之间的差异,但这是一个不同的主题,有点超出了这个问题的范围,所以我不想在这里详细介绍。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69944595

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档