0
votes

Having a few issues with counts in Terraform, wondering if anyone could advise. I have a set of three instances, with EBS volumes mounted to them in one of my modules. Please see code excerpt below:

  resource "aws_instance" "xxxx" {
  count = "${length(data.aws_availability_zones.all.names)}"

  ami                    = "${var.ami}"
  instance_type          = "t2.small"
  vpc_security_group_ids = ["${module.xxxx-sg.this_security_group_id}"]
  key_name               = "${var.key_name}"
  subnet_id              = "${element(module.vpc.xxxx_subnets, count.index)}"
  user_data              = "${module.xxxx-userdata.template_file}"

  tags {
    Name              = "${local.xxxx_name}"
  }

  root_block_device = [
    {
      volume_size           = 20
      volume_type           = "gp2"
      delete_on_termination = true
    },
  ]
}

This is paired with the following code to create and attach EBS volumes:

resource "aws_ebs_volume" "xxxx-ebs" {
  count = "${length(data.aws_availability_zones.all.names)}"

  availability_zone = "${element(data.aws_availability_zones.all.names, count.index)}"
  size              = 100
  type              = "gp2"

  tags {
    Name = "${local.xxxx_name}"
  }
}

resource "aws_volume_attachment" "xxxx-ebs-attachment" {
  count = "${length(data.aws_availability_zones.all.names)}"
  device_name = "/dev/sdg"
  volume_id   = "${aws_ebs_volume.xxxx-ebs.*.id[count.index]}"
  instance_id = "${aws_instance.xxxx.*.id[count.index]}"
}

So the syntax used above (aws_ebs_volume.xxxx-ebs.*.id[count.index]) was originally using the element() function in Terraform, but I was having issues whereby when one instance was terminated/edited...Terraform would attempt to reattach all EBS' to all instances, not just the one that had been changed. I amended and am currently using the syntax above and it has been working fine for the last few weeks, until a Terraform run this morning threw the following issues.

To give you a current view of the state, two of the xxxx instances have been terminated, so i'd expect it to recreate these two instances and reattach the existing EBS volumes. Error below

* module.prod-env0.aws_volume_attachment.xxxx-ebs-attachment: 2 error(s) occurred:

* module.prod-env0.aws_volume_attachment.xxxx-ebs-attachment[1]: index 1 out of range for list aws_instance.xxxx.*.id (max 1) in:
   ${aws_instance.xxxx.*.id[count.index]}

* module.prod-env0.aws_volume_attachment.xxxx-ebs-attachment[2]: index 2 out of range for list aws_instance.xxxx.*.id (max 1) in:
   ${aws_instance.xxxx.*.id[count.index]}

I'd be interested to see how others are managing their EBS volumes.

1
if the attachments are being made before the new instances are created you could try adding an explicit depends_on to the attachment resourceJamesP

1 Answers

0
votes

Your syntax is wrong. You should do

resource "aws_volume_attachment" "xxxx-ebs-attachment" {
  count = "${length(data.aws_availability_zones.all.names)}"
  device_name = "/dev/sdg"
  volume_id   = "${element(aws_ebs_volume.xxxx-ebs.*.id, count.index)}"
  instance_id = "${element(aws_instance.xxxx.*.id, count.index)}"
}