如何创建 3 个 EBS 卷并通过 Terraform 附加到每个实例

How to create 3 EBS volumes and attach to each instance via Terraform

我正在尝试通过 Terraform 创建 "N" 个实例,我希望我的每个实例都附加 3 个 EBS 卷。我正在尝试使用以下 Terraform 片段来执行此操作:

resource "aws_instance" "provision-data-nodes" {
  count                  = "${var.data_node_count}"
  ami                    = "${var.ami_id}"
  instance_type          = "${var.machine_type}"
  key_name               = "elasticsearch-prod"
  vpc_security_group_ids = ["${aws_security_group.es-sec-group.id}"]

  #availability_zone = "${element(var.azs, count.index)}"
  subnet_id = "${element(var.subnets, count.index)}"

  tags {
    Name = "${var.data_name}-${count.index+1}"
    Type = "es-data"
  }

  root_block_device {
    volume_size = 100
    volume_type = "gp2"
  }
}

resource "aws_ebs_volume" "data-ebs-volumes" {
  count             = "${var.data_node_count * 3}"
  availability_zone = "${element(var.azs, count.index)}"
  size              = "${var.volume_size_data}"
  type              = "gp2"

  tags {
    Name = "${var.data_name}-${count.index+1}"
    Type = "es-data-vols"
  }
}

resource "aws_volume_attachment" "data-ebs-volumes-attach" {
  count       = "${var.data_node_count * 3}"
  device_name = "${element(var.block_device_names, count.index)}"

  #device_name = "${var.block_device_names}"
  #volume_id   = "${element(aws_ebs_volume.data-ebs-volumes.*.id,count.index)}"
  volume_id = "${aws_ebs_volume.data-ebs-volumes.*.id[count.index]}"

  #instance_id = "${element(aws_instance.provision-data-nodes.*.id,count.index)}"
  instance_id = "${aws_instance.provision-data-nodes.*.id[count.index]}"
}

变量data_node_count = 2,这样实际上应该为我创建 2*3=6 个驱动器,所以 3 个驱动器应该附加到第一个实例,另外 3 个应该附加到下一个实例,依此类推随着 data_node_count 的增加。

Terraform 在 运行 计划时输出以下错误:

Error: Error running plan: 1 error(s) occurred:

* aws_volume_attachment.data-ebs-volumes-attach: 4 error(s) occurred:

* aws_volume_attachment.data-ebs-volumes-attach[2]: index 2 out of range for list aws_instance.provision-data-nodes.*.id (max 2) in:

${aws_instance.provision-data-nodes.*.id[count.index]}
* aws_volume_attachment.data-ebs-volumes-attach[5]: index 5 out of range for list aws_instance.provision-data-nodes.*.id (max 2) in:

${aws_instance.provision-data-nodes.*.id[count.index]}
* aws_volume_attachment.data-ebs-volumes-attach[3]: index 3 out of range for list aws_instance.provision-data-nodes.*.id (max 2) in:

${aws_instance.provision-data-nodes.*.id[count.index]}
* aws_volume_attachment.data-ebs-volumes-attach[4]: index 4 out of range for list aws_instance.provision-data-nodes.*.id (max 2) in:

${aws_instance.provision-data-nodes.*.id[count.index]}

所以我无法将 3 个卷附加到 2 个实例中的每一个。

您在这里似乎可以互换使用 element(list, index) and list[index],但实际上它们略有不同。

虽然 list[index] 是一种稍微更紧凑的语法,但它不会以列表长度为模循环返回列表。 element(list, index) 另一方面确实这样做了。

因此给出以下列表:

variable "list" {
  default = [
    1,
    2,
  ]
}

这将因索引超出范围异常而出错:

output "loop" {
  value = "${var.list[3]}"
}

虽然这会 return 2:

output "loop_element" {
  value = "${element(var.list, 3)}"
}

您还应注意,您的 EBS 卷附件循环不会按照您认为的方式运行:

The variable data_node_count = 2, so that should actually create me 2*3=6 drives and so 3 drives should be attached to the first instance and the other 3 should be attached to next and so on as the data_node_count is increased.

相反,附件会将第一个卷附加到第一个实例,第二个卷附加到第二个实例,第三个卷附加到第一个实例,第四个卷附加到第二个实例,依此类推,在实例之间交替。