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

时间:2018-02-18 09:18:09

标签: amazon-web-services amazon-ec2 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个驱动器应该连接到next,依此类推,因为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个实例中的每个实例。

1 个答案:

答案 0 :(得分:3)

你似乎在这里互换使用element(list, index)list[index],实际上它们实际上是微妙的不同。

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

所以给出以下列表:

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

如果索引超出范围异常,则会出错:

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

虽然这将返回2

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

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

  

变量data_node_count = 2,因此实际上应该创建2 * 3 = 6个驱动器,因此3个驱动器应该连接到第一个实例,而另外3个驱动器应该连接到下一个等等data_node_count增加。

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