Search code examples
amazon-web-servicesterraformterraform-provider-awsamazon-vpc

What's the difference between default_route_table_id and main_route_table_id?


Using Terraform and the AWS Provider, what's the difference between default_route_table_id and main_route_table_id?

I'm trying to make a public subnet that allows both ingress and egress. Googling around, I'm seeing I need an Internet Gateway and should attach the main route table to the subnets.

Attaching:

resource "aws_route_table_association" "public-association-a" {
  subnet_id      = aws_subnet.public-subnet-a.id
  route_table_id = aws_vpc.vpc.main_route_table_id
}

resource "aws_route_table_association" "public-association-b" {
  subnet_id      = aws_subnet.public-subnet-b.id
  route_table_id = aws_vpc.vpc.main_route_table_id
}

Editing the default (does default = main?) route table:

resource "aws_default_route_table" "default" {
  default_route_table_id = aws_vpc.vpc.default_route_table_id

  route = [{
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw.id
  }]
}

Something doesn't feel right about them both having different names but I see references to them both online.


Solution

  • Based on terraform docs, the default route table is a special resource:

    This is an advanced resource with special caveats. Please read this document in its entirety before using this resource. The aws_default_route_table resource behaves differently from normal resources. Terraform does not create this resource but instead attempts to "adopt" it into management. Do not use both aws_default_route_table to manage a default route table and aws_main_route_table_association with the same VPC due to possible route conflicts.

    By default, you cannot remove the route table associated with a VPC, i.e, the one which has Main field set to Yes in the AWS console:

    enter image description here

    When you create a VPC using terraform, there are two attributes exported:

    • main_route_table_id
    • default_route_table_id

    These values are the same and they give the main route table ID for a VPC. So from how I understand this, the aws_default_route_table resource allows you to work with and manipulate the main route table in such a way that cannot be done from the AWS console. If you don't want to get in trouble, I would suggest not using the aws_default_route_table resource.

    The Internet Gateway is assigned to the VPC, not subnets. If you want to avoid managing the main route table in terraform, you would need to add a route to the main route table to reference it:

    resource "aws_route" "public" {
      route_table_id         = aws_vpc.test.main_route_table_id
      destination_cidr_block = "0.0.0.0/0"
      gateway_id             = aws_internet_gateway.igw.id
    }