Nishant Singh
Nishant Singh

Reputation: 3209

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

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

Answers (1)

ydaetskcoR
ydaetskcoR

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 the data_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

Related Questions