-
Notifications
You must be signed in to change notification settings - Fork 0
Terraform Tutorial
Phần 1: Variables (Input của module)
hcl variable "environment" { type = string # Kiểu dữ liệu: text }
variable "vpc_cidr" {
type = string
default = "10.0.0.0/16" # Dải IP cho VPC (65,536 IPs)
}
variable "availability_zones" {
type = list(string) # Kiểu: danh sách text
default = ["ap-southeast-1a", "ap-southeast-1b"] # 2 datacenter ở Singapore
}
Giải thích CIDR: • 10.0.0.0/16 = 10.0.0.0 → 10.0.255.255 (65,536 IPs) • /16 càng nhỏ → càng nhiều IP
──────────────────────────────────────────
Phần 2: VPC + Internet Gateway
hcl # Tạo VPC resource "aws_vpc" "main" { cidr_block = var.vpc_cidr # Dải IP enable_dns_hostnames = true # Cho phép DNS names enable_dns_support = true # Bật DNS
tags = {
Name = "mapvibe-vpc-${var.environment}" # Tên hiển thị trên Console
}
}
# Internet Gateway - "Cổng ra Internet"
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id # Gắn vào VPC ở trên
# aws_vpc.main.id = Reference đến resource đã tạo
}
Reference giữa resources:
aws_vpc.main.id
↑ ↑ ↑
loại tên thuộc tính
──────────────────────────────────────────
Phần 3: Subnets (count = tạo nhiều cái)
hcl resource "aws_subnet" "public" { count = length(var.availability_zones) # = 2 → Tạo 2 subnets
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.vpc_cidr, 8, count.index)
# ↑ Hàm tự tính CIDR con
# 10.0.0.0/16, 8, 0 → 10.0.0.0/24
# 10.0.0.0/16, 8, 1 → 10.0.1.0/24
availability_zone = var.availability_zones[count.index]
# count.index = 0, 1, 2...
}
count pattern:
• count = 2 → Terraform tạo 2 resources giống nhau
• count.index = 0, 1, 2... (index của mỗi resource)
• Truy cập: aws_subnet.public[0], aws_subnet.public[1]
──────────────────────────────────────────
Phần 4: NAT Gateway
hcl # Elastic IP (IP tĩnh) resource "aws_eip" "nat" { domain = "vpc" depends_on = [aws_internet_gateway.main] # Chờ IGW tạo xong }
# NAT Gateway
resource "aws_nat_gateway" "main" {
allocation_id = aws_eip.nat.id # Gắn IP tĩnh
subnet_id = aws_subnet.public[0].id # Đặt trong public subnet
}
depends_on là gì?
• Bắt Terraform chờ resource khác tạo xong trước
• Thường Terraform tự biết, nhưng đôi khi cần chỉ rõ
──────────────────────────────────────────
Phần 5: Route Tables
hcl # Public Route: Internet → qua Internet Gateway resource "aws_route_table" "public" { route { cidr_block = "0.0.0.0/0" # Mọi traffic gateway_id = aws_internet_gateway.main.id # → đi qua IGW } }
# Private Route: Internet → qua NAT Gateway
resource "aws_route_table" "private" {
route {
cidr_block = "0.0.0.0/0" # Mọi traffic
nat_gateway_id = aws_nat_gateway.main.id # → đi qua NAT
}
}
Tại sao Private cần NAT? • Lambda trong Private Subnet muốn gọi API bên ngoài • Không có NAT → Lambda không ra được Internet • NAT cho phép ra ngoài, nhưng bên ngoài không vào được
──────────────────────────────────────────
Phần 6: Outputs
hcl output "vpc_id" { value = aws_vpc.main.id # Trả về ID của VPC }
output "private_subnet_ids" {
value = aws_subnet.private[*].id # [*] = lấy tất cả
# → ["subnet-123", "subnet-456"]
}
[] là gì?* (Splat expression)
• Lấy thuộc tính của TẤT CẢ resources trong list
• aws_subnet.private[*].id = IDs của mọi private subnets
──────────────────────────────────────────
- Các "bẫy" thường gặp
Bẫy │ Hậu quả │ Cách tránh
------------------------+-----------------------------------------+----------------------------------
Xóa terraform.tfstate │ Terraform quên hết đã tạo gì │ Backup state, dùng remote backend
Sửa resource name │ Terraform xóa cũ, tạo mới │ Dùng terraform state mv
Quên depends_on │ Resource tạo trước khi dependency ready │ Thêm depends_on nếu cần
NAT Gateway tốn tiền │ ~$32/tháng │ Tắt khi dev không dùng
──────────────────────────────────────────
- Key Takeaway
**VPC = Mạng riêng, chia thành Public (ra Internet trực tiếp) và Private (ra qua NAT). RDS và Lambda nằm trong Private để bảo mật.**