Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 817
Employee Avatar asked Mar 06 '20 18:03

Employee


People also ask

How do I add a static route to AWS?

To add or remove a static route (console)Open the Amazon VPC console at https://console.aws.amazon.com/vpc/ . In the navigation pane, choose Site-to-Site VPN Connections. Select the appropriate Site-to-Site VPN connection that you want to work with. Choose Static routes, Edit routes.

What is destination and target in AWS route table?

Destination—The range of IP addresses where you want traffic to go (destination CIDR). For example, an external corporate network with the CIDR 172.16. 0.0/12 . Target—The gateway, network interface, or connection through which to send the destination traffic; for example, an internet gateway.


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

like image 156
user3246046 Avatar answered Oct 12 '22 04:10

user3246046


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"
}
}
like image 33
krishna kumar mishra Avatar answered Oct 12 '22 04:10

krishna kumar mishra