terraform-provider-aws: aws_instance dynamic ebs_block_device forces replacement

I ran into an issue with changes being forced on every run while attempting to deploy servers using a third-party AMI while enabling storage encryption. I used a dynamic block to mimic the block_device_mappings from the AMI, which produced a working encrypted system but Terraform detects the system as changed on every run even though the listed plan shows the same values for the removed and added blocks. Unlike the condition noted in the AWS instance docs, these instances do not mix usage with aws_ebs_volume.

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave “+1” or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform Version

Terraform v0.12.24
+ provider.aws v2.59.0
+ provider.http v1.1.1

Affected Resource(s)

  • aws_instance

Terraform Configuration Files

  dynamic "ebs_block_device" {
    for_each = data.aws_ami.cis_amazon_linux2.block_device_mappings
    iterator = device
    content {
      device_name = device.value["device_name"]
      encrypted   = true
      kms_key_id  = aws_kms_key.app_server.arn
      iops        = device.value["ebs"]["iops"]
      snapshot_id = device.value["ebs"]["snapshot_id"]
      volume_size = device.value["ebs"]["volume_size"]
      volume_type = device.value["ebs"]["volume_type"]
    }
  }

Expected Behavior

No changes were attempted

Actual Behavior

      - ebs_block_device { # forces replacement
          - delete_on_termination = true -> null
          - device_name           = "/dev/sdb" -> null
          - encrypted             = true -> null
          - iops                  = 100 -> null
          - kms_key_id            = "arn:aws:kms:us-east-1:…:key/4c134819-e3f1-48e1-a9f3-078c51e50247" -> null
          - snapshot_id           = "snap-0141e981aeb73231b" -> null
          - volume_id             = "vol-03883d920c410e30a" -> null
          - volume_size           = 2 -> null
          - volume_type           = "gp2" -> null
        }
      + ebs_block_device { # forces replacement
          + delete_on_termination = true
          + device_name           = "/dev/sdb"
          + encrypted             = true
          + iops                  = (known after apply)
          + kms_key_id            = "arn:aws:kms:us-east-1:…:key/4c134819-e3f1-48e1-a9f3-078c51e50247"
          + snapshot_id           = "snap-0141e981aeb73231b"
          + volume_id             = (known after apply)
          + volume_size           = 2
          + volume_type           = "gp2"
        }

Steps to Reproduce

  1. terraform apply

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 3
  • Comments: 16 (13 by maintainers)

Most upvoted comments

closing this for now, given the above config example can be used as a reference when creating an instance with dynamic EBS blocks and an additional code change in the provider is not required.

That workaround seems to be working well

Ah, thank you for confirming that you see it with multiple devices – I was starting to wonder what I could be missing. The CIS Linux baseline requires separate partitions for a number of common paths so we have to have a ton of them.