Terraform: существует ли краткий синтаксис для указания нескольких тегов для ресурса?

10

Чтобы прикрепить несколько тегов к ресурсу, в настоящее время я использую несколько 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для каждого тега.

Обновление: вопрос был написан до выхода Terrafrom v0.12. С тех пор поддержка улучшена с динамическими вложенными блоками (см. Мой ответ ниже ).

Филипп Классен
источник

Ответы:

7

Для того , auto-scaling-groupэто самый лаконичный синтаксис доступен.

Для большинства других ресурсов вы используете tagsсинтаксис, который выглядит следующим образом:

tags {
  Key1 = "value1"
  Key2 = "value2"
}
Briansbum
источник
3

В Terraform v0.12 добавлена ​​поддержка динамических вложенных блоков. Следующий пример взят из их записи в блоге о новых функциях (see section Динамические вложенные блоки ):

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
    }
  }
}
Филипп Классен
источник
2

Другой вариант - использовать 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поле, чтобы показать, как генерировать со

Эрик Остерман
источник
Что было бы лучшим способом сделать «имя» уникальным для каждого ресурса? Если вы используете модуль с нулевой меткой, каждое «имя» в ресурсах будет одинаковым. Что, если вы хотите назвать свои подсети суффиксом вроде -private-subnet? Есть ли способ, которым нулевая метка может справиться с этим?
Исаак
0

Теперь aws_autoscaling_groupон поддерживает список тегов ( https://www.terraform.io/docs/providers/aws/r/autoscaling_group.html#tags ). Но это немного отличается от синтаксиса других ресурсов terraform:

tags = [
  {
    key                 = "explicit1"
    value               = "value1"
    propagate_at_launch = true
  },
  {
    key                 = "explicit2"
    value               = "value2"
    propagate_at_launch = true
  },
]

Это также позволяет динамически создавать теги посредством интерполяции.

Финн
источник