Terraform "Route target is not supported" when creating a AWS route table to make a subnet publicly accessible

Viewed 4167

Using terraform v0.12.21 and the AWS provider v2.51.0, I'm trying to create some infrastructure from scratch (no previous terraform state).

The goal is to have some publicly-accessible EC2 instances in a single VPC, and I think these are the resources I'd need to accomplish that:

  • VPC
  • Internet gateway in the VPC
  • Subnet in the VPC
  • Route table in the VPC to connect the subnet to the internet gateway
  • Route table association to connect the subnet to the route table
  • A security group in the VPC, which will be set for the instances
  • Multiple EC2 instances

Using this terraform config:

locals {
  office_cidr = ["x.x.x.x/32", "x.x.x.x/32"]
}

provider "aws" {
  region  = var.region
  version = "~> 2.51"
}

resource "aws_vpc" "main" {
  cidr_block       = "10.0.0.0/16"
  instance_tenancy = "default"
}

resource "aws_internet_gateway" "gw" {
  vpc_id = aws_vpc.main.id
}

resource "aws_subnet" "main" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.1.0/24"
}

resource "aws_route_table" "r" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = aws_subnet.main.cidr_block
    gateway_id = aws_internet_gateway.gw.id
  }
}

resource "aws_route_table_association" "a" {
  subnet_id      = aws_subnet.main.id
  route_table_id = aws_route_table.r.id
}


resource "aws_security_group" "allow_http" {
  name        = "security group"
  vpc_id      = aws_vpc.main.id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = local.office_cidr
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = local.office_cidr
  }

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = local.office_cidr
  }
}

resource "aws_instance" "a" {
  ami                         = "ami-xxxxxxxxxxxxxxxxx"
  instance_type               = "t2.micro"
  vpc_security_group_ids      = ["${aws_security_group.allow_http.id}"]
  subnet_id                   = aws_subnet.main.id
  associate_public_ip_address = true
}
resource "aws_instance" "b" {
  ami                         = "ami-xxxxxxxxxxxxxxxxx"
  instance_type               = "t2.micro"
  vpc_security_group_ids      = ["${aws_security_group.allow_http.id}"]
  subnet_id                   = aws_subnet.main.id
  associate_public_ip_address = true
}

When I plan it everything seems OK (only showing the aws_route_table part of the plan output here):

# aws_route_table.r will be created


 + resource "aws_route_table" "r" {
      + id               = (known after apply)
      + owner_id         = (known after apply)
      + propagating_vgws = (known after apply)
      + route            = [
          + {
              + cidr_block                = "10.0.1.0/24"
              + egress_only_gateway_id    = ""
              + gateway_id                = (known after apply)
              + instance_id               = ""
              + ipv6_cidr_block           = ""
              + nat_gateway_id            = ""
              + network_interface_id      = ""
              + transit_gateway_id        = ""
              + vpc_peering_connection_id = ""
            },
        ]
      + vpc_id           = (known after apply)
    }

The aws_subnet.main.cidr_block input for the cidr_block in the route interpolates to "10.0.1.0/24".

But when I apply I get this error:

Error: Error creating route: InvalidParameterValue: Route target is not supported. This route only supports interface and instance targets.
status code: 400, request id: a303e768-69e2-4af0-88d4-e97ebcaeae5d

  on main.tf line 38, in resource "aws_route_table" "r":
  38: resource "aws_route_table" "r" {

By "interface target" is it referring to a network interface? If so, is a network interface automatically created when the VPC is created, or should I be creating a aws_network_interface resource as well and connect the internet gateway to that instead?

Basically, I'd like to know the best practice for creating instances on a subnet which need to have public IP addresses and be publicly accessible, whether any of my resources are not needed, and if I am missing any resources that would typically be included.

But for the purposes of this question: how should I change the aws_route_table resource block, and any other resource blocks, to resolve this error and make it so that my instances can be publicly-accessible?

2 Answers

If in the route you use internet gateway gateway_id = aws_internet_gateway.gw.id, for such route cidr_block must be 0.0.0.0/0 but not aws_subnet.main.cidr_block

change cidr_block to use "0.0.0.0/0" instead of "10.0.1.0/24" work for me. like this :

resource "aws_route_table" "prod-rt" {
vpc_id = aws_vpc.prod-vpc.id

route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.prod-gw.id
}

route {
ipv6_cidr_block        = "::/0"
gateway_id = aws_internet_gateway.prod-gw.id
}

tags = {
Name = "prod-rt"
}
}
Related