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?