EC2 资源的 terraform 动态标记失败,并显示"此处不应包含 "tag" 类型的块"


➜ terraform -v  
Terraform v0.12.24
+ provider.aws v2.60.0

我的地形示例。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.

在模式中没有为aws_instance资源类型定义名为tag的块类型。是一个名为tags的参数,我认为这是获得您在这里寻找的结果的方法:

tags = local.standard_tags

我想你想到的是aws_autoscaling_group中的tag块,它偏离了AWS提供程序资源中tags参数的通常设计,因为对于这种资源类型,特别是每个标记都有额外的属性propagate_at_launch。该属性仅适用于自动缩放组,因为它决定从自动缩放组启动的实例是否会继承组本身的特定标记。

不幸的是,由于aws_instance资源的tags属性是一个映射,在HCL构造atm中,它不能像动态嵌套块部分中的aws_autoscaling_group示例中的标签属性那样作为可重复块存在:https://www.hashicorp.com/blog/hashicorp-terraform-0-12-preview-for-and-for-each/

但从你的评论来看,你似乎试图用键/值对的映射来设置tags属性?在这种情况下,这当然是可行的——您应该能够直接设置标签为local.standard_tags 的字段

或者,如果您打算用键/值对列表设置tags属性,则for循环也可以通过执行以下操作来工作:

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
}
}

能够

  1. 将相同的公共标记附加到所有资源
  2. 同时仍然可以向单个资源添加自定义标记

您可以在地形提供者部分中添加默认标签部分

# Configure the AWS Provider
provider "aws" {
region  = var.aws_region
profile = var.aws_profile
default_tags {
tags = {
environment = var.tag_environment
created_by  = var.tag_created_by
}
}
}

你可以在这里查看完整的文档

相关内容

最新更新