Introduction to VPC
An logically isolated area of the Amazon Web Services (AWS) cloud where you can launch and use AWS resources can be created and managed using the AWS VPC (Amazon Virtual Private Cloud) web service offered by AWS. To put it simply, a VPC allows you to build your own private network inside the AWS cloud.
The IP address range, subnets, route tables, network gateways, and security settings of a VPC are completely under your control once you build it. With this level of control, you may design and set up the network environment to meet your individual demands and security requirements.
Subnets
Subnets in AWS VPC can be categorised as either public or private depending on how easily they can access the internet. Let's examine what distinguishes public from private subnets:
Public Subnet: An Internet Gateway (IGW) route is what makes a subnet a public subnet. A public subnet allows for instances to have public IP addresses and enable direct internet communication. This enables outbound traffic to the internet and makes them accessible from it. For resources that require direct internet connectivity, like web servers or instances hosting publicly available apps, public subnets are often used.
Private Subnet: An unconnected private subnet lacks a direct connection to the internet. To access resources on the internet, instances within a private subnet use a Network Address Translation (NAT) gateway or NAT instance because they lack public IP addresses. The fact that private subnets are inaccessible from the internet adds an extra layer of protection. They are frequently utilized for backend servers, databases, or other resources that demand internal VPC communication.
Route Tables
The traffic routing within a VPC is managed by a route table. It includes directives (routes) that describe how traffic should be routed across subnets, NAT gateways, VPN connections, and other resources.
Internet Gateway
A horizontally scalable, redundant AWS service called an Internet Gateway (IGW) enables connectivity between instances inside of your VPC and the internet. It gives internet-bound traffic a target and enables resources on public subnets to connect directly to the internet.
Security Groups
Security Groups act as virtual firewalls for your resources within a VPC. They control inbound and outbound traffic at the instance level by specifying rules that allow or deny traffic based on protocols, ports, and IP addresses.
To Explore more, visit AWS Documentation
"Secure VPC Setup with Terraform"
Terraform is an open-source Infrastructure as Code (IaC) tool that enables the automation and management of cloud infrastructure using a declarative configuration language. It allows users to define the desired state of their infrastructure and automates the process of provisioning and managing resources across various cloud providers such as AWS, Azure, and Google Cloud. With Terraform, infrastructure can be described in configuration files, making it easier to manage, version, and scale environments in a repeatable manner.
When Terraform is used to configure a Virtual Private Cloud (VPC) on AWS, it automates the creation and management of various networking components within the VPC. This includes defining the VPC itself, specifying CIDR blocks for IP address allocation, and enabling DNS support. Terraform also provisions subnets (public and private) to segregate different types of resources, such as instances requiring internet access and those that must remain isolated. Additionally, Terraform configures routing tables to manage the flow of traffic between subnets and the internet, using components like Internet Gateways (IGW) for public access and NAT Gateways for secure private subnet connectivity. It also sets up security groups to control inbound and outbound traffic for resources, ensuring proper isolation and protection. Through this automated process, Terraform ensures that the AWS environment is securely configured, scalable, and easily replicable across multiple instances or accounts.
Here's the recommended file structure for your Terraform project, organized for clarity and maintainability:
terraform-aws-vpc-setup/
├── main.tf # Main Terraform configuration file
├── variables.tf
├── outputs.tf
├── provider.tf
├── network/
│ ├── vpc.tf
│ ├── subnets.tf
│ ├── route_tables.tf
│ └──nat_gateway.tf
└── security_groups.tf
├── terraform.tfvars
└── terraform.tfstate
Explanation of Each File:
main.tf:
The entry point for your Terraform configuration. It includes calls to modular files like network/.
module "network" {
source = "./network" # References the network module
}
output "vpc_id" {
value = module.network.vpc_id
}
output "public_subnet_ids" {
value = module.network.public_subnet_ids
}
output "private_subnet_ids" {
value = module.network.private_subnet_ids
}
variables.tf:
Contains definitions of input variables (e.g., VPC CIDR block, subnet CIDR blocks, region) to make the configuration reusable.
variable "region" {
description = "AWS region for resource deployment"
type = string
default = "us-west-2"
}
variable "vpc_cidr" {
description = "CIDR block for the VPC"
type = string
default = "10.0.0.0/16"
}
variable "public_subnet_cidrs" {
description = "List of CIDR blocks for public subnets"
type = list(string)
default = ["10.0.1.0/24"]
}
variable "private_subnet_cidrs" {
description = "List of CIDR blocks for private subnets"
type = list(string)
default = ["10.0.2.0/24"]
}
outputs.tf:
Exposes useful information such as VPC ID, subnet IDs, and NAT Gateway ID after the infrastructure is created.
output "vpc_id" {
value = aws_vpc.my_vpc.id
}
output "public_subnet_ids" {
value = aws_subnet.public_subnet.*.id
}
output "private_subnet_ids" {
value = aws_subnet.private_subnet.*.id
}
provider.tf:
Specifies the provider (AWS in this case) and the region for deployment.
provider "aws" {
region = var.region
}
network/vpc.tf:
Contains the VPC configuration.
resource "aws_vpc" "my_vpc" {
cidr_block = var.vpc_cidr
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "my_vpc"
}
}
network/subnets.tf:
Defines the public and private subnets.
resource "aws_subnet" "public_subnet" {
count = length(var.public_subnet_cidrs)
vpc_id = aws_vpc.my_vpc.id
cidr_block = var.public_subnet_cidrs[count.index]
map_public_ip_on_launch = true
availability_zone = "us-west-2a"
tags = {
Name = "public_subnet_${count.index}"
}
}
resource "aws_subnet" "private_subnet" {
count = length(var.private_subnet_cidrs)
vpc_id = aws_vpc.my_vpc.id
cidr_block = var.private_subnet_cidrs[count.index]
availability_zone = "us-west-2a"
tags = {
Name = "private_subnet_${count.index}"
}
}
network/route_tables.tf:
Contains route table definitions and associations.
resource "aws_route_table" "public_route_table" {
vpc_id = aws_vpc.my_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.my_igw.id
}
tags = {
Name = "public_route_table"
}
}
resource "aws_route_table_association" "public_association" {
count = length(aws_subnet.public_subnet)
subnet_id = aws_subnet.public_subnet[count.index].id
route_table_id = aws_route_table.public_route_table.id
}
resource "aws_route_table" "private_route_table" {
vpc_id = aws_vpc.my_vpc.id
}
resource "aws_route_table_association" "private_association" {
count = length(aws_subnet.private_subnet)
subnet_id = aws_subnet.private_subnet[count.index].id
route_table_id = aws_route_table.private_route_table.id
}
network/nat_gateway.tf:
Configures the NAT Gateway and its associated Elastic IP.
resource "aws_eip" "nat_eip" {
vpc = true
}
resource "aws_nat_gateway" "my_nat_gateway" {
allocation_id = aws_eip.nat_eip.id
subnet_id = aws_subnet.public_subnet[0].id
tags = {
Name = "my_nat_gateway"
}
}
resource "aws_route" "private_route" {
route_table_id = aws_route_table.private_route_table.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.my_nat_gateway.id
}
network/security_groups.tf:
Defines the security groups for public and private resources.
resource "aws_security_group" "public_sg" {
vpc_id = aws_vpc.my_vpc.id
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "public_sg"
}
}
resource "aws_security_group" "private_sg" {
vpc_id = aws_vpc.my_vpc.id
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = []
}
tags = {
Name = "private_sg"
}
}
terraform.tfvars:
Contains actual values for the variables defined in variables.tf (e.g., CIDR blocks, region, tags).
region = "us-west-2"
vpc_cidr = "10.0.0.0/16"
public_subnet_cidrs = ["10.0.1.0/24"]
private_subnet_cidrs = ["10.0.2.0/24"]
terraform.tfstate:
Automatically generated by Terraform to track the state of the infrastructure. This file should be stored securely or in a remote backend.
-
Set Up Terraform: Execute
terraform init
to prepare the working directory containing your configuration files. This step ensures that all necessary plugins and modules are downloaded. -
Preview Changes: Use
terraform plan
to review the modifications Terraform will make. This step allows you to confirm the accuracy of the configuration before proceeding. -
Deploy Resources: Run
terraform apply
to create the infrastructure defined in the configuration. When prompted, confirm to proceed with the deployment.
Top comments (0)