terraform-provider-mongodbatlas icon indicating copy to clipboard operation
terraform-provider-mongodbatlas copied to clipboard

Terraform lifecycle ignore_changes tags

Open OlehHarmash opened this issue 3 months ago • 1 comments

Hello!

Terraform CLI and Terraform MongoDB Atlas Provider Version

Terraform v1.1.9

mongodbatlas = {
      source  = "mongodb/mongodbatlas"
      version = ">= 1.15.1"
    }

Terraform Configuration File

resource "mongodbatlas_advanced_cluster" "cluster" {
  count = var.is_advanced_cluster && var.cluster_name != null ? 1 : 0

  project_id     = var.project_id
  name           = var.cluster_name
  cluster_type   = var.cluster_type
  backup_enabled = var.cluster_backup_enabled

  dynamic "bi_connector_config" {
    for_each = var.cluster_bi_connector_config != null ? ["true"] : []
    content {
      enabled         = var.cluster_bi_connector_config.enabled
      read_preference = var.cluster_bi_connector_config.read_preference
    }
  }

  replication_specs {
    region_configs {
      dynamic "electable_specs" {
        for_each = var.electable_specs
        content {
          instance_size = electable_specs.value.instance_size
          node_count    = electable_specs.value.node_count
        }

      }
      dynamic "analytics_specs" {
        for_each = var.analytics_specs
        content {
          instance_size = analytics_specs.value.instance_size
          node_count    = analytics_specs.value.node_count
        }
      }

      provider_name = var.provider_name
      region_name   = var.advanced_cluster_region_name
      priority      = var.advanced_cluster_priority
    }
  }

  dynamic "tags" {
    for_each = local.tags
    content {
      key   = tags.key
      value = tags.value
    }
  }

  lifecycle {
    ignore_changes = [
      #tags["costcenter"],
      #tags["environment"],
      #tags["projectcode"],
      #Block type "tags" 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
      #tags[index(local.default_tags[*].key, "costcenter")],
      #A single static variable reference is required: only attribute access and
      #│ indexing with constant keys. No calculations, function calls, template
      #│ expressions, etc are allowed here
      #tags[[for k, v in local.default_tags : k if v.key == "costcenter"]],
      #│ A single static variable reference is required: only attribute access and
      #│ indexing with constant keys. No calculations, function calls, template
      #│ expressions, etc are allowed here
      tags,
      provider_disk_type_name,
      provider_instance_size_name
    ]
  }
}

Steps to Reproduce

Case 1:

  1. Apply to terraform configuration with tags.
  2. Run any pipeline that could update some specific tags. For ex. it could be some internal policy to update Production cluster tags to change "costcenter" or "project code" but without running terraform.
  3. Run Terraform apply and override changed tags.

Case 2: 0) you need to manage some tags not from Terraform

  1. Apply to terraform configuration with tags.
  2. Add tags manually.
  3. Run Terraform apply and override changed tags.

Expected Behavior

It would be nice if tags would not be set of list and will be a map, like tags for Azure resources. In that case you can ignore some tags by name. Like this

lifecycle {
    ignore_changes = [
      tags["costcenter"],
      tags["environment"],
      tags["projectcode"]
    ]
  }

Actual Behavior

You can ignore all tags. You can ignore tags by number element number in the list, but it could be changed if some custom tags are defined in the workspace(not in the module). In that case, you will ignore the wrong tag.

Debug Output

Crash Output

      #tags["projectcode"],
      #│Block type "tags" 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

      #tags[index(local.default_tags[*].key, "costcenter")],
      #│A single static variable reference is required: only attribute access and
      #│ indexing with constant keys. No calculations, function calls, template
      #│ expressions, etc are allowed here

      #tags[[for k, v in local.default_tags : k if v.key == "costcenter"]],
      #│ A single static variable reference is required: only attribute access and
      #│ indexing with constant keys. No calculations, function calls, template
      #│ expressions, etc are allowed here

Additional Context

References

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/guides/resource-tagging

OlehHarmash avatar Mar 11 '24 13:03 OlehHarmash