Hello Gurus, I’m creating custom vpc and using public and private subnet. all looks good as pasted below. however when I try to ping from ec2 instance in a public subnet to ec2 instance in a private subnet, it does now work. Please let me know what I’m missing.
provider “aws” {
region = “eu-west-2” # London
access_key = “My KEY”
secret_key = “MY SECRET KEY”
}
Custom VPC
resource “aws_vpc” “MyVPC” {
cidr_block = “10.0.0.0/16”
instance_tenancy = “default” # For Prod use “dedicated”
tags = {
Name = “MyVPC”
}
}
Creates “Main Route Table”, “NACL” & “default Security Group”
Create Public Subnet, Associate with our VPC, Auto assign Public IP
resource “aws_subnet” “PublicSubNet” {
vpc_id = aws_vpc.MyVPC.id # Our VPC
availability_zone = “eu-west-2a” # AZ within London, 1 Subnet = 1 AZ
cidr_block = “10.0.1.0/24” # Check using this later > “${cidrsubnet(data.aws_vpc.MyVPC.cidr_block, 4, 1)}”
map_public_ip_on_launch = “true” # Auto assign Public IP for Public Subnet
tags = {
Name = “PublicSubNet”
}
}
Create Private Subnet, Associate with our VPC
resource “aws_subnet” “PrivateSubNet” {
vpc_id = aws_vpc.MyVPC.id # Our VPC
availability_zone = “eu-west-2b” # AZ within London region, 1 Subnet = 1 AZ
cidr_block = “10.0.2.0/24” # Check using this later > “${cidrsubnet(data.aws_vpc.MyVPC.cidr_block, 4, 1)}”
tags = {
Name = “PrivateSubNet”
}
}
Only 1 IGW per VPC
resource “aws_internet_gateway” “MyIGW” {
vpc_id = aws_vpc.MyVPC.id
tags = {
Name = “MyIGW”
}
}
New Public route table, so we can keep “default main” route table as Private. Route out to MyIGW
resource “aws_route_table” “MyPublicRouteTable” {
vpc_id = aws_vpc.MyVPC.id # Our VPC
route { # Route out IPV4
cidr_block = “0.0.0.0/0” # IPV4 Route Out for all
#ipv6_cidr_block = “::/0” The parameter destinationCidrBlock cannot be used with the parameter destinationIpv6CidrBlock # IPV6 Route Out for all
gateway_id = aws_internet_gateway.MyIGW.id # Target : Internet Gateway created earlier
}
route { # Route out IPV6
ipv6_cidr_block = “::/0” # IPV6 Route Out for all
gateway_id = aws_internet_gateway.MyIGW.id # Target : Internet Gateway created earlier
}
tags = {
Name = “MyPublicRouteTable”
}
}
Associate “PublicSubNet” with the public route table created above, removes it from default main route table
resource “aws_route_table_association” “PublicSubNetnPublicRouteTable” {
subnet_id = aws_subnet.PublicSubNet.id
route_table_id = aws_route_table.MyPublicRouteTable.id
}
Create new security group “WebDMZ” for WebServer
resource “aws_security_group” “WebDMZ” {
name = “WebDMZ”
description = “Allows SSH & HTTP requests”
vpc_id = aws_vpc.MyVPC.id # Our VPC : SGs cannot span VPC
ingress {
description = “Allows SSH requests for VPC: IPV4”
from_port = 22
to_port = 22
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”] # SSH restricted to my laptop public IP /32
}
ingress {
description = “Allows HTTP requests for VPC: IPV4”
from_port = 80
to_port = 80
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”] # You can use Load Balancer
}
ingress {
description = “Allows HTTP requests for VPC: IPV6”
from_port = 80
to_port = 80
protocol = “tcp”
ipv6_cidr_blocks = ["::/0"]
}
egress {
description = “Allows SSH requests for VPC: IPV4”
from_port = 22
to_port = 22
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”] # SSH restricted to my laptop public IP /32
}
egress {
description = “Allows HTTP requests for VPC: IPV4”
from_port = 80
to_port = 80
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”]
}
egress {
description = “Allows HTTP requests for VPC: IPV6”
from_port = 80
to_port = 80
protocol = “tcp”
ipv6_cidr_blocks = ["::/0"]
}
}
Create new EC2 instance (WebServer01) in Public Subnet
Get ami id from Console
resource “aws_instance” “WebServer01” {
ami = “ami-01a6e31ac994bbc09”
instance_type = “t2.micro”
subnet_id = aws_subnet.PublicSubNet.id
key_name = “MyEC2KeyPair” # To connect using key pair
security_groups = [aws_security_group.WebDMZ.id] # Assign WebDMZ security group created above
#vpc_security_group_ids = [aws_security_group.WebDMZ.id]
tags = {
Name = “WebServer01”
}
}
Create new security group “MyDBSG” for WebServer
resource “aws_security_group” “MyDBSG” {
name = “MyDBSG”
description = “Allows Public WebServer to Communicate with Private DB Server”
vpc_id = aws_vpc.MyVPC.id # Our VPC : SGs cannot span VPC
ingress {
description = “Allows ICMP requests: IPV4” # For ping,communication, error reporting etc
from_port = -1
to_port = -1
protocol = “icmp”
cidr_blocks = [“10.0.1.0/24”] # Public Subnet CIDR block, can be “WebDMZ” security group id too as below
security_groups = [aws_security_group.WebDMZ.id] # Tried this as above was not working, but still doesn’t work
}
ingress {
description = “Allows SSH requests: IPV4” # You can SSH from WebServer01 to DBServer, using DBServer private ip address and copying private key to WebServer
from_port = 22 # ssh ec2-user@Private Ip Address -i MyPvKey.pem Private Key pasted in MyPvKey.pem
to_port = 22 # Not a good practise to use store private key on WebServer, instead use Bastion Host (Hardened Image, Secure) to connect to Private DB
protocol = “tcp”
cidr_blocks = [“10.0.1.0/24”]
}
ingress {
description = “Allows HTTP requests: IPV4”
from_port = 80
to_port = 80
protocol = “tcp”
cidr_blocks = [“10.0.1.0/24”]
}
ingress {
description = “Allows HTTPS requests : IPV4”
from_port = 443
to_port = 443
protocol = “tcp”
cidr_blocks = [“10.0.1.0/24”]
}
ingress {
description = “Allows MySQL/Aurora requests”
from_port = 3306
to_port = 3306
protocol = “tcp”
cidr_blocks = [“10.0.1.0/24”]
}
egress {
description = “Allows ICMP requests: IPV4” # For ping,communication, error reporting etc
from_port = -1
to_port = -1
protocol = “icmp”
cidr_blocks = [“10.0.1.0/24”] # Public Subnet CIDR block, can be “WebDMZ” security group id too
}
egress {
description = “Allows SSH requests: IPV4” # You can SSH from WebServer01 to DBServer, using DBServer private ip address and copying private key to WebServer
from_port = 22 # ssh ec2-user@Private Ip Address -i MyPvtKey.pem Private Key pasted in MyPvKey.pem chmod 400 MyPvtKey.pem
to_port = 22 # Not a good practise to use store private key on WebServer, instead use Bastion Host (Hardened Image, Secure) to connect to Private DB
protocol = “tcp”
cidr_blocks = [“10.0.1.0/24”]
}
egress {
description = “Allows HTTP requests: IPV4”
from_port = 80
to_port = 80
protocol = “tcp”
cidr_blocks = [“10.0.1.0/24”]
}
egress {
description = “Allows HTTPS requests : IPV4”
from_port = 443
to_port = 443
protocol = “tcp”
cidr_blocks = [“10.0.1.0/24”]
}
egress {
description = “Allows MySQL/Aurora requests”
from_port = 3306
to_port = 3306
protocol = “tcp”
cidr_blocks = [“10.0.1.0/24”]
}
}
Create new EC2 instance (DBServer) in Private Subnet, Associate “MyDBSG” Security Group
resource “aws_instance” “DBServer” {
ami = “ami-01a6e31ac994bbc09”
instance_type = “t2.micro”
subnet_id = aws_subnet.PrivateSubNet.id
key_name = “MyEC2KeyPair” # To connect using key pair
security_groups = [aws_security_group.MyDBSG.id] # THIS WAS GIVING ERROR WHEN ASSOCIATING
#vpc_security_group_ids = [aws_security_group.MyDBSG.id]
tags = {
Name = “DBServer”
}
}
Elastic IP required for NAT Gateway
resource “aws_eip” “nateip” {
vpc = true
tags = {
Name = “NATEIP”
}
}
DBServer in private subnet cannot access internet, so add “NAT Gateway” in Public Subnet
Add Target as NAT Gateway in default main route table. So there is route out to Internet.
Now you can do yum update on DBServer
resource “aws_nat_gateway” “NATGW” { # Create NAT Gateway in each AZ so in case of failure it can use other
allocation_id = aws_eip.nateip.id # Elastic IP allocation
subnet_id = aws_subnet.PublicSubNet.id # Public Subnet
tags = {
Name = “NATGW”
}
}
Main Route Table add NATGW as Target
resource “aws_default_route_table” “DefaultRouteTable” {
default_route_table_id = aws_vpc.MyVPC.default_route_table_id
route {
cidr_block = “0.0.0.0/0” # IPV4 Route Out for all
nat_gateway_id = aws_nat_gateway.NATGW.id # Target : NAT Gateway created above
}
tags = {
Name = “DefaultRouteTable”
}
}
1 post - 1 participant
Read full topic