terraform icon indicating copy to clipboard operation
terraform copied to clipboard

ignore_changes should support wildcards

Open gozer opened this issue 8 years ago • 17 comments

In my particular example I have a case where I'd like to ignore a single proprety of a route, but I can't determine the item id, since it's actually going to be route.123323232323.instance_id, and I can't predict what that ID is going to be like.

Instead of simply doing a Prefix match, would be nice if wildcards (or regexpes, really) were also supported.

resource "aws_route_table" "private" {
  lifecycle {

    ignore_changes = [
      # One of these should work, but they don't, so be careful if we ever need to change the routes below
      #"route.*.instance_id",
      #"route.instance_id",
      #"instance_id",
      "route",
    ]
  }

  route {
    cidr_block = "0.0.0.0/0"
    network_interface_id = "${aws_network_interface.private-nat.id}"
  }

gozer avatar Mar 16 '16 17:03 gozer

Hi @gozer - yep this use case definitely makes sense! Tagged.

phinze avatar Mar 16 '16 20:03 phinze

Agree with @gozer. This also applies to resources like aws_db_parameter_group that takes a list of db_parameters to apply.

resource "aws_db_parameter_group" "default" {
    name = "rds-pg"
    family = "mysql5.6"
    description = "RDS default parameter group"

    parameter {
      name = "character_set_server"
      value = "utf8"
    }

    parameter {
      name = "character_set_client"
      value = "utf8"
    }

   lifecycle {
    ignore_changes = [ "parameter" ]
   }
}

This will ignore changes for All parameters and won't allow ignoring only say "character_set_client" parameter.

   lifecycle {
    ignore_changes = [ "parameter.character_set_client" ]
   }

Also, I suggest there should be an negation option available, something like below, to ignore changes to all parameters but character_set_client

lifecycle { not_ignore_changes = [ "parameter.character_set_client" ] }

yasin-amadmia-mck avatar Apr 04 '16 14:04 yasin-amadmia-mck

I am not sure what i am missing .. but I cant get ignore change to work on nested objects like https://www.terraform.io/docs/providers/aws/r/emr_cluster.html#emr_managed_master_security_group. Its annoying that they change because they are AWS managed so they change all the time... this is what I came up with that wont work ..

resource "aws_emr_cluster" "cluster" {
  lifecycle {
    ignore_changes = ["step", "ec2_attributes.0.emr_managed_master_security_group", " ec2_attributes.0.emr_managed_slave_security_group"]
  }
}

Anyone has an insight into what can I do to make it work, just using "emr_managed" does not work either ..

resource "aws_emr_cluster" "cluster" {
  lifecycle {
    ignore_changes = ["step", "emr_managed"]
  }
}

suneeta-mall avatar May 24 '18 06:05 suneeta-mall

This got a "yep this use case definitely makes sense! Tagged." but hasn't seen any implementation for over 2 years? Will this ever be supported?

rhyas avatar Sep 19 '18 16:09 rhyas

@gozer you found any workaround for this issue?

yunoth avatar Jul 02 '19 14:07 yunoth

Any updates on this feature request?

jdj333 avatar Sep 26 '19 23:09 jdj333

I'm using Cloud Custodian which makes heavy use of tags prefixed by c7n to, for example, mark resources with Security Hub finding IDs and to mark them for future operations such as stopping an EC2 instance or deleting an S3 bucket. Being able to ignore all tags prefixed with c7n would be a huge help here, since I don't think Cloud Custodian gives you much ability to customize the tag keys it uses on resources.

brianreumere avatar Jan 03 '20 21:01 brianreumere

This feature would be very helpful for managing subnets that are used by EKS clusters. I have exactly the same situation as described here, and have to ignore changes to all tags instead of using something similar to this: kubernetes.io/cluster/*

akonokhov avatar May 04 '20 09:05 akonokhov

It looks like v2.60.0 of the AWS provider includes this PR that adds provider-level ignore_tags functionality! I haven't tested it out yet, but I think that would address this feature request (or at least my use case with Cloud Custodian and Security Hub). https://github.com/terraform-providers/terraform-provider-aws/releases

brianreumere avatar May 07 '20 17:05 brianreumere

I'm in a situation where I would like to use lifecycle to ignore changes to all ip_restriction blocks in the azurerm_app_service. For example:

resource "azurerm_app_service" "webapp" {
  name                = lower(join("-", [azurerm_resource_group.rg.location, "mytestwebapp-83749195"]))
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  app_service_plan_id = azurerm_app_service_plan.asp.id
  enabled             = true
  site_config {
    always_on = true
    use_32_bit_worker_process = false
    dotnet_framework_version  = "v4.0"
    websockets_enabled        = true
  }
  lifecycle {
    ignore_changes = [tags, app_settings, site_config.ip_restriction]
  }
}

In this example, I want to be able to configure site_config in Terraform, but I don't want Terraform to change ip_restriction blocks, and in this resource, ip_restriction block exists in the site_config{} block if you refer to the azurerm_app_service documentation.

Update: I figured out how to ignore all ip_restriction changes in site_config. I had to use index reference

  lifecycle {
    ignore_changes = [tags, app_settings, site_config["ip_restriction"]]
  }

ajklotz avatar Nov 12 '20 19:11 ajklotz

Here's the workaround I used to avoid resetting the tags on subnets that are used by EKS clusters. I used the new ignore_tags feature in the AWS provider:

provider "aws" {
  region = var.region
  ignore_tags {
    key_prefixes = ["kubernetes.io"]
  }
}

EronWright avatar Dec 17 '20 22:12 EronWright

My insane workaround at the moment is to use an external datasource with a script to queue information to match what has changed and inject that value into the place of the list map attribute. A big use case for this is vsphere virtual machines that get migrated around manually or by DRS. I don't want and also don't care if the resource pool (compute host) or the datastore for virtual disks locations change. To simply add a disk to a VM. the Entire VM in some cases with huge disks has to move back to it's original declared location or you have to go through and edit all of the values to match the current state manually. External datasource works just fine for now though.

lebonez avatar Dec 23 '21 15:12 lebonez

+1

jaredbrogan avatar Mar 21 '22 15:03 jaredbrogan

I am also looking for a way to ignore all tags (which i have no control over ) except specific ..

like suggestion not_ignore_changes

mpjtaylor avatar Mar 23 '23 08:03 mpjtaylor

7.5 years later, still no solution? Yes there is the aws provider's ignore_tags parameter, but it's global and cannot be used for individual resources.

shapirus avatar Sep 09 '23 09:09 shapirus

Feels like this it could be something simple to someone with experience in the: https://github.com/hashicorp/terraform/blob/main/internal/terraform/node_resource_abstract_instance.go#L1362 func processIgnoreChangesIndividual

Looks like no changes to the function in the last 3 years... Last by @jbardin: https://github.com/hashicorp/terraform/commit/ea077cbd90b3e079ef4df5659a6ac06ecab49d91 Maybe James Bardin can give an estimate how complex it would be to implement this

heldersepu avatar Feb 03 '24 21:02 heldersepu

It would be great to see this kind of functionality. My use case is that I wish to decouple the deployment of an Azure Function with azurerm_windows_function_app and the App Settings/Sticky Settings which I wish to update during code deploy.

This is related to using App Settings to selectively disable Functions during Slot based deployment, and the specific App Settings are not know at initial deployment time. (https://learn.microsoft.com/en-us/azure/azure-functions/disable-function?tabs=portal#functions-in-a-slot) Of course we could re-terraform the Function App prior to code deployment, but it impacts our agility.

An ideal case for me would be to define and ignore block like

resource "azurerm_windows_function_app" "example" {
  name                = "example-windows-function-app"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location

  storage_account_name       = azurerm_storage_account.example.name
  storage_account_access_key = azurerm_storage_account.example.primary_access_key
  service_plan_id            = azurerm_service_plan.example.id

  site_config {}
  app_settings = {
    ValueKnownAtDeployTime = "Value1"
    StickyValueKnownAtDeployTime = "Value2"
  }
  sticky_settings {
    app_setting_names = ["StickyValueKnownAtDeployTime"]
  }

  lifecycle {
    ignore_changes = [tags, app_settings["AzureWebJobs.*.Disabled"], sticky_settings.app_setting_names["AzureWebJobs.*.Disabled"]]
  }
}

Then during code deployment I am free to add in the additional AzureWebJobs.*.Disabled settings as required without causing state drift every time, or forcing the removal of settings if I have to terrraform the underlying Function Apps.

b-twis avatar Feb 07 '24 23:02 b-twis

+1

neerajjose avatar Feb 29 '24 06:02 neerajjose