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 for a single AWS Resource Tag #6632

Closed
emoshaya opened this issue May 12, 2016 · 44 comments · Fixed by #21788
Closed

Ignore changes for a single AWS Resource Tag #6632

emoshaya opened this issue May 12, 2016 · 44 comments · Fixed by #21788

Comments

@emoshaya
Copy link

Is there a way to limit the @ignore_changes to just a single tag e.g. VERSION tag. As apposed to every single tag for a particular resource? I have a VERSION tag which is updated regularly by Jenkins and I would like a way to just ignore_changes for that tag.

Thanks

@dsolsona
Copy link

I'm also interested in this. ignore_changes = ["tags"] seems very generic and it appears that it also stops terraform adding new tags to resources.

@jen20
Copy link
Contributor

jen20 commented Jun 17, 2016

Hi @emoshaya-cognito! There currently isn't a way to ignore changes to individual map fields. I don't believe there is a way to implement this given the current semantics of ignore_changes, though @phinze is more familiar with that area of the code base than I am.

@manojlds
Copy link
Contributor

Would also like to have this. Use case - EBS volume tags are updated with the instance id of the instance in which they are mounted. Would like to control other tags from terraform, but ignore changes to the instance id tag.

@jimhoagland
Copy link

I would also like this. We run JanitorMonkey regularly, which adds CreatorId, CreatorName, PrincipalId. I really don't want those removed when doing an apply. Perhaps those can be listed in the config with some kind of marking that those tags should be ignored if present.

@pgporada
Copy link

This would be useful for us as well. Amongst other things we're doing is setting the current version of our application in the AWS console so people in there can check it without too much effort.

@ashald
Copy link
Contributor

ashald commented Jan 31, 2017

We would be glad to see this as well - we need to set a date-derived tags upon resource creation but the change in such tag shouldn't be a reason for resource "invalidation".

@nwalke
Copy link
Contributor

nwalke commented Mar 15, 2017

We have an application that creates/updates/deletes tags on the resources it's running on, but have a set of tags that never get removed or updated. Would be super nice to ensure that group of tags never gets touched, but disregard the rest.

@joseph-holland
Copy link

Would also like this functionality.

@MikeMcMahon
Copy link

We do this already and it worked flawlessly in older versions of terraform (0.8.8 and prior)

ignore_changes {
  "tags.%",
  "tags.hostname",  # dynamically generated on boot time
   ...
}

However it seems that now it still seemingly ignores the individual tags (as it always has) but now for some reason in TF 0.9.11 it tries to re-apply the tags over and over and over and over and only seems to actually ignore the tag in the apply, not in the plan.

@apparentlymart
Copy link
Contributor

Hi all! Thanks for the great discussion here.

This is hard to implement today in Terraform core due to how Terraform currently thinks of map attributes. Indeed, @MikeMcMahon's workaround above is depending on an implementation detail of how maps are represented internally that is very likely to break in future if it hasn't broken already, since Terraform isn't really "understanding" what's going on there and instead it is (or was) just working by accident.

We are starting to plan some changes to the configuration language that would shore up how Terraform thinks about maps internally. While adjustments to the behavior of ignore_changes are unlikely to be included in the first pass (that goes deeper into Terraform's guts than we're currently looking at) we will hopefully be able to get some better building blocks in place to support this in a smarter way in future. Unfortunately this is one of those things where there's a fair amount of supporting work that needs to be done first.

In principle we could do something special in the AWS provider to deal with this use case specifically, rather than changing Terraform core, but given how many different resources deal with tags it'd take some significant changes across many resources to get this implemented in a robust way even just within the provider itself.

So with all of that said, this is something we want to support, but it's unfortunately still some ways out. 😖

@mr-olson
Copy link

From the comments so far, it seems there are 2 use cases (both of which would be useful for my needs)

  1. ignore_changes per tag - original report

  2. Ignore unknown tags automatically - create & manage only the set of tags specified in the template - if tags Foo and Bar are set in TF, but Fiz and Baz are later set via some other process, TF should only consider Foo and Bar's presence & values when calculating changes (@nwalke's comment & others).

