Amazon VPC là gì?
VPC (Virtual Private Cloud) là mạng ảo riêng trong AWS cloud. Bạn có toàn quyền kiểm soát IP ranges, subnets, route tables và network gateways.
Các thành phần chính
| Component | Mô tả |
|---|---|
| VPC | Mạng ảo với CIDR block (VD: 10.0.0.0/16) |
| Subnet | Phân đoạn VPC (public/private) |
| Route Table | Điều hướng traffic |
| Internet Gateway | Kết nối internet |
| NAT Gateway | Internet cho private subnets |
| Security Group | Firewall ở instance level |
| NACL | Firewall ở subnet level |
VPC Module với Terraform
Cấu trúc Module
modules/vpc/
├── main.tf
├── variables.tf
├── outputs.tf
└── README.md
Main VPC Configuration
# modules/vpc/main.tf
# VPC
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${var.project_name}-vpc"
}
}
# Internet Gateway
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${var.project_name}-igw"
}
}
# Public Subnets
resource "aws_subnet" "public" {
count = length(var.availability_zones)
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.vpc_cidr, 4, count.index)
availability_zone = var.availability_zones[count.index]
map_public_ip_on_launch = true
tags = {
Name = "${var.project_name}-public-${var.availability_zones[count.index]}"
Type = "public"
}
}
# Private Subnets
resource "aws_subnet" "private" {
count = length(var.availability_zones)
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.vpc_cidr, 4, count.index + length(var.availability_zones))
availability_zone = var.availability_zones[count.index]
tags = {
Name = "${var.project_name}-private-${var.availability_zones[count.index]}"
Type = "private"
}
}
# Elastic IP for NAT Gateway
resource "aws_eip" "nat" {
count = var.enable_nat_gateway ? 1 : 0
domain = "vpc"
tags = {
Name = "${var.project_name}-nat-eip"
}
}
# NAT Gateway
resource "aws_nat_gateway" "main" {
count = var.enable_nat_gateway ? 1 : 0
allocation_id = aws_eip.nat[0].id
subnet_id = aws_subnet.public[0].id
tags = {
Name = "${var.project_name}-nat"
}
depends_on = [aws_internet_gateway.main]
}
# Public Route Table
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
tags = {
Name = "${var.project_name}-public-rt"
}
}
# Private Route Table
resource "aws_route_table" "private" {
vpc_id = aws_vpc.main.id
dynamic "route" {
for_each = var.enable_nat_gateway ? [1] : []
content {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.main[0].id
}
}
tags = {
Name = "${var.project_name}-private-rt"
}
}
# Route Table Associations - Public
resource "aws_route_table_association" "public" {
count = length(var.availability_zones)
subnet_id = aws_subnet.public[count.index].id
route_table_id = aws_route_table.public.id
}
# Route Table Associations - Private
resource "aws_route_table_association" "private" {
count = length(var.availability_zones)
subnet_id = aws_subnet.private[count.index].id
route_table_id = aws_route_table.private.id
}
Variables
# modules/vpc/variables.tf
variable "project_name" {
description = "Project name for resource naming"
type = string
}
variable "vpc_cidr" {
description = "CIDR block for VPC"
type = string
default = "10.0.0.0/16"
}
variable "availability_zones" {
description = "List of availability zones"
type = list(string)
default = ["ap-southeast-1a", "ap-southeast-1b"]
}
variable "enable_nat_gateway" {
description = "Enable NAT Gateway for private subnets"
type = bool
default = true
}
Outputs
# modules/vpc/outputs.tf
output "vpc_id" {
value = aws_vpc.main.id
}
output "vpc_cidr" {
value = aws_vpc.main.cidr_block
}
output "public_subnet_ids" {
value = aws_subnet.public[*].id
}
output "private_subnet_ids" {
value = aws_subnet.private[*].id
}
output "internet_gateway_id" {
value = aws_internet_gateway.main.id
}
output "nat_gateway_id" {
value = var.enable_nat_gateway ? aws_nat_gateway.main[0].id : null
}
Sử dụng Module
# main.tf (root module)
module "vpc" {
source = "./modules/vpc"
project_name = "myapp"
vpc_cidr = "10.0.0.0/16"
availability_zones = ["ap-southeast-1a", "ap-southeast-1b"]
enable_nat_gateway = true
}
# Tham chiếu outputs
resource "aws_instance" "web" {
subnet_id = module.vpc.public_subnet_ids[0]
# ...
}
AWS CLI Commands
# Tạo VPC
aws ec2 create-vpc \
--cidr-block 10.0.0.0/16 \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=my-vpc}]'
# Tạo Subnet
aws ec2 create-subnet \
--vpc-id vpc-xxx \
--cidr-block 10.0.1.0/24 \
--availability-zone ap-southeast-1a
# Tạo Internet Gateway
aws ec2 create-internet-gateway
aws ec2 attach-internet-gateway --vpc-id vpc-xxx --internet-gateway-id igw-xxx
# Describe VPCs
aws ec2 describe-vpcs --filters "Name=tag:Name,Values=my-vpc"
# Describe Subnets
aws ec2 describe-subnets --filters "Name=vpc-id,Values=vpc-xxx"
Network Architecture Pattern
Internet
│
┌───────▼───────┐
│ Internet GW │
└───────┬───────┘
│
┌───────────────┼───────────────┐
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│Public │ │Public │ │Public │
│Subnet-A │ │Subnet-B │ │Subnet-C │
│(ALB,NAT)│ │(ALB) │ │(ALB) │
└────┬────┘ └─────────┘ └─────────┘
│
┌────▼────┐
│ NAT GW │
└────┬────┘
│
┌────▼────┐ ┌─────────┐ ┌─────────┐
│Private │ │Private │ │Private │
│Subnet-A │ │Subnet-B │ │Subnet-C │
│(EC2,ECS)│ │(EC2,ECS)│ │(EC2,ECS)│
└─────────┘ └─────────┘ └─────────┘
Security Groups vs NACLs
| Feature | Security Group | NACL |
|---|---|---|
| Level | Instance | Subnet |
| State | Stateful | Stateless |
| Rules | Allow only | Allow + Deny |
| Evaluation | All rules | Number order |
Security Group Example
resource "aws_security_group" "alb" {
name = "${var.project_name}-alb-sg"
description = "Security group for ALB"
vpc_id = module.vpc.vpc_id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
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"]
}
}
Best Practices
- Multi-AZ - Luôn deploy across 2+ AZs
- Private subnets - Đặt databases, app servers ở private
- NAT Gateway - Cho phép private resources access internet
- VPC Flow Logs - Enable để troubleshoot và audit
- Least privilege - Security Groups chỉ mở ports cần thiết
Bài tiếp theo: IAM Identity - Quản lý access control với Terraform.