【问题标题】:Terraform Change Tags Only If There Is Any Other ChangeTerraform 仅在有任何其他更改时更改标签
【发布时间】:2021-08-25 19:39:15
【问题描述】:

我想使用以下内容为项目中的所有资源创建/管理通用标签。对于 common_var_tag,我希望仅在有任何其他更改时才应用它。因此,源被标记为 last-modified by who and when。

有什么办法吗?

提前致谢!

locals { 
    common_var_tags = { 
        ChangedBy = data.aws_caller_identity.current.arn
        ChangedAt = timestamp() 
    } 

    common_fix_tags = { 
        Project.  = "Project" 
        Owner     = "Tiger Peng" 
        Team      = "DevOps" 
        CreatedAt = "2021-06-08" 
     } 
} 

例如,现在,我必须注释掉“local.common_var_tags”,因为每次我在不更改任何属性的情况下运行terraform planterrafomr apply 时,由于ChangedAt = timestamp() 而标记/更改了资源nginx .我想找到只有当其他属性发生变化时才会应用这个标签变化的方式。

resource "aws_instance" "nginx" {
  count                  = 1
  ami                    = var.nginx-ami
  instance_type          = var.nginx-instance-type
  subnet_id              = var.frontend-subnets[count.index]
  key_name               = aws_key_pair.key-pair.key_name
  vpc_security_group_ids = [aws_security_group.nginx-sg.id]

  root_block_device {
    delete_on_termination = false
    encrypted             = true
    volume_size           = var.nginx-root-volume-size
    volume_type           = var.default-ebs-type
    tags = merge(
      local.common_fix_tags,
      #local.common_var_tags,
      map(
        "Name", "${var.project}-${var.env}-nginx-${var.zones[count.index]}"
      )
    )
  }

  tags = merge(
    local.common_fix_tags,
    #local.common_var_tags,
    map(
      "Name", "${var.project}-${var.env}-nginx-${var.zones[count.index]}",
      "Role", "Nginx"
    )
  )
}

【问题讨论】:

  • 你有任何应用这些标签的例子吗?不清楚“仅应用了其他更改”是什么意思?改变什么,在哪里?

标签: terraform terraform-provider-aws


【解决方案1】:

我遇到了同样的问题,我找到了解决方法。这不是一个干净的解决方案,但它以某种方式起作用。

首先,您必须在资源上创建一个生命周期块并忽略“ChangedAt”标签上的更改:

resource "aws_instance" "nginx" {
  ...

  lifecycle {
    ignore_changes = [tags["ChangedAt"]]
  }
}

然后创建一个局部变量。它的值必须是一个 md5 哈希值,其中包含所有资源属性的值,其更改应在“ChangedAt”标签上引发和更新:

locals{
  hash = md5(join(",",[var.nginx-ami,var.nginx-instance-type, etc]))
}

最后创建一个在该局部变量更改时触发的空资源,并使用更新“ChangedAt”标签的local-exec:

resource "null_resource" "nginx_tags" {
  triggers = {
    instance = local.hash
  }

  provisioner "local-exec" {
    command = "aws resourcegroupstaggingapi tag-resources --resource-arn-list ${aws_instance.nginx.arn} --tags ChangedAt=${timestamp()}"
  }
}

使用该配置,md5 中包含的变量的任何更改都会更新您的标签

【讨论】:

    【解决方案2】:

    这有点违背不可变基础架构的目的。您不应该在 2 个连续的 tf apply 之间进行任何更改。但是因为当您在 K8S 集群中工作时这是一种非常常见的模式,Terraforn AWS 提供商 2.6 允许您全局忽略标签上的更改

    provider "aws" {
      # ... potentially other configuration ...
    
      ignore_tags {
        # specific tag
        keys = ["ChangedAt"]
        # or by prefix to ignore ChangedBy too
        key_prefixes = ["Changed"]
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-07
      • 2021-12-05
      相关资源
      最近更新 更多