Reputation: 3209
I am trying to create "N" number of instances via Terraform and i want each of my instance to be attached with 3 EBS volumes. I am trying the following Terraform snippet to perform this:
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]}"
}
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.
Terraform outputs the following error when running the plan:
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]}
So I am not able to attach the 3 volumes to each of the 2 instances.
Upvotes: 1
Views: 3579
Reputation: 56987
You seem to be using element(list, index)
and list[index]
interchangeably here when actually they are subtly different.
While list[index]
is a slightly more compact syntax it won't loop back through the list modulo the list length. element(list, index)
on the other hand does do this.
So given the following list:
variable "list" {
default = [
1,
2,
]
}
This will error with an index out of range exception:
output "loop" {
value = "${var.list[3]}"
}
While this will return 2
:
output "loop_element" {
value = "${element(var.list, 3)}"
}
You should also note that your looping of EBS volume attachments won't operate in the way you think it will:
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 thedata_node_count
is increased.
Instead the attachments will attach the first volume to the first instance, the second volume to the second instance, the third volume to the first instance, the fourth volume to the second instance and so on, alternating across the instances.
Upvotes: 3