@flypenguin
Copy link

flypenguin commented May 28, 2018

yup, also hit that use case right now. any updates on this? it's been a while since the last comment.

mine is kops deployments in AWS - it adds tags to terraform-created resources (namely subnets), and TF wants to remove them later.

@jimbeck
Copy link

jimbeck commented May 30, 2018

@flypenguin we just hit the same issue with using kops to create a k8s cluster. Did you do anything to get around this? Minus handjamming those tags into the subnet creation >.<

@flypenguin
Copy link

flypenguin commented Jun 3, 2018

nah, I didn't. Actually it seems that the removal of the tags does not harm the cluster or kops, at least not in my initial tests. The only thing you get is a tagging battle between kops and terraform, which is something I can live with (if there are really no side effects) until HCL and terraform are getting straightened out a bit. I guess everybody is using HCL and terraform in ways nobody thought about in the beginning, and it is hitting its limits :)

@sidick
Copy link

sidick commented Jun 11, 2018

I'm actually seeing the same issue when creating an EKS cluster which adds tags to the VPC it's associated with

@flypenguin
Copy link

flypenguin commented Jun 25, 2018

Well, it does affect kops clusters. If you deploy an nginx-ingress, it will try to use the subnet tags to find suitable subnets for the ELB. No tags, no ELB.

The error message is also something really have to figure out if you haven't seen it before: Error creating load balancer (will retry): failed to ensure load balancer for service kube-system/nginx-ingress-controller: could not find any suitable subnets for creating the ELB

Now this feature becomes something I really would like to have :)

@jeremygaither
Copy link

Any chance this might be coming with Terraform 0.12? This would be very helpful with multiple scenarios, especially with kops-generated Terraform and general version tags.

@apparentlymart apparentlymart added config and removed core labels Jul 3, 2018
@apparentlymart
Copy link
Contributor

apparentlymart commented Jul 3, 2018

We've not intentionally made any changes in this area for v0.12, but it's possible that some of the changes we've made for other reasons might come together to offer at least a partial solution here. Once the v0.12 branch lands in master (still quite a bit of work to do there first, unfortunately) we'll give this a try and see what the situation is.

The foundational piece that has shifted for the v0.12 release is that Terraform will now parse ignore_changes as an expression relative to the resource itself, so syntactically it's in theory possible to state the following:

  ignore_changes = [
    tags["Version"],
  ]

...however, there's of course more to ignore_changes than just syntax, and the v0.12 scope is already pretty large, so if this isn't fully solved by the other changes then we'll probably need to hold on this one for a subsequent release, but at least the building blocks will be in place to make this more reasonable to implement.

I've relabeled this issue so it'll be on our radar to review it once the development branch is merged and we're testing prior to the release.

@richievos
Copy link

@apparentlymart would you expect those changes to support wildcarding? For the kops example that some have mentioned, the tag name would be something of the form kubernetes.io/cluster/foo-bar-123, so the ignore would likely need to be ignore_changes = tags["kubernetes.io/cluster/*"].

@lopezm1
Copy link

lopezm1 commented Jul 19, 2018

excited for this functionality

@dkelertasaamgroup
Copy link

waiting for this too - need to ignore unmanaged tags

@DheerajJoshi
Copy link

@apparentlymart is the changes will work for "aws_autoscaling_group"?
We need to only ignore one particular tag as it gets updated very frequently.

@galdor
Copy link

galdor commented Oct 26, 2018

We are using the following with Terraform v0.11.10:

  lifecycle {
    ignore_changes = ["tags.ServiceVersion"]
  }

but still have the same issue than MikeMcMahon above, with Terraform trying to apply:

tags.%:                                "5" => "4"

For all instances.

Anything new on this feature ?

@andyspiers
Copy link

@galdor if you're trying to stop terraform removing a tag that was added outside of terraform then you need to ignore both the tag(s) that were added and the number of tags:

