问题描述
在使用Terraform时,希望能够为一个资源指定多个标签,他目前使用多个tag
块来实现:
resource "aws_autoscaling_group" "instance" {
# ...
tag {
key = "Name"
value = "${var.cluster_prefix}"
propagate_at_launch = true
}
tag {
key = "Owner"
value = "${var.tag_Owner}"
propagate_at_launch = true
}
tag {
key = "Project"
value = "${var.tag_Project}"
propagate_at_launch = true
}
}
尽管这样能够工作,但用户想知道是否有更简洁的语法。同时,他还提到这种方式有些容易出错,因为需要为每个标签都指定propagate_at_launch
属性。
解决方案
请注意以下操作可能涉及版本差异或较新特性,请确保你的Terraform版本支持所述功能。
最佳解决方案
对于auto-scaling-group
资源来说,目前这已经是最简洁的语法了。
对于大多数其他资源,你可以使用类似如下的tags
语法:
tags = {
Key1 = "value1"
Key2 = "value2"
}
方案2
从Terraform v0.12开始,支持动态嵌套块(Dynamic Nested Blocks)。下面的示例源自Terraform的博客文章,介绍了这个新特性(见Dynamic Nested Blocks):
locals {
standard_tags = {
Name = var.cluster_prefix
Owner = var.tag_Owner
Project = var.tag_Project
}
}
resource "aws_autoscaling_group" "example" {
# ...
dynamic "tag" {
for_each = local.standard_tags
content {
key = tag.key
value = tag.value
propagate_at_launch = true
}
}
}
方案3
另一个选择是使用terraform-null-label
模块。该模块支持将一个名为tags
的变量作为标准Terraform映射传递。模块会生成一个名为tags_as_list_of_maps
的输出,其中包含你想要的标签格式。这个模块的另一个好处是可以生成遵循固定约定的一致性资源名称。
例如,你可以这样使用:
module "example" {
source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=master"
namespace = "eg"
stage = "prod"
name = "bastion"
tags = {
"BusinessUnit" = "XYZ"
"Snapshot" = "true"
}
}
resource "aws_autoscaling_group" "instance" {
# ...
name = "${module.example.id}"
...
tags = "${module.example.tags_as_list_of_maps}"
...
}
注意:上述示例中,我添加了
name
字段以展示如何生成唯一的资源名称。
方案4
aws_autoscaling_group
现在支持一个标签列表(文档链接)。但这与其他Terraform资源的语法略有不同:
tags = [
{
key = "explicit1"
value = "value1"
propagate_at_launch = true
},
{
key = "explicit2"
value = "value2"
propagate_at_launch = true
},
]
方案5
如果你希望将相同的常用标签附加到所有资源,并仍然可以为各个资源添加自定义标签,以下是最佳实践:
在Terraform提供者部分添加默认标签配置:
# 配置AWS提供者
provider "aws" {
region = var.aws_region
profile = var.aws_profile
default_tags {
tags = {
environment = var.tag_environment
created_by = var.tag_created_by
}
}
}
注意:在这个示例中,我添加了
name
字段以展示如何生成唯一的资源名称。
这样,你可以在资源定义中省略常见的标签,Terraform会自动应用它们。
注意:如果你使用的是旧版本的Terraform,某些解决方案可能不适用或需要相应的修改。请确保你的Terraform版本符合解决方案中所述。