仅当有任何其他更改时 Terraform 才更改标签

Tig*_*eng 5 terraform terraform-provider-aws

我想使用如下内容来创建/管理项目中所有资源的通用标签。对于 common_var_tag,我希望仅在有任何其他更改时应用它。因此,源代码被标记为最后修改者和时间。

有什么办法可以做到吗?

提前致谢!

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" 
     } 
} 
Run Code Online (Sandbox Code Playgroud)

例如,现在,我必须注释掉“ local.common_var_tags”,因为每次运行terraform planterrafomr apply不更改任何属性时,资源 nginx 都会由于ChangedAt = timestamp(). 我想找到一种方法,只有当其他属性发生变化时,才会应用此标签更改。

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"
    )
  )
}
Run Code Online (Sandbox Code Playgroud)

小智 0

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

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

resource "aws_instance" "nginx" {
  ...

  lifecycle {
    ignore_changes = [tags["ChangedAt"]]
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

最后创建一个空资源,该资源在该局部变量发生更改时触发,并使用更新“ChangedAt”标记的本地执行程序:

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()}"
  }
}
Run Code Online (Sandbox Code Playgroud)

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