Terraform Dynami c тегирование ресурса EC2 не выполняется с помощью `Блоки типа" тег "здесь не ожидаются` - PullRequest
1 голос
/ 05 мая 2020
➜ terraform -v  
Terraform v0.12.24
+ provider.aws v2.60.0

My terraform example.tf :

locals {
  standard_tags = {
    team        = var.team
    project     = var.project
    component   = var.component
    environment = var.environment
  }
}

provider "aws" {
  profile = "profile"
  region  = var.region
}

resource "aws_key_pair" "security_key" {
  key_name   = "security_key"
  public_key = file(".ssh/key.pub")
}

# New resource for the S3 bucket our application will use.
resource "aws_s3_bucket" "project_bucket" {
  # NOTE: S3 bucket names must be unique across _all_ AWS accounts, so
  # this name must be changed before applying this example to avoid naming
  # conflicts.
  bucket = "project-bucket"
  acl    = "private"
}


resource "aws_security_group" "ssh_allow" {
  name = "allow-all-ssh"
  ingress {
    cidr_blocks = [
      "0.0.0.0/0"
    ]
    from_port = 22
    to_port   = 22
    protocol  = "tcp"
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_security_group" "http_allow" {
  name = "allow-all-http"
  ingress {
    cidr_blocks = [
      "0.0.0.0/0"
    ]
    from_port = 80
    to_port   = 80
    protocol  = "tcp"
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}


resource "aws_instance" "example" {
  ami             = "ami-08ee2516c7709ea48"
  instance_type   = "t2.micro"
  security_groups = [aws_security_group.ssh_allow.name, aws_security_group.http_allow.name]
  key_name        = aws_key_pair.security_key.key_name

  connection {
    type        = "ssh"
    user        = "centos"
    private_key = file(".ssh/key")
    host        = self.public_ip
  }


  provisioner "local-exec" {
    command = "echo ${aws_instance.example.public_ip} > ip_address.txt"
  }

  provisioner "remote-exec" {
    inline = [
      "sudo yum -y install nginx",
      "sudo systemctl start nginx"
    ]
  }

  depends_on = [aws_s3_bucket.project_bucket, aws_key_pair.security_key]

  dynamic "tag" {
    for_each = local.standard_tags

    content {
      key                 = tag.key
      value               = tag.value
      propagate_at_launch = true
    }
  }

}

И когда я запускаю terraform plan

, я получил следующую ошибку:

➜ terraform plan

Error: Unsupported block type

  on example.tf line 94, in resource "aws_instance" "example":
  94:   dynamic "tag" {

Blocks of type "tag" are not expected here.


Ответы [ 2 ]

2 голосов
/ 06 мая 2020

Тип блока с именем tag не определен в схеме для типа ресурса aws_instance. Здесь - это аргумент с именем tags, который, я думаю, является способом получить результат, который вы здесь искали:

  tags = local.standard_tags

Я думаю, вы думаете о tag блок в aws_autoscaling_group, который отличается от обычного дизайна tags аргументов в AWS ресурсах провайдера, потому что для этого типа ресурса, в частности, каждый тег имеет дополнительный атрибут propagate_at_launch. Этот атрибут применяется только к группам автомасштабирования, поскольку он определяет, будут ли экземпляры, запущенные из группы автомасштабирования, наследовать конкретный тег от самой группы.

1 голос
/ 06 мая 2020

к сожалению, поскольку атрибут тегов ресурса aws_instance представляет собой карту, w / в конструкциях HCL atm, он не может существовать в виде повторяющихся блоков, таких как атрибут тега в примере aws_autoscaling_group, показанном здесь в разделе Dynami c Вложенные блоки: https://www.hashicorp.com/blog/hashicorp-terraform-0-12-preview-for-and-for-each/

но из вашего комментария кажется, что вы пытаетесь установить атрибут тегов, возможно, с картой пар ключ / значение? в этом случае это, безусловно, выполнимо ? вы должны иметь возможность напрямую установить поле с помощью tags = local.standard_tags

ИЛИ, если вы собираетесь установить атрибут тегов со списком пар ключ / значение, a для l oop также может работать, выполнив что-то вроде:

locals {
  standard_tags = [
  {
      name   = "a"
      number = 1
    },
    {
      name   = "b"
      number = 2
    },
    {
      name   = "c"
      number = 3
    },
  ]
}

resource "aws_instance" "test" {
 ...
  tags = {
    for tag in local.standard_tags:
    tag.name => tag.number
  }
}

...