Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 对Terraform中的列表或元素集进行迭代的问题_List_Count_Element_Terraform - Fatal编程技术网

List 对Terraform中的列表或元素集进行迭代的问题

List 对Terraform中的列表或元素集进行迭代的问题,list,count,element,terraform,List,Count,Element,Terraform,我尝试在AZs中创建的不同子网中启动AWS实例,在子网ID列表上使用count变量,失败时会显示不同方法的错误消息 我尝试过使用element()和[count.index],我使用的是TFV12 下面是一段代码,请忽略带有#(注释)的行 下面是两个错误片段 Error: Invalid index on k8-cluster.tf line 85, in resource "aws_instance" "workers": 85: subnet_id = "${data.aws_subn

我尝试在AZs中创建的不同子网中启动AWS实例,在子网ID列表上使用count变量,失败时会显示不同方法的错误消息

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

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

下面是两个错误片段

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.
元素()的另一个错误:


您只需按如下方式更改计数:

count = "${length(data.aws_subnet_ids.subnet_list.ids)}"
"${var.var_name}" 
当你引用变量时,我建议你这样做:

count = "${length(data.aws_subnet_ids.subnet_list.ids)}"
"${var.var_name}" 
因此,整个代码如下所示:

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}"
    ]
}

您可以在中看到示例。

这里的根本问题是
数据.aws\u subnet\u ids.subnet\u list.ids
是一个设置值,而不是列表值,因此其元素不是按特定顺序排列的,因此无法通过列表中的数字索引进行访问

要将其用作列表,需要决定如何对元素排序。在这种情况下,排序似乎并不重要,因为目标只是为每个子网创建一个实例,因此将集合传递给
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的未来版本中(在编写v0.12.0时不可用),计划为每个功能提供一个新的
,这将使这一点更加简单:

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
  ]
}

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

发生此问题是因为返回的数据是“集合”的形式,而元素希望以“列表”的形式输入

要解决此问题,需要将其转换为列表


subnet\u id=“${element(tolist(data.aws\u subnet\u ids.subnet\u list.ids),count.index)}”

谢谢,但这仍然会导致错误
错误:函数调用中出现错误。。。调用函数“element”失败:无法从字符串集合中读取元素。
EDIT:只需添加,这是在TF v12上,而不是v11上。可能是一个错误?@mzs_47也许你可以输出子网_id来检查它是否真的得到了子网id。是的,它有四个元素,如果你注意到上面的错误片段,计数会有所不同,它会提到“是一组有四个元素的字符串”,为了简洁起见,我只是为我尝试的每个方法粘贴了一个。@mzs_47我没有AWS的经验。但是从您显示的错误来看,count.index 1似乎正常,而after则不正常。如果您可以使用v11?很遗憾,我无法切换到v11 atm,:(我需要花时间引用表达式以使其正常工作。不过我稍后会尝试。谢谢!谢谢!这是一个聪明的解决方案,谢谢!