【问题标题】:terraform dynamic tags on ASG and other resources like EFSASG 和 EFS 等其他资源上的 terraform 动态标签
【发布时间】:2018-12-14 21:24:43
【问题描述】:

我想在aws_autoscaling_group 资源上获取动态标签,但与文档中的示例不同,我现在还不知道会有多少标签必须与其他资源共享 .在下面的示例中,这将是 EFS,但基本上所有其他 aws 资源都会受到影响。

所以设置了以下几行:

variable "tags" {
  type = "map"

  default = {
    tag1 = "value1"
    tag2 = "value2"
  }
}

resource "aws_autoscaling_group" "asg" {
  name                 = "test-asg"
  launch_configuration = "test-lc"
  min_size             = 1
  max_size             = 1
  min_elb_capacity     = 1
  vpc_zone_identifier  = ["subnet-1234"]
  tags                 = <code_here>
}

resource "aws_efs_file_system" "foo" {
  creation_token = "my-product"
  tags           = "${var.tags}"
}

我想出了一个最多支持x 动态标签的解决方案。不幸的是,它使用虚拟标签来填充未提供的标签,直到 x

data "template_file" "test" {
  count    = "9"
  template = "key:@:$${key}:@:value:@:$${value}:@:propagate_at_launch:@:true"

  vars {
    key   = "${element(concat(keys(var.tags), list("unusedtag1", "unusedtag2","unusedtag3","unusedtag4","unusedtag5","unusedtag6","unusedtag7","unusedtag8","unusedtag9")), count.index)}"
    value = "${element(concat(values(var.tags), list("", "","","","","","","","")), count.index)}"
  }
}

locals{
  tag0 = "${split(":@:", data.template_file.test.0.rendered)}"
  tag1 = "${split(":@:", data.template_file.test.1.rendered)}"
  tag2 = "${split(":@:", data.template_file.test.2.rendered)}"
  tag3 = "${split(":@:", data.template_file.test.3.rendered)}"
  tag4 = "${split(":@:", data.template_file.test.4.rendered)}"
  tag5 = "${split(":@:", data.template_file.test.5.rendered)}"
  tag6 = "${split(":@:", data.template_file.test.6.rendered)}"
  tag7 = "${split(":@:", data.template_file.test.7.rendered)}"
  tag8 = "${split(":@:", data.template_file.test.8.rendered)}"

  tags = "${list(
          map(local.tag0[0],local.tag0[1],local.tag0[2],local.tag0[3],local.tag0[4],local.tag0[5]),
          map(local.tag1[0],local.tag1[1],local.tag1[2],local.tag1[3],local.tag1[4],local.tag1[5]),
          map(local.tag2[0],local.tag2[1],local.tag2[2],local.tag2[3],local.tag2[4],local.tag2[5]),
          map(local.tag3[0],local.tag3[1],local.tag3[2],local.tag3[3],local.tag3[4],local.tag3[5]),
          map(local.tag4[0],local.tag4[1],local.tag4[2],local.tag4[3],local.tag4[4],local.tag4[5]),
          map(local.tag5[0],local.tag5[1],local.tag5[2],local.tag5[3],local.tag5[4],local.tag5[5]),
          map(local.tag6[0],local.tag6[1],local.tag6[2],local.tag6[3],local.tag6[4],local.tag6[5]),
          map(local.tag7[0],local.tag7[1],local.tag7[2],local.tag7[3],local.tag7[4],local.tag7[5]),
          map(local.tag8[0],local.tag8[1],local.tag8[2],local.tag8[3],local.tag8[4],local.tag8[5]),
          )}"
}

通过 ASG 中的此代码,我可以使用 tags = ["${local.tags}"]。通过示例输入,资源被标记为

tag1 = value1
tag2 = value2
unusedtag1 = 
unusedtag2 = 
unusedtag3 = 
unusedtag4 = 
unusedtag5 =
unusedtag6 = 
unusedtag7 =  

我想有一个解决方案是

  • 动态
  • 不使用不必要的标签
  • 同时使用 ASG 和其他 AWS 资源
  • 简单地将 ASG 上的所有标签传播到启动的实例:propagate_on_launch = true

因此,解决方案必须先获取现有标签并将propagate_at_launch 键添加到其中,然后再将其添加到 ASG。

【问题讨论】:

  • 投反对票,没有评论不好!请解释您投反对票的原因。

标签: terraform terraform-provider-aws


【解决方案1】:

您可以创建一个保存共享标签的本地地图...

locals {
  shared_tags = "${map(
    "Foo", "1",
    "Bar", "2"
  )}"
}

...然后将它们(带有可选的合并更新)应用到资源的标记属性:

resource "aws_autoscaling_group" "asg" {
  name                 = "test-asg"
  launch_configuration = "test-lc"
  min_size             = 1
  max_size             = 1
  min_elb_capacity     = 1
  vpc_zone_identifier  = ["subnet-1234"]
  tags                 = "${merge(local.shared_tags, map("Baz", "3"))}"
}

resource "aws_efs_file_system" "foo" {
  creation_token = "my-product"
  tags           = "${merge(local.shared_tags, map("Qux", "4"))}"
}

dwmkerr 的属性为 idea

【讨论】:

  • 嘿@Eric。谢谢,但不起作用。因为 ASG 需要第三个参数propagate_at_launch。
  • 那我还没有完全理解你的问题。您的示例中没有 propogate_at_launch 。如果您希望由标记的 ASG 启动的实例动态获取更新的标签,则不能这样做,因为这些实例不是由 Terraform 管理的。动态是什么意思?
  • 动态标签例如是部署的版本。当您运行 terraform 时会发生一些变化,但之后不会自行发生变化。基本上所有标签都应该传播到实例。原始标签中没有propagate_at_launch 正是问题所在。很抱歉造成混乱。
  • 这是一个有趣的问题,您应该考虑更新您的问题以更清楚地表明这是问题所在。
  • 嗯。那是我在这里的尝试。我已经有一个几乎相同的问题,它的解释方式与预期完全不同。我已经编辑了这个问题,它是否让您更清楚?如果不能随意编辑。
【解决方案2】:

然后,您可以将aws_ec2_tag 资源与提供程序属性ignore_tags 结合使用,该资源也适用于非ec2 资源。更多详情请参考我在该主题上所做的another answer

【讨论】:

    【解决方案3】:

    您现在可以使用 Terraform 的 dynamic "tag" 块来完成此操作。首先,创建一个数据资源:

    data "aws_default_tags" "tags" {}
    

    接下来。将此数据资源插入您的目标资源(如aws_autoscaling_group:

    resource "aws_autoscaling_group" "foo" {
      desired_capacity          = 1
      force_delete              = true
      health_check_grace_period = 300
      launch_configuration = aws_launch_configuration.foo.name
      max_size             = 4
      min_size             = 1
      name                 = var.resource_name
      placement_group      = aws_placement_group.foo.name
      vpc_zone_identifier  = [aws_subnet.private[*].id]
    
      dynamic "tag" {
        for_each = data.aws_default_tags.tags.tags
        content {
          key                 = tag.key
          value               = tag.value
          propagate_at_launch = true
        }
      }
    

    【讨论】:

      猜你喜欢
      • 2021-05-31
      • 2018-08-01
      • 1970-01-01
      • 2018-08-10
      • 1970-01-01
      • 2020-07-09
      • 2016-08-19
      • 2021-10-28
      • 2021-07-25
      相关资源
      最近更新 更多