不能使用通过与aws_route_table_association相同的terraform配置创建的子网id



我正在尝试使用由resource "aws_subnet" "public" {...}块创建的子网id,进入resource "aws_route_table_association" "public" {...}块,但它给出了错误:

Error: Invalid for_each argument

on main.tf line 69, in resource "aws_route_table_association" "public":
69:   for_each       = toset(tolist([for subnet in aws_subnet.public : subnet.id]))
├────────────────
│ aws_subnet.public is object with 3 attributes

The "for_each" set includes values derived from resource attributes
that cannot be determined until apply, and so Terraform cannot determine
the full set of keys that will identify the instances of this resource.

When working with unknown values in for_each, it's better to use a map
value where the keys are defined statically in your configuration and 
where only the values contain   apply-time results.
Alternatively, you could use the -target planning option to first apply
only the resources that the for_each value depends on, and then apply a
second time to fully converge.

如下面的地形配置文件所示,我在resource "aws_route_table_association" "public"中使用depends_on = [aws_subnet.public],期望在关联触发之前创建子网id。

就像错误信息中建议的那样,如果我像下面这样分两步运行:

terraform apply -target=aws_subnet.public -target=aws_subnet.private -auto-approve
terraform apply -auto-approve

映射建议,我不清楚,但我认为将需要使用AWS区域名称进行映射,我不想使用,因为我需要在任何区域上运行它。如果我可以使用aws_region变量的映射,我可以这样做。

我如何通过一次运行来完成这个?

配置文件main.tf:

// provider
provider "aws" {
region                   = var.aws_region
shared_credentials_files = ["~/.aws/credentials"]
#profile                  = var.aws_profile # using `default` profile
}
// data
data "aws_availability_zones" "available" {
state = "available"
filter {
name   = "zone-type"
values = ["availability-zone"]
}
}
//variables
variable "aws_region" {
type    = string
default = "us-east-1"
}
variable "environment" {
type        = string
description = "Deployment Environment (e.g. dev, prod, etc.)"
default     = "dev"
}
variable "vpc_cidr" {
type        = string
description = "AWS VPC CIDR"
default     = "10.0.0.0/16"
}
variable "public_subnet_cidrs" {
type    = list(string)
default = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
}
// vpc
resource "aws_vpc" "this" {
cidr_block           = var.vpc_cidr
enable_dns_hostnames = true
tags = {
Name = "${var.environment}-vpc"
}
}
// public subnets, public route table, public subnet associations
resource "aws_subnet" "public" {
for_each          = toset(var.public_subnet_cidrs)
cidr_block        = each.value
vpc_id            = aws_vpc.this.id
availability_zone = data.aws_availability_zones.available.names[index(var.public_subnet_cidrs, each.value)]
tags = {
Name = "Public-Subnet-${index(var.public_subnet_cidrs, each.value) + 1}"
}
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.this.id
tags = {
Name = "Public-RouteTable"
}
}
resource "aws_route_table_association" "public" {
for_each       = toset(tolist([for subnet in aws_subnet.public : subnet.id])) # touples --> list --> set
route_table_id = aws_route_table.public.id
subnet_id      = each.value
depends_on     = [aws_subnet.public]
}

你可以直接使用for_each = aws_subnet.public:

resource "aws_route_table_association" "public" {
for_each       = aws_subnet.public
route_table_id = aws_route_table.public.id
subnet_id      = each.value.id
}

最新更新