Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ignore_changes not working for sets #22504

Closed
ryzr opened this issue Aug 18, 2019 · 14 comments
Closed

ignore_changes not working for sets #22504

ryzr opened this issue Aug 18, 2019 · 14 comments

Comments

@ryzr
Copy link

ryzr commented Aug 18, 2019

Terraform Version

0.12.6

Terraform Configuration Files

provider "aws" {}

resource "aws_s3_bucket" "foo" {
  bucket = "bar"

  logging {
    target_bucket = "baz"
    target_prefix = "log/"
  }

  lifecycle {
    ignore_changes = [logging[0].target_bucket]
  }
}

Debug Output

https://gist.github.com/ryzr/46c4dbd7f085efa76bb4aad96194b502

Expected Behavior

The target_bucket key of the first logging set should be ignored.

Actual Behavior

The following error output is produced:

Error: Cannot index a set value

  on main.tf line 12, in resource "aws_s3_bucket" "foo":
  12:     ignore_changes = [logging[0].target_bucket]

Block type "logging" is represented by a set of objects, and set elements do
not have addressable keys. To find elements matching specific criteria, use a
"for" expression with an "if" clause.

Steps to Reproduce

  1. Create .tf file with contents above
  2. terraform init
  3. terraform apply

Additional Context

I've scoured the internet for any other possible variations I could use, and failed (all produce the same error):

logging.target_bucket
logging.0.target_bucket
logging["*"].target_bucket
logging["%"].target_bucket
logging["#"].target_bucket

References

@jbardin
Copy link
Member

jbardin commented Aug 19, 2019

Hi @ryzr,

Sorry you're experiencing an issue with this configuration. This does however appear to be working as intended.

A "set" data structure is unordered, and therefore has no way of consistently addressing individual elements of the set. One possibility here is that we might be able to extend the syntax to allow addressing an attribute of all set elements, e.g. logging[*].target_bucket would ignore changes if any target_bucket were to change, though it is a very limited use case.

The only way to allow addressing of individual logging instances at the moment would if the provider could change the structure to a TypeList allowing for indexed addressing of the elements.

@hdryx
Copy link

hdryx commented Aug 23, 2019

Hi,

Having the same issue with autoscaling group when i'm trying to ignore a specific Tag :

  lifecycle {
      ignore_changes = [tag["DateTimeTag"]]
  }

Block type "tag" is represented by a set of objects, and set elements do not
have addressable keys. To find elements matching specific criteria, use a
"for" expression with an "if" clause.

I'm using Terraform v0.12.6

@scyellleader
Copy link

scyellleader commented Aug 23, 2019

I'm experiencing the same issue with ignoring snapshot_id in ebs_block_device sets. When we launch an instance from an ami created with Packer that has multiple block devices terraform wants to rebuild the instance after subsequent runs because of the presence of the snapshot id.

Error: Attribute name required
on main.tf line 226, in resource "aws_instance" "sql_server":
 226:     ignore_changes = ["ebs_block_device.*.snapshot_id"]

Splat expressions (.*) may not be used here.```
Error: Cannot index a set value

  on main.tf line 226, in resource "aws_instance" "sql_server":
 226:     ignore_changes = ["ebs_block_device.snapshot_id"]

Block type "ebs_block_device" is represented by a set of objects, and set
elements do not have addressable keys. To find elements matching specific
criteria, use a "for" expression with an "if" clause.

@hdryx
Copy link

hdryx commented Sep 4, 2019

So any solutions for this issue ?

@kjagiello
Copy link

kjagiello commented Sep 26, 2019

Would it be possible to introduce a way of manually indexing set members?

provider "aws" {}

resource "aws_s3_bucket" "foo" {
  bucket = "bar"

  logging {
    index = 0
    target_bucket = "baz"
    target_prefix = "log/"
  }

  lifecycle {
    ignore_changes = [logging[0].target_bucket]
  }
}

I'm unfamiliar with the internals of Terraform, but if this is doable, I could probably take a stab at it.

@jinglejengel
Copy link

Also running into this issue when using kubernetes resources that can be dynamically updated by operators (e.g. a namespace where the operators add their own annotations to a namespace).

@trinitronx
Copy link

Related to this issue:

Some resources such as aws_autoscaling_group name-based tag indexing does not work the same as other aws_* resources. So it's not possible to use the normal syntax: ignore_changes = [ tags["Name_of_tag"] ]

It appears that tags on this resource are a set / list of maps. For example:

tags = [
        {
            "key"                 = "foo"
            "propagate_at_launch" = "true"
            "value"               = "some value"
        },
        {
            "key"                 = "bar"
            "propagate_at_launch" = "true"
            "value"               = "another value"
        },

## [...SNIP...]

]

The workaround is to use numeric list indexing like this:

   lifecycle {
     create_before_destroy = true
     ignore_changes = [
       # Ignore changes to first tag in list: "foo"
       tags[0]
     ]
   }

This breaks anytime the ordering of tags changes... so be aware of that issue, given that this is an order-based workaround for ignoring tag changes by name (ignore_changes = [ tags["foo"] ]).

@hdryx
Copy link

hdryx commented Oct 24, 2019

The workaround is to use numeric list indexing like this:

   lifecycle {
     create_before_destroy = true
     ignore_changes = [
       # Ignore changes to first tag in list: "foo"
       tags[0]
     ]
   }

.

It's not working for me, i'm receiving this error :

Error: Cannot index a set value

  on autoscaling.tf line 61, in resource "aws_autoscaling_group" "ecs":
  61:     ignore_changes = [tag[10]]

Block type "tag" is represented by a set of objects, and set elements do not
have addressable keys. To find elements matching specific criteria, use a
"for" expression with an "if" clause.

And here is my tag variable :

variable "resource_tagging" {
  type = "map"
  default = {
    "Name"            = "to_be_filled",
    "ApplicationCode" = "app",
    "SubProject"      = "",
    "Automation"      = "None",
    "BU"              = "xx",
    "Creator"         = "",
    "Criticity"       = "3",
    "Environment"     = "env",
    "Note"            = "",
    "Owner"           = "",
    "Support"         = "",
    "DateTimeTag"     = "nodef"
  }
}

@janxious
Copy link

@jbardin is this a bug in the documention at https://www.terraform.io/docs/configuration/resources.html#ignore_changes or a bug in terraform?

The tags applied here make it seem like you think this is a bug in the documentation but I have the same behavior as other reporters regarding changes to parts of a tags structure.

@jbardin
Copy link
Member

jbardin commented Nov 18, 2019

@janxious, this issue is not in reference to a bug in terraform or the documentation. Individual set elements are not addressable, and therefore cannot be referenced in ignore_changes. There may be some more helpful errors that terraform could return for now, and it may be possible to implement the functionality in some other way in the future, so for now this is marked as an enhancement.

@kapilt
Copy link

kapilt commented Jan 3, 2020

for maps it would also be nice if the key could be supplied as a prefix or wildcard .. ie tags["xyz*"]

@cixelsyd
Copy link

Ran into this issue when attempting to ignore the the aws_ecs_service load_balancer target_group_arn, which is updated dynamically via CodeDeploy during containerized Blue/Green deployments.

@ryzr
Copy link
Author

ryzr commented Apr 16, 2020

There might be something more actionable happen if you open an issue in https://github.com/terraform-providers/terraform-provider-aws repo (or search for a relevant issue); you could potentially suggest @jbardin 's idea of using a TypeList rather than a Set. I'm not actively developing with Terraform at the moment, so I'll leave that to someone else.

@ghost
Copy link

ghost commented May 17, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators May 17, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests