How do i fix Route table error using terraform aws - amazon-web-services

I need help with the following error on Terraform, when i ran terraform apply, everything seemed to have worked when I checked aws console but then I get the following error at the end:
Error: error reading Main Route Table Association (subnet-09b6d028942d15d8e): empty result
│
│ with aws_main_route_table_association.a,
│ on main.tf line 55, in resource "aws_main_route_table_association" "a":
│ 55: resource "aws_main_route_table_association" "a"{
The below is the code for the route table portion
#3. create custom route table
resource "aws_route_table" "prod-route-table" {
vpc_id = aws_vpc.prod-vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
}
route {
ipv6_cidr_block = "::/0"
gateway_id = aws_internet_gateway.gw.id
}
tags = {
Name = "Prod"
}
}
This is the associate subnet with route table
#5. associate subnet with route table
resource "aws_main_route_table_association" "a"{
vpc_id = aws_subnet.subnet-1.id
route_table_id = aws_route_table.prod-route-table.id
}
This is the subnet portion
#4. create a subnet
resource "aws_subnet" "subnet-1" {
vpc_id = aws_vpc.prod-vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
tags = {
Name = "Prod-subnet"
}
}
Your help will be kindly appreciated. What am i doing wrong?
Thank you.

egress_only_gateway_id applies to only aws_egress_only_internet_gateway, not to aws_internet_gateway. So you have to create aws_egress_only_internet_gateway.

You're setting the attribute egress_only_gateway_id to an internet gateway resource, while it must be using an egress internet gateway resource [1].
References:
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/egress_only_internet_gateway

Related

The "count" object can only be used in "module", "resource", and "data" blocks, and only when the "count" argument is set

I'm trying to deploy a subnet to each of 3 availability zones in AWS. I have my public subnet resource block have a count of 3 to deploy 3 subnets, one to each az
resource "aws_subnet" "public_subnet" {
count = length(var.azs)
vpc_id = aws_vpc.vpc.id
cidr_block = var.public_cidrs[count.index]
availability_zone = var.azs[count.index]
map_public_ip_on_launch = true
tags = {
Name = "${var.name}-public-subnet"
}
}
That worked fine, now I'm trying to deploy a nat gateway to each subnet and that's where I'm having issues. Here's my nat gateway resource block
resource "aws_nat_gateway" "nat_gateway" {
allocation_id = aws_eip.nat_eip.id
subnet_id = aws_subnet.public_subnet[count.index].id
tags = {
Name = "${var.name}-NAT-gateway"
}
It's giving me this error
│ Error: Reference to "count" in non-counted context
│
│ on main.tf line 48, in resource "aws_nat_gateway" "nat_gateway":
│ 48: subnet_id = aws_subnet.public_subnet[count.index].id
│
│ The "count" object can only be used in "module", "resource", and "data" blocks, and only when the "count"
│ argument is set.
I know that this error is occurring because I don't have a count argument in my NAT gateway resource block, but on Terraforms docs, I can't use count as an argument for NAT gateways. So how exactly do I accomplish what I'm trying to do? I want 3 NAT gateways, one in each subnet and I can't figure out how to achieve that
You can create NAT for each subnest as follows:
resource "aws_nat_gateway" "nat_gateway" {
count = length(aws_subnet.public_subnet)
allocation_id = aws_eip.nat_eip.id
subnet_id = aws_subnet.public_subnet[count.index].id
tags = {
Name = "${var.name}-NAT-gateway"
}
You will have problem with EIP, as you can't reuse the same EIP for three different NATs. But this is an issue for a new question.

Terraform error: error creating route: InvalidEgressOnlyInternetGatewayId.Malformed

I started a new chapter in my life, and this world of IaC (Infrastructure as code) is really amazing...
I saw a free course in YouTube, how to start working with Terraform in AWS, but something along the way is not working properly, although the code seems the as in the videos, and mine.
here is the code, and the result.
I'll be grateful for your assistance in understanding what is wrong.
Terraform details:
Terraform v0.14.10
provider registry.terraform.io/hashicorp/aws v3.36.0
The code:
3. Create Custom Route Table
resource "aws_route_table" "prod-route-table" {
vpc_id = aws_vpc.prod-vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
}
route {
ipv6_cidr_block = "::/0"
egress_only_gateway_id = aws_internet_gateway.gw.id
}
tags = {
Name = "example"
}
}
4. Create a Subnet
resource "aws_subnet" "subnet_1" {
vpc_id = aws_vpc.prod-vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1e"
tags = {
"name" = "Prod-subnet"
}
}
5. Assosicate subent with Route Table
resource "aws_route_table_association" "a" {
subnet_id = aws_subnet.subnet_1.id
route_table_id = aws_route_table.prod-route-table.id
}
The error:
Error: error creating route: InvalidEgressOnlyInternetGatewayId.Malformed: Invalid id: "igw-07f6dac9f8bd89fd5" (expecting "eigw-...")
status code: 400, request id: 7f7e2445-f537-4113-a52e-ac6b32dee888
on main.tf line 26, in resource "aws_route_table" "prod-route-table":
26: resource "aws_route_table" "prod-route-table" {
I added only the part of the code that the error is pointing me too.
You don't show the code for how you create the aws_internet_gateway.gw resource but the issue is that this resource is a normal Internet Gateway but you are passing the value to the egress_only_gateway_id field under which is expecting an ID for an egress only internet gateway.
The solution would be to either update the aws_internet_gateway resource to be an aws_egress_only_internet_gateway resource or to update the route property to be gateway_id which expects a normal Internet gateway ID and not an egress only gateway.
If you are just starting out with this stuff, I would avoid egress only internet gateways for now.

how to refer to resources created with for_each in terraform

This is what I'm trying to do. I have 3 NAT gateways deployed into separate AZs. I am now trying to create 1 route table for my private subnets pointing to the NAT gateway. In terraform I have created the NAT Gateways using for_each. I am now trying to associate these NAT gateways with a private route table and getting an error because I created the NAT gateways using for_each. Essentially, I am trying to refer to resources created with for_each in a resource that I do not need to use "for_each." Below is the code and error message. Any advice would be appreciated.
resource "aws_route_table" "nat" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.main[each.key].id
}
tags = {
Name = "${var.vpc_tags}_PrivRT"
}
}
resource "aws_eip" "main" {
for_each = aws_subnet.public
vpc = true
lifecycle {
create_before_destroy = true
}
}
resource "aws_nat_gateway" "main" {
for_each = aws_subnet.public
subnet_id = each.value.id
allocation_id = aws_eip.main[each.key].id
}
resource "aws_subnet" "public" {
for_each = var.pub_subnet
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, each.value)
availability_zone = each.key
map_public_ip_on_launch = true
tags = {
Name = "PubSub-${each.key}"
}
}
Error
Error: Reference to "each" in context without for_each
on vpc.tf line 89, in resource "aws_route_table" "nat":
89: nat_gateway_id = aws_nat_gateway.main[each.key].id
The "each" object can be used only in "resource" blocks, and only when the
"for_each" argument is set.
The problem is that you are referencing each.key in the nat_gateway_id property of the "aws_route_table" "nat" resource without a for_each anywhere in that resource or sub-block.
Add a for_each to that resource and that should do the trick:
Here is some sample code (untested):
resource "aws_route_table" "nat" {
for_each = var.pub_subnet
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.main[each.key].id
}
}

Terraform error creating subnet dependency

I'm trying to get a documentdb cluster up and running and have it running from within a private subnet I have created.
Running the config below without the depends_on i get the following error message as the subnet hasn't been created:
Error: error creating DocDB cluster: DBSubnetGroupNotFoundFault: DB subnet group 'subnet-0b97a3f5bf6db758f' does not exist.
status code: 404, request id: 59b75d23-50a4-42f9-99a3-367af58e6e16
Added the depends on setup to wait for the subnet to be created but are running into an issue.
cluster_identifier = "my-docdb-cluster"
engine = "docdb"
master_username = "myusername"
master_password = "mypassword"
backup_retention_period = 5
preferred_backup_window = "07:00-09:00"
skip_final_snapshot = true
apply_immediately = true
db_subnet_group_name = aws_subnet.eu-west-3a-private
depends_on = [aws_subnet.eu-west-3a-private]
}
On running terraform apply I an getting an error on the config:
Error: error creating DocDB cluster: DBSubnetGroupNotFoundFault: DB subnet group 'subnet-0b97a3f5bf6db758f' does not exist.
status code: 404, request id: 8b992d86-eb7f-427e-8f69-d05cc13d5b2d
on main.tf line 230, in resource "aws_docdb_cluster" "docdb":
230: resource "aws_docdb_cluster" "docdb"
A DB subnet group is a logical resource in itself that tells AWS where it may schedule a database instance in a VPC. It is not referring to the subnets directly which is what you're trying to do there.
To create a DB subnet group you should use the aws_db_subnet_group resource. You then refer to it by name directly when creating database instances or clusters.
A basic example would look like this:
resource "aws_vpc" "example" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "eu-west-3a" {
vpc_id = aws_vpc.example.id
availability_zone = "a"
cidr_block = "10.0.1.0/24"
tags = {
AZ = "a"
}
}
resource "aws_subnet" "eu-west-3b" {
vpc_id = aws_vpc.example.id
availability_zone = "b"
cidr_block = "10.0.2.0/24"
tags = {
AZ = "b"
}
}
resource "aws_db_subnet_group" "example" {
name = "main"
subnet_ids = [
aws_subnet.eu-west-3a.id,
aws_subnet.eu-west-3b.id
]
tags = {
Name = "My DB subnet group"
}
}
resource "aws_db_instance" "example" {
allocated_storage = 20
storage_type = "gp2"
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t2.micro"
name = "mydb"
username = "foo"
password = "foobarbaz"
parameter_group_name = "default.mysql5.7"
db_subnet_group_name = aws_db_subnet_group.example.name
}
The same thing applies to Elasticache subnet groups which use the aws_elasticache_subnet_group resource.
It's also worth noting that adding depends_on to a resource that already references the dependent resource via interpolation does nothing. The depends_on meta parameter is for resources that don't expose a parameter that would provide this dependency information directly only.
It seems value in parameter is wrong. db_subnet_group_name created somewhere else gives the output id/arn. So u need to use id value. although depends_on clause looks okie.
db_subnet_group_name = aws_db_subnet_group.eu-west-3a-private.id
So that would be correct/You can try to use arn in place of id.
Thanks,
Ashish

terraform aws - how to add default route to vpc default route table?

When you create an AWS VPC in terraform, it will be assigned a default route table that will route traffic just within the CIDR block of the VPC.
I want to add a default route to this to send all other traffic to the Internet.
This can be done by using the aws_route to add the default route to the existing VPC route table. For example:
resource "aws_vpc" "vpc" {
cidr_block = "${var.classb}.0.0/16"
}
resource "aws_intenet_gateway" "ig" {
vpc_id = "${aws_vpc.vpc.id}"
}
resource "aws_route" "simulation_default_route" {
route_table_id = "${aws_vpc.vpc.default_route_table_id}"
destination_cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.ig.id}"
}
This should also work if you prefer to use route table way.
resource "aws_default_route_table" "rtb-default" {
default_route_table_id = aws_vpc.main.default_route_table_id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.ngw-main.id
}
}