lifecycle {
    ignore_changes = ["tags.ServiceVersion", "tags.%"]
  }

I tested this just now on a DynamoDB table resource but it should be the same for all resource types.

(Note that ignoring "tags.%" is not needed if terraform expects the tag to be there but you just need to ignore changes to the value)

@galdor
Copy link

galdor commented Oct 26, 2018

It works indeed, thank you !

@enekofb
Copy link

enekofb commented Nov 28, 2018

@richievos In the context of kubernetes the following works ...

resource "aws_subnet" "xxxx" {
  ...
  lifecycle {
    ignore_changes = ["tags.%","tags.kubernetes"]
  }
}

tested with

Terraform v0.11.10
+ provider.aws v1.43.2

@szinck
Copy link

szinck commented Dec 6, 2018

@enekofb worked for me! Thanks! If you are using kops you must also ignore tags.SubnetType.

@citizenkahn
Copy link

citizenkahn commented Dec 14, 2018

hmmm. So I'm using a module and creating an ASG. I've tried many things in tf 0.11.7 and 0.11.10 and only ignoring all tags works:

Ignores:

lifecycle {
    ignore_changes = ["tag"]
  }

Does not Ignore:

lifecycle {
    ignore_changes = ["tags.CreatedAt", "tags.%"]
  }

Providers

  • "null" (1.0.0)...
  • "tls" (1.2.0)...
  • "aws" (1.52.0)...
  • "template" (1.0.0)...
  • "local" (1.1.0)...

I'm not sure what's wrong.

@DrmCtchr
Copy link

in terraform i have
tags = {
tag1 = "Hello"
tag2 = "world"
}

outside of terraform i have my resource additionally tagged with tag3 = "foo" and tag4 = "bar"

I need terraform to apply tag1 and tag2 but ignore any changes to tag3 and tag4 and any additional tags that are dynamically applied by tagging engines outside of terraform that are unknown at the time of terraform resource creation.

I have tried

lifecycle {
ignore_changes = ["tags"]
}

but that will cause terraform to not apply tag1 and tag2 on initial resource creation.

@bpoland
Copy link

bpoland commented Mar 19, 2019

@DrmCtchr several folks above have mentioned ignoring the specific tag names plus the number of tags, like this:

lifecycle {
  ignore_changes = ["tags.%","tags.tag3","tags.tag4"]
}

That has worked perfectly for me.

@DrmCtchr
Copy link

DrmCtchr commented Mar 19, 2019

right the problem is when the tag names are not known ... since our organization tags our resources for us the only thing we can be sure of at resource build time is the names(and values) of tag1 and tag2 after that all bets are off. We need to apply tag1 and tag2 on initial build but we cannot wipe out tag3 and tag4 and tag239842387 etc. on subsequent reapplies

@bpoland
Copy link

bpoland commented Mar 19, 2019

Ah okay. Yeah that's tough then. I would have thought the way you have it above would have created tag1 and tag2 on initial creation, and then not touched the tags after that.

@jbscare
Copy link

jbscare commented Mar 20, 2019

This works for us:

lifecycle {
ignore_changes = ["tags.%", "flexy"]
}

where flexy is a tag that that Terraform creates at provisioning time with a default value, but then we want to change it by hand later, and don't want Terraform to complain about it.

Ignoring tags.% causes it to ignore any other tags that it didn't create. It continues to manage all the other tags that it created.

@DrmCtchr , in your last comment, you didn't mention that you were ignoring tags.% -- are you? If not, try ignoring just that, and see if it does what you want.

@DrmCtchr
Copy link

In testing this:
lifecycle {
ignore_changes = ["tags.%"]
}

DID NOT WORK It did ignore the number of tags ... but in the plan the rest of the tag values set out of band were modified to ""

@jbscare
Copy link

jbscare commented Mar 25, 2019

in the plan the rest of the tag values set out of band were modified to ""

Just to clarify, you mean additional tags that were added that Terraform doesn't know about? Or tags that Terraform does know about, but that you modified out of band?

If you want Terraform to create a tag and set an initial value, and then ignore changes to it after that, you need to add it to the ignore list, like

ignore_changes = ["tags.%", "flexy"]

If Terraform is blanking the values of tags that it doesn't know about, even with tags.% being ignored, that's surprising to me.

@DrmCtchr
Copy link

right if i have terraform set "tag1" to 'foo' and "tag2" to 'bar'
and have some non-terraform automation comes around and sets "tag3" to 'narf' and 'tag4' to "troz"

then even if : ignore_changes = ["tags.%"]

then on next plan:
tag3 = "narf" -> "" and tag4 = "troz" -> ""

@DrmCtchr
Copy link

DrmCtchr commented Mar 25, 2019

the BUG is that if you have:

tags {
"tag1" = "foo"
"tag2" = "bar"
}

AND you have:
lifecycle {ignore_changes = ["tags"]}

that the ignore gets evaluated after the tags block effectivey ignoring it... so you will never get tag1 or tag2 applied.

OR (and this could be likely)
That i have not found the right verbiage to make lifecycle only effective AFTER the Tagblock is applied to the resource

@pgporada
Copy link

pgporada commented May 23, 2019

Edit: Tracking this problem in #21444

The following statement was broken after upgrading from 0.11.14 => 0.12.0.

  lifecycle {
    create_before_destroy = true
    ignore_changes        = ["tags.%", "tags.kubernetes.io"]
  }

Here's the `terraform validate output

$ terraform validate

Error: Attribute name required

  on modules/vpc/vpc.tf line 28, in resource "aws_vpc" "ct":
  28:     ignore_changes        = ["tags.%", "tags.kubernetes.io"]

Dot must be followed by attribute name.


Error: Attribute name required

  on modules/subnets/template/subnet_tmpl.tf line 55, in resource "aws_subnet" "template":
  55:     ignore_changes        = ["tags.%", "tags.kubernetes.io"]

Dot must be followed by attribute name.


Error: Attribute name required

  on modules/subnets/template/subnet_tmpl.tf line 55, in resource "aws_subnet" "template":
  55:     ignore_changes        = ["tags.%", "tags.kubernetes.io"]

Dot must be followed by attribute name.

Removing tags.% fixes the immediate issue and outputs this.

Error: Unsupported attribute

  on modules/vpc/vpc.tf line 28, in resource "aws_vpc" "ct":
  28:     ignore_changes        = ["tags.kubernetes.io"]

This value does not have any attributes.

@apparentlymart
Copy link
Contributor

Hi @pgporada,

Please open a new issue for that, including the information requested in the issue template. If your configuration still contained a tags.% entry after running through the upgrade guide then that's a bug in the upgrade tool, which is something different than what this issue is about.

@cmbrad
Copy link

cmbrad commented Jun 7, 2019

Has anyone found a way to do ignore a single tag successfully in 0.12? I tried:

ignore_changes = [tags.Name]

Accepted by the parser but seemingly does nothing. Plans still try and modify the Name tag

ignore_lifecycle = [tags["Name"]]

Generates the error "A static variable reference is required."

ignore_lifecycle = [tags]

This works as expected but ignores all tags.

@kladiv
Copy link

kladiv commented Jun 17, 2019

+1

@akdracarys
Copy link

+1 to ignore a single tag in 0.12

@davi5e
Copy link

davi5e commented Jul 10, 2019

Read it all and my problem is essentially the same as everyone described, expect that I'm not creating the resources myself, I'm using modules...

As in terraform-aws-modules/vpc/aws for VPC and then terraform-aws-modules/eks/aws for EKS.

As mentioned above, the Kubernetes tags are "kubernetes.io/cluster/*" = "shared" and they're added to each subnet and also for the VPC resource.

I'm using 0.12 but, even if lifecycle.ignore_changes were to work, how would it be used from the module? =/

@ghost
Copy link

ghost commented Jul 24, 2019

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 Jul 24, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.