Overview
I am kinda confused about the concept of VPC
and subnet
when I have to set up AWS infrastructure with terrafrom. So I decide to dig keep on this concept. The blog will follow the following structure
refresher of IP address and subnet mask
go over concepts of VPC, subnet in AWS
terraform setup for RDS with VPC and subnet
IP address
Some basic knowledge of IP needs to be studied for networking
Some terms are:
IP address
: for example 10.100.122.2, it consists of 4 segments and each segment ranges from 0-255. The IP address consists of the network id and host id. Each can take up a variable amount of segments.
The reason why we divide ip address into network id and host id is that it is going to take forever to find a specific device, therefore we divide and conquer to locate the host machine:
find the subnet first identified by network id
find the host by host id
The definition is here
network id
: used to locate subnet.host id
: used to locate subnet
Then the question is how to find which portion of the IP address is network id and host id. The answer is a subnet mask.
subnet mask
: subnet mask follows right behind the ip address with/24
the maximum number for a subnet mask is 32. The value stands for the number of ones in binary.
The IP address consists of the network id and host id. To determine the host id, you can do the following operation:
convert
IP address
andsubnet mask
to binary formAND operation to obtain the host id
Check the IP calculator here to have a deeper understanding of this.
Now we have the basics to move forward to understand VPC.
Virtual Private Cloud
Virtual Private Cloud (VPC) is a secure and private cloud on a public cloud provider. It sounds like a tongue twister. VPC is just a secure network dedicated to the aws account holder, managed by AWS.
Let's consider you create a web-application with
load balancer
EC2 to host an instance of your web app
RDS to store data
You need to deploy it to two availability zone within the ca-central-1
region to improve fault tolerance.
Under ca-central-1, everything you have created, by default, will live in a VPC. The availability zone lives inside the VPC. Each availability zone hosts an instance of your web server.
Each subnet contains an instance of EC2, load balancer and RDS. Between the subset, they are free to talk to each other, even if the two subnets are not in the same availability zone. Your services are very secure now!
However, from a practical point of view, your web app lives in a VPC that blocks traffic from users. Therefore, no one can use your app.
I made the mistake when I spin up RDS for testing but without public access, since they live in a private subnet.
Lucky for us, you can control the subnet to be either private or public. The way to do this is to set up a gateway.
You typically set up an internet gateway for your load balancer so users can reach it but no one can SSH into your ec2 instance or rds.
Terraform set-up RDS
Let's set up AWS RDS with proper VPC and subnet.
Even if you don't specify VPC, one by default will be set for you.
# configured aws provider with proper credentials
provider "aws" {
region = "ca-canada-1"
profile = "terraform"
}
# create default vpc if one does not exit
resource "aws_default_vpc" "default_vpc" {
tags = {
Name = "default vpc"
}
}
# use data source to get all avalablility zones in region
data "aws_availability_zones" "available_zones" {}
# create a default subnet in the first az if one does not exit
resource "aws_default_subnet" "subnet_az1" {
availability_zone = aws_availability_zones.available_zones.names[0]
}
# create a default subnet in the second az if one does not exit
resource "aws_default_subnet" "subnet_az2" {
availability_zone = aws_availability_zones.available_zones.names[1]
}
# create security group for the web server
resource "aws_security_group" "webserver_security_group" {
name = "webserver security group"
description = "enable http access on port 80"
vpc_id = aws_default_vpc.default_vpc.id
ingress {
description = "http access"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = -1
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "webserver security group"
}
}
# create security group for the database
resource "aws_security_group" "database_security_group" {
name = "database security group"
description = "enable mysql/aurora access on port 3306"
vpc_id = aws_default_vpc.default_vpc.id
ingress {
description = "postgres"
from_port = 5432
to_port = 5432
protocol = "tcp"
# allow traffic to RDS from webserver
security_groups = [aws_security_group.webserver_security_group.id]
}
egress {
from_port = 0
to_port = 0
protocol = -1
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "database security group"
}
}
# create the subnet group for the rds instance
resource "aws_db_subnet_group" "database_subnet_group" {
name = "database-subnets"
subnet_ids = [aws_default_subnet.subnet_az1.id, aws_default_subnet.subnet_az2.id]
description = "subnets for database instance"
tags = {
Name = "database-subnets"
}
}
# create the rds instance
resource "aws_db_instance" "db_instance" {
engine = "postgres"
engine_version = "14.7"
multi_az = false
identifier = "rds-database-instance"
username = "admin"
password = "password"
instance_class = "db.t3.micro"
allocated_storage = 200
# 无限套娃,subnet放入group
db_subnet_group_name = aws_db_subnet_group.database_subnet_group.name
vpc_security_group_ids = [aws_security_group.database_security_group_id]
# spin up in one az zone, multi_az = false
availability_zone = data.aws_availability_zones.available_zones.names[0]
db_name = "applicationdb"
# when you delete rds instance, will you have a final snapshot of it?
skip_final_snapshot = false
}
Before you create a database instance, you need to
create VPC,
create AZ
create a subset within different AZ
create a web server security group to allow traffic at port 80 to interact with the user
create a database security group and connect it with the web server security group so it can talk to the database
create your database instance
Summary
In this blog, we have covered
some breakdown of IP address and its relationship with subnet mask to calculate host id and network id
graphical illustration of the concept of VPC etc
terraform implementaion of setting up RDS with granular control
Reference
-
- hidden gym for picking up those concepts