Terraform-provider-aws: aws_instance volume_tags conflict with aws_ebs_volume tags for attached volumes in a module

Created on 13 Jun 2017  路  10Comments  路  Source: hashicorp/terraform-provider-aws

_This issue was originally opened by @kojiromike as hashicorp/terraform#14462. It was migrated here as part of the provider split. The original body of the issue is below._


Terraform Version

0.9.5

Affected Resource(s)

Please list the resources as a list, for example:

  • aws_instance
  • aws_ebs_volume
  • aws_volume_attachment

Terraform Configuration Files

  1. A file in a non-root module:
resource "aws_instance" "test" {
  ami               = "ami-20328b40"
  availability_zone = "us-west-2a"
  instance_type     = "t2.micro"
  subnet_id         = "subnet-850585e2"
  key_name          = "michaels_id_rsa"

  tags {
    Name = "test-instance"
  }

  volume_tags {
    Name = "test-instance"
  }
}

variable "vol_id" {}

resource "aws_volume_attachment" "test" {
  device_name = "/dev/xvdf"
  instance_id = "${aws_instance.test.id}"
  volume_id   = "${var.vol_id}"
}
  1. A root module referencing that file:
provider aws {
  region = "us-west-2"
}

resource "aws_ebs_volume" "test" {
  availability_zone = "us-west-2a"
  size              = "1"
  type              = "gp2"

  tags {
    Name = "test-vol"
  }
}

module "test" {
  source = "../../modules/bug"
  vol_id = "${aws_ebs_volume.test.id}"
}

Expected Behavior

The tag for aws_ebs_volume.test should consistently be "Name=>vol" according to the tags specified in that resource.

Actual Behavior

The "Name" tag switches back and forth between the value supplied by the aws_ebs_volume and the aws_instance.volume_tags.

Steps to Reproduce

After each subsequent terraform plan/apply, then I do aws --region us-west-2 ec2 describe-volumes --volume-ids "$volid" | jq -c '.Volumes[].Tags' using the volume id grabbed from the first run:

Run 1: [{"Value":"test-vol","Key":"Name"}]
Run 2: [{"Value":"test-instance","Key":"Name"}]

Important Factoids

This is so similar to terraform-providers/terraform-provider-aws#729 I almost requested that be reopened, but when I tried to reproduce it in a very simple case without a non-root module, I couldn't. But when I put some components in a module, the problem was evident.

bug servicec2

Most helpful comment

Since this seems to be sitting around without a clear path forward, I'll share my workaround which I'm reasonably content with:

resource "aws_instance" "foo" {
  ...
  lifecycle {
    ignore_changes = [
      "ami",
      "key_name",

      # This prevents clobbering the tags of attached EBS volumes. See
      # [this bug][1] in the AWS provider upstream.
      #
      # [1]: https://github.com/terraform-providers/terraform-provider-aws/issues/770
      "volume_tags",
    ]
  }

  tags = "${merge(local.tags, map(
    "Name", "${local.name_prefix}-foo",
    "Role", "foo",
  ))}"

  volume_tags = "${merge(local.tags, map(
    "Name", "${local.name_prefix}-foo-rootfs",
    "Role", "foo-rootfs",
  ))}"

In addition, I avoid putting any EBS configuration other than the root block device into the instance resource itself, and tag aws_ebs_volume resources separately, however I feel inclined. This seems to break the logic that applies the volume_tags to all attached EBS volumes, and basically makes volume_tags only apply to the root device.

This isn't so much a workaround as a way to tag root volumes and otherwise ignore the feature. My conclusions:

  1. It's conceivable the entire feature should be dropped.
  2. Perhaps there should be a tags key under the root_block_device and block_device stanzas in the aws_instance resource.
  3. Perhaps volume_tags should be renamed default_volume_tags, and gain an inheritance relationship with tags specified in aws_ebs_volume resources. If option 2 above is also pursued, then it could be overridden by those, also.

Just my 2垄.

All 10 comments

Am I the only one who feels that the whole idea behind volume_tags is conceptually deficient and will forever be bug-prone? It seems to me that root_block_device and ebs_block_device should instead have tags arguments. That would provide a clean, clear and more flexible way to achieve the same goal.

Is it too late to re-design this feature?

@morissm no, you aren't. This smells like something not very well designed. What I am not sure yet is where the wrong is, if it's something regarding terraform implementation itself, or it's something inherent to AWS resources internal design...

@syquus Oh I'm not talking about the implementation but about the very design philosophy behind volume_tags.

This argument conceptually impacts the configuration of multiple resources: the root volume, the ebs_block_devices defined inline in the aws_instance and the aws_ebs_volumes attached to the instance which may or may not define their own sets of tags.

This goes against the general design of Terraform where the configuration of each resource is solely determined by its arguments. Dependencies are expressed solely through interpolations made explicit in the config with no second order effects.

volume_tags flies in the face of this philosophy, even inside aws_instance resources which is why I believe it will always be bug prone in its current design.

I don't have time to fix this myself but if it were me, I would not fix volume_tags, add a tags argument to ebs_block_device and root_block_device now, and sunset volume_tags in the next major release.

I agree to adding tags to root_block_device. However, I've noticed that any changes to root_block_device will cause the instance resource to be rebuilt. I'm not sure if this would be an issue if we're adding tags to an existing root_block_device

edit: I'm not sure why my comment unassigned @stack72. my apologies.

I still see the issue

Since this seems to be sitting around without a clear path forward, I'll share my workaround which I'm reasonably content with:

resource "aws_instance" "foo" {
  ...
  lifecycle {
    ignore_changes = [
      "ami",
      "key_name",

      # This prevents clobbering the tags of attached EBS volumes. See
      # [this bug][1] in the AWS provider upstream.
      #
      # [1]: https://github.com/terraform-providers/terraform-provider-aws/issues/770
      "volume_tags",
    ]
  }

  tags = "${merge(local.tags, map(
    "Name", "${local.name_prefix}-foo",
    "Role", "foo",
  ))}"

  volume_tags = "${merge(local.tags, map(
    "Name", "${local.name_prefix}-foo-rootfs",
    "Role", "foo-rootfs",
  ))}"

In addition, I avoid putting any EBS configuration other than the root block device into the instance resource itself, and tag aws_ebs_volume resources separately, however I feel inclined. This seems to break the logic that applies the volume_tags to all attached EBS volumes, and basically makes volume_tags only apply to the root device.

This isn't so much a workaround as a way to tag root volumes and otherwise ignore the feature. My conclusions:

  1. It's conceivable the entire feature should be dropped.
  2. Perhaps there should be a tags key under the root_block_device and block_device stanzas in the aws_instance resource.
  3. Perhaps volume_tags should be renamed default_volume_tags, and gain an inheritance relationship with tags specified in aws_ebs_volume resources. If option 2 above is also pursued, then it could be overridden by those, also.

Just my 2垄.

Related tickets: #729 & #884 (possibly all duplicates of the same issue?)

Still an issue for

Terraform v0.11.10
+ provider.aws v1.41.0
+ provider.template v1.0.0

I was hoping terraform 0.12's support for null resources would help address this, but unfortunately it does not. Even when set to null it flip-flops :(

I for one vote for the removal of the feature or at least not affecting volumes attached by other means.

This is a nightmare for trying to edit root volume options like Name, or even adding a tag for a lifecycle policy within AWS. I attempted to edit just the root device (all attached EBSs are really just Kubernetes Persistent Volumes) and I can't. This feel very broken, and I don't get why after 2+ years of reporting this that nothing has been done.

Was this page helpful?
0 / 5 - 0 ratings