Nested Maps Indexing issues

Terraform version:
Terraform v0.12.10

OS version:
Red Hat Enterprise Linux Server release 7.6 (Maipo)

Problem:
When i use nested maps to create multiple ebs_volumes and trying to delete intermediate volume. i am seeing an unexpected behaviour. It modifies the intermediate volume to last volume’s size/device and deletes the last volume instead directly deleting the intermediate volume.

Code Snippet:

resource “aws_instance” “ec2_server” {
ami = var.ami_id
instance_type = var.instance_type
vpc_security_group_ids = var.security_group
subnet_id = var.zone_subnet[“A”]
tags = {
Name = “terraform-maps-test”
}
}

resource “aws_ebs_volume” “ebs_volume” {
count = “{length(var.volume_mapping)}" availability_zone = "{aws_instance.ec2_server.availability_zone}”
size = “${lookup(var.volume_mapping[element(keys(var.volume_mapping), count.index)], “size”)}”
tags = {
Name = “terraform-maps-test”
}
}

resource “aws_volume_attachment” “ebs_attach” {
count = “{length(var.volume_mapping)}" device_name = "{lookup(var.volume_mapping[element(keys(var.volume_mapping), count.index)], “device”)}”
skip_destroy = false
volume_id = “{element(aws_ebs_volume.ebs_volume.*.id, count.index)}" instance_id = "{aws_instance.ec2_server.id}”
}

variable “volume_mapping” {
type = “map”
default = {
“mapping1” = {
“device” = “/dev/xvdc”
“size” = “5”
},
“mapping3” = {
“device” = “/dev/xvdde”
“size” = “7”
}
“mapping4” = {
“device” = “/dev/xvdd”
“size” = “6”
}

}
}


Output snippet:

After i remove “mapping3” from the above variable file and run terraform apply.


An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
~ update in-place

  • destroy
    -/+ destroy and then create replacement

Terraform will perform the following actions:

aws_ebs_volume.ebs_volume[1] will be updated in-place

~ resource “aws_ebs_volume” “ebs_volume” {
arn = “arn:aws:ec2:ap-southeast-2:207880003428:volume/vol-01a177070abff885e”
availability_zone = “ap-southeast-2a”
encrypted = false
id = “vol-01a177070abff885e”
iops = 100
~ size = 7 -> 6
tags = {
“Name” = “terraform-maps-test”
}
type = “gp2”
}

aws_ebs_volume.ebs_volume[2] will be destroyed

  • resource “aws_ebs_volume” “ebs_volume” {
    • arn = “arn:aws:ec2:ap-southeast-2:207880003428:volume/vol-070ddcdb58d9b672d” -> null
    • availability_zone = “ap-southeast-2a” -> null
    • encrypted = false -> null
    • id = “vol-070ddcdb58d9b672d” -> null
    • iops = 100 -> null
    • size = 6 -> null
    • tags = {
      • “Name” = “terraform-maps-test”
        } -> null
    • type = “gp2” -> null
      }

aws_volume_attachment.ebs_attach[1] must be replaced

-/+ resource “aws_volume_attachment” “ebs_attach” {
~ device_name = “/dev/xvde” -> “/dev/xvdd” # forces replacement
~ id = “vai-3700536342” -> (known after apply)
instance_id = “i-05587036f89572062”
skip_destroy = false
volume_id = “vol-01a177070abff885e”
}

aws_volume_attachment.ebs_attach[2] will be destroyed

  • resource “aws_volume_attachment” “ebs_attach” {
    • device_name = “/dev/xvdd” -> null
    • id = “vai-1708391633” -> null
    • instance_id = “i-05587036f89572062” -> null
    • skip_destroy = false -> null
    • volume_id = “vol-070ddcdb58d9b672d” -> null
      }

Plan: 1 to add, 1 to change, 3 to destroy.

Full code can be viewed in:

I need to delete the intermediate volume and the terraform state should adjust automatically
Any ideas on how to deal with this situation except manually changing state index by using terraform state command ?