Trying to get the root device id from instances using count

Hello. We just got word that we need to encrypt our instances. So I’m using Terraform create the snapshot, encrypted copy, create the volume, and make the volume attachment. However I can’t seem to figure out how to get my root block device id from my instances since I have count set. I have tried [0], 0, count.index, etc in various places and can’t seem to grab it. Also note I’m not sure if this code is going to work yet…

resource "aws_instance" "jobserver" {
  count                   = "${var.jobservers}"
  ami                     = "${var.ami_jobserver}"
  instance_type           = "${var.instance_type_jobserver}"
  subnet_id               = "${var.subnet}"
  key_name                = "${var.key}"
  vpc_security_group_ids  = ["${var.sg}"]
  iam_instance_profile    = "${var.profile}"
  user_data               = "${data.template_file.jobserver.rendered}"
  disable_api_termination = true
  ebs_optimized           = true

  root_block_device {
    volume_size = 50
  }

  lifecycle {
    ignore_changes = ["user_data"]
  }

  tags = {
    Name              = "${upper(var.service)}_${upper(var.environment)}_ENERGY_JOBSERVER_${count.index + 1}"
    Service           = "${title(var.service)}"
    Contact           = "${var.contact}"
    Environment       = "${var.environment}"
    Terraform         = "true"
    "c7n:OnHour"      = "on=(M-F,05);tz=mt"
    "c7n:OffHour"     = "off=[(M-U,18),(S,8)];tz=mt"
    "c7n:DoNotPatchX" = "True"
  }

  volume_tags = {
    Name        = "${upper(var.service)}_${upper(var.environment)}_ENERGY_JOBSERVER_${count.index + 1}_ROOT"
    Service     = "${title(var.service)}"
    Contact     = "${var.contact}"
    Environment = "${var.environment}"
    Terraform   = "true"
  }
}

resource "aws_ebs_snapshot" "jobserver-1-snapshot" {
  volume_id   = "${aws_instance.jobserver.root_block_device[0]}"
  description = "${upper(var.service)}_${upper(var.environment)}_ENERGY_JOBSERVER_1_ROOT"

  tags = {
    Name = "${upper(var.service)}_${upper(var.environment)}_ENERGY_JOBSERVER_1_ROOT"
  }
}

resource "aws_ebs_snapshot_copy" "jobserver-1-snapshot-copy" {
  source_snapshot_id = "${aws_ebs_snapshot.jobserver-1-snapshot.id}"
  encrypted          = true
  kms_key_id         = "${var.kms}"
  source_region      = "${var.availability_zone}"

  tags = {
    Name = "${upper(var.service)}_${upper(var.environment)}_ENERGY_JOBSERVER_1_ROOT"
  }
}

resource "aws_snapshot_create_volume_permission" "jobserver-1-snapshot-perm" {
  snapshot_id = "${aws_ebs_snapshot_copy.jobserver-1-snapshot-copy.id}"
  account_id  = "${var.account_id}"
}

resource "aws_ebs_volume" "jobserver-1-from-snapshot" {
  availability_zone = "${var.availability_zone}"
  snapshot_id       = "${aws_ebs_snapshot_copy.jobserver-1-snapshot-copy}"
  encrypted         = true
  kms_key_id        = "${var.kms}"
  iops              = 150
  type              = "gp2"

  tags = {
    Name        = "${upper(var.service)}_${upper(var.environment)}_ENERGY_JOBSERVER_${count.index + 1}_ROOT"
    Service     = "${title(var.service)}"
    Contact     = "${var.contact}"
    Environment = "${var.environment}"
    Terraform   = "true"
  }
}

resource "aws_volume_attachment" "jobserver-1-root" {
  device_name = "/dev/xvda"
  volume_id = "${aws_ebs_volume.jobserver-1-from-snapshot}"
  instance_id = "${aws_instance.jobserver[0].id}"
}

I think you need a splat in order to get them all aws_instance.jobserver[*].root_block_device.0.volume_id

That should be a list of all the volume ids, which you can then use to make the other resources using the same count = "${var.jobservers}"

… having said that, you really don’t want to do the encryption this way. I strongly recommend rebuilding the jobservers using encryption from the beginning https://www.terraform.io/docs/providers/aws/r/instance.html#encrypted