So i want to specify gateway_id to the route table but i am getting this:
Error: Missing resource instance key
on modules/vpc/main.tf line 55, in resource "aws_route_table" "RT":
55: gateway_id = aws_internet_gateway.igw.id
Because aws_internet_gateway.igw has "for_each" set, its attributes must be accessed on
specific instances.
For example, to correlate with indices of a referring resource, use:
aws_internet_gateway.igw[each.key]`
variables.tf
variable "vpc" {
type = map(object({
cidr = string
tags = map(string)
}))
default = {
"main" = {
cidr = "10.0.0.0/16"
tags = {
"Name" = "Main-Vpc"
}
}
}
}
# Subnets
variable "subnets" {
type = map(object({
cidr = string
tags = map(string)
}))
# Privates
default = {
"Private1" = {
cidr = "10.0.10.0/24"
tags = {
"Name" = "Private1"
}
}
"Private2" = {
cidr = "10.0.20.0/24"
tags = {
"Name" = "Private2"
}
}
#Publcs
"Public1" = {
cidr = "10.0.1.0/24"
tags = {
"Name" = "Public1"
}
}
"Public2" = {
cidr = "10.0.2.0/24"
tags = {
"Name" = "Public2"
}
}
}
}
# Route tables
variable "route-tables" {
type = map(object({
cidr_block = string
tags = map(string)
}))
default = {
"Public1" = {
cidr_block = "0.0.0.0/0"
tags = {
"Name" = "Public1"
}
}
"Public2" = {
cidr_block = "0.0.0.0/0"
tags = {
"Name" = "Public2"
}
}
"Private1" = {
cidr_block = "0.0.0.0/0"
tags = {
"Name" = "Private1"
}
}
"Private2" = {
cidr_block = "0.0.0.0/0"
tags = {
"Name" = "Private2"
}
}
}
}
main.tf
resource "aws_vpc" "main" {
for_each = var.vpc
cidr_block = each.value["cidr"]
tags = each.value["tags"]
}
# Creting Privates and Public
resource "aws_subnet" "subnets" {
vpc_id = aws_vpc.main["main"].id
for_each = var.subnets
cidr_block = each.value["cidr"]
tags = each.value["tags"]
depends_on = [
aws_vpc.main
]
}
# Gateways and Elastic ip
resource "aws_internet_gateway" "igw" {
for_each = aws_vpc.main
vpc_id = aws_vpc.main["main"].id
}
resource "aws_eip" "elastic" {
vpc = true
}
resource "aws_nat_gateway" "nat" {
allocation_id = aws_eip.elastic.id
subnet_id = aws_subnet.subnets["Public1"].id
tags = {
"Name" = "nat-gateway"
}
depends_on = [
aws_internet_gateway.igw
]
}
# Route tables
resource "aws_route_table" "RT" {
for_each = var.route-tables
tags = each.value["tags"]
vpc_id = aws_vpc.main["main"].id
dynamic "route" {
for_each = var.route-tables
content {
cidr_block = route.value.cidr_block
gateway_id = aws_internet_gateway.igw["main"].id
}
}
}
I am trying to get the value of created resource igw but i dont know how to do it when im using for_each . Also i'm not sure how can i debug this to check the output of the internet_gateway resource!
Edit: I'm posting my full code if needed to analyze maybe will help!
CodePudding user response:
To debug such an issue, run Terraform console
on your terminal, type aws_internet_gateway.igw
and run enter
,
it will show you how many items are created by this resource, and it will give you an idea how to reference your igw ID,
from your code I assume referencing your igw ID by gateway_id = aws_internet_gateway.igw.["main"].id
will work, but I'm not sure,
use Terrafrom console
to confirm.
UPDATE :
it worked because you didn't pass a value for the variable var.vpc
, so terraform used the default value and thus create just one vpc resource with the key 'main'
if you run terraform plan, you'll see :
aws_vpc.main["main"] will be created
resource "aws_vpc" "main" {
arn = (known after apply)
cidr_block = "10.0.0.0/16"
default_network_acl_id = (known after apply)
default_route_table_id = (known after apply)
default_security_group_id = (known after apply)
dhcp_options_id = (known after apply)
and when you did for_each = aws_vpc.main
on the igw resource, for_each
received a map of one element with a key "main", so it created just one igw resource with the same key of the vpc which is main
so we were able to reference it by aws_internet_gateway.igw.["main"].id
if you have instead multiple items on the var.vpc variable like
variable "vpcs" {
type = map(object({
cidr = string
tags = map(string)
}))
default = {
"main" = {
cidr = "10.0.0.0/16"
tags = {
"Name" = "Main-Vpc"
}
}
"boo" = {
cidr = "10.0.0.0/16"
tags = {
"Name" = "Main-Vpc"
}
}
}
}
this will create two vpcs with keys main
, boo
, and as you're using var.vpcs
as the for_each
value of the igw resource, it will create two igw with the same keys main
, and boo