list - 在 Terraform 中迭代列表或元素集时出现问题

标签 list count element terraform

我尝试使用子网 ID 列表上的计数变量在跨可用区创建的不同子网中启动 AWS 实例,但使用不同的方法失败并显示错误消息。

我尝试过使用 element() 和 [count.index],我使用的是 TF v12。

下面是代码片段,请忽略带#(注释)的行。

resource "aws_instance" "workers" {
#count         =   length(data.terraform_remote_state.network.outputs.public_subnet_list)
count         = length(data.aws_subnet_ids.subnet_list.ids)
instance_type = var.worker_instance_type
ami           = var.k8_ami
key_name      = aws_key_pair.ssh_key.key_name
#subnet_id     = "${data.terraform_remote_state.network.outputs.public_subnet_list[count.index]}"
subnet_id = "${element(data.aws_subnet_ids.subnet_list.ids, count.index)}"
vpc_security_group_ids = [
aws_security_group.kubernetes.id
]
}

下面是两个错误片段。

Error: Invalid index

on k8-cluster.tf line 85, in resource "aws_instance" "workers":
85:   subnet_id = "${data.aws_subnet_ids.subnet_list.ids[count.index]}"
|----------------
| count.index is 2
| data.aws_subnet_ids.subnet_list.ids is set of string with 4 elements

This value does not have any indices.

element() 的另一个错误:

Error: Error in function call

on k8-cluster.tf line 85, in resource "aws_instance" "workers":
85:   subnet_id = "${element(data.aws_subnet_ids.subnet_list.ids, count.index)}"
|----------------
| count.index is 3
| data.aws_subnet_ids.subnet_list.ids is set of string with 4 elements

Call to function "element" failed: cannot read elements from set of string.

最佳答案

这里的根本问题是 data.aws_subnet_ids.subnet_list.ids 是一个 set 值,而不是 list 值,所以它的元素没有特定的顺序,因此无法通过列表中的数字索引进行访问。

要将其用作列表,需要决定如何对元素进行排序。在这种情况下,排序似乎并不重要,因为目标只是为每个子网创建一个实例,因此将集合传递给 sort 函数应该足以对它们进行词法排序:

resource "aws_instance" "workers" {
  count         = length(data.terraform_remote_state.network.outputs.public_subnet_list)
  instance_type = var.worker_instance_type
  ami           = var.k8_ami
  key_name      = aws_key_pair.ssh_key.key_name
  subnet_id     = sort(data.terraform_remote_state.network.outputs.public_subnet_list)[count.index]
  vpc_security_group_ids = [
    aws_security_group.kubernetes.id
  ]
}
<小时/>

在 Terraform 的 future 版本中(在撰写本文时 v0.12.0 中尚未提供),计划推出一个新的 for_each 功能,这将使此操作更加简单:

resource "aws_instance" "workers" {
  # Planned for a future Terraform release; not in v0.12.0
  for_each = data.terraform_remote_state.network.outputs.public_subnet_list

  instance_type = var.worker_instance_type
  ami           = var.k8_ami
  key_name      = aws_key_pair.ssh_key.key_name
  subnet_id     = each.value
  vpc_security_group_ids = [
    aws_security_group.kubernetes.id
  ]
}

一旦实现(除了简洁之外)使用 for_each 的一个优点是,它还会告诉 Terraform 通过子网 id 字符串而不是通过在子网中的位置来识别该资源的各个实例。列表。这意味着将来添加新的子网不会导致后来的实例“偏移”并不必要地重新创建,就像我上面的原始示例一样。

关于list - 在 Terraform 中迭代列表或元素集时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56372089/

相关文章:

java - 移动数组中的元素?

Python,从原始形式对我的列表进行排序

MYSQL > 统计同时添加的记录条数

r:循环遍历列表并将结果附加到数据框

java - 统计 ArrayList 中一定范围内的数字

xml - 为什么 XQuery 表达式返回错误的元素计数?

element - 在 html 中嵌入 EXTJS 的正确方法

jquery拖动元素

C# SkipWhile(Item => Item == null) 仍然返回空项目

java - 从 List<String> Java 解析