Quản lý cơ sở hạ tầng AWS với Terraform: Triển khai cụm VPC và mạng con an toàn
Trong kỷ nguyên của điện toán đám mây, việc quản lý cơ sở hạ tầng thông qua mã nguồn (Infrastructure as Code) đã trở thành tiêu chuẩn vàng trong ngành DevOps. Terraform, với tư cách là công cụ quản lý IaC phổ biến nhất hiện nay, cho phép các kỹ sư xây dựng, biến đổi và phiên bản hóa các tài nguyên đám mây một cách tự động. Bài viết này sẽ hướng dẫn chi tiết cách bạn thiết lập một mạng ảo (VPC) trên AWS với cấu trúc mạng con (Subnet) công cộng và riêng tư, đồng thời tích hợp các nguyên tắc bảo mật cơ bản như bảng định tuyến và nhóm bảo mật.
Chuẩn bị môi trường và cấu hình nhà cung cấp
Trước khi đi sâu vào việc tạo các tài nguyên phức tạp, bước đầu tiên và quan trọng nhất là thiết lập kết nối giữa Terraform và nhà cung cấp dịch vụ đám mây. Trong trường hợp này, chúng ta sẽ tập trung vào AWS. Bạn cần đảm bảo đã cài đặt Terraform trên máy tính của mình và đã cấu hình các biến môi trường hoặc file cấu hình để xác thực thông qua AWS CLI. Việc cấu hình nhà cung cấp (provider) trong Terraform giúp công cụ biết chính xác vùng (region) nào sẽ được sử dụng để triển khai tài nguyên, đảm bảo tính nhất quán cho toàn bộ dự án.
Bạn hãy tạo một file có tên là main.tf và bắt đầu bằng việc khai báo phiên bản Terraform cũng như cấu hình nhà cung cấp AWS. Việc này giúp loại bỏ các xung đột phiên bản và định rõ phạm vi tác động của mã nguồn.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
Sau đó, hãy thêm cấu hình provider để Terraform có thể tương tác với AWS. Lưu ý rằng thông tin về key và secret sẽ được lấy từ file ~/.aws/credentials hoặc các biến môi trường mà bạn đã cấu hình trước đó.
provider "aws" {
region = "ap-southeast-1"
}
Thiết kế VPC và mạng con (Subnet)
VPC (Virtual Private Cloud) là một mạng ảo riêng của bạn trong đám mây AWS, nơi bạn có thể khởi tạo các tài nguyên của mình trong một môi trường có thể cấu hình được. Để đảm bảo tính an toàn và khả năng mở rộng, một kiến trúc VPC tiêu chuẩn thường bao gồm ít nhất hai mạng con công cộng (Public Subnets) và hai mạng con riêng tư (Private Subnets) được phân bổ trên các vùng khả dụng (Availability Zones) khác nhau. Việc phân tán này giúp hệ thống của bạn có khả năng chịu lỗi cao hơn: nếu một vùng khả dụng gặp sự cố, các vùng khác vẫn hoạt động bình thường.
Bắt đầu bằng việc tạo VPC với dải địa chỉ IP CIDR là 10.0.0.0/16. Đây là dải địa chỉ riêng nội bộ rất phổ biến. Sau khi có VPC, chúng ta sẽ tạo các mạng con. Mạng con công cộng thường được dùng để chứa các cổng truyền tải (Internet Gateway) hoặc cân bằng tải, trong khi mạng con riêng tư sẽ chứa các máy chủ ứng dụng hoặc cơ sở dữ liệu không tiếp xúc trực tiếp với Internet.
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "my-dev-vpc"
}
}
Tiếp theo, để đơn giản hóa quy trình tạo nhiều mạng con, chúng ta có thể sử dụng tài nguyên aws_subnet và lặp lại nó thông qua tham số for_each. Điều này giúp mã nguồn gọn gàng và dễ bảo trì hơn là viết thủ công từng tài nguyên mạng con. Chúng ta sẽ chia dải IP của VPC thành các dải nhỏ hơn cho Public và Private.
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnets("10.0.0.0/16", 4, 4, 4, 4)[count.index]
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "public-subnet-${count.index + 1}"
Type = "public"
}
}
resource "aws_subnet" "private" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnets("10.0.0.0/16", 4, 4, 4, 4)[count.index + 4]
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = {
Name = "private-subnet-${count.index + 1}"
Type = "private"
}
}
Cấu hình định tuyến và kết nối Internet
Việc tạo ra các mạng con công cộng và riêng tư sẽ không có ý nghĩa nếu chúng không được kết nối đúng cách. Để mạng con công cộng có thể truy cập ra Internet, chúng ta cần tạo một cổng Internet Gateway (Internet Gateway) và gắn nó vào VPC. Tuy nhiên, chỉ gắn gateway là chưa đủ, bạn cần phải thiết lập bảng định tuyến (Route Table) để hướng lưu lượng từ mạng con công cộng đến gateway này.
Đối với các mạng con riêng tư, chúng thường không cần truy cập trực tiếp ra Internet. Trong một kiến trúc phức tạp hơn, bạn có thể sử dụng NAT Gateway để cho phép các máy trong mạng con riêng tư tải bản cập nhật phần mềm từ Internet mà không bị lộ địa chỉ IP công cộng. Tuy nhiên, trong ví dụ cơ bản này, chúng ta sẽ tập trung vào việc đảm bảo mạng con công cộng hoạt động thông suốt. Bạn cần tạo một bảng định tuyến cho mạng con công cộng, thêm một route mặc định (0.0.0.0/0) trỏ đến Internet Gateway.
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "my-dev-igw"
}
}
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 = "public-route-table"
}
}
resource "aws_route_table_association" "public" {
count = 2
subnet_id = aws_subnet.public[count.index].id
route_table_id = aws_route_table.public.id
}
Triển khai và kiểm thử cơ sở hạ tầng
Sau khi hoàn thành việc viết mã nguồn trong file main.tf, bước tiếp theo là khởi tạo trạng thái làm việc (state) của Terraform. Lệnh terraform init sẽ tải các plugin nhà cung cấp cần thiết từ thư viện của HashiCorp và lưu chúng trong thư mục cục bộ. Đây là bước tiên quyết trước khi bạn có thể xem trước hoặc áp dụng bất kỳ thay đổi nào.
terraform init
Để tránh những sai lầm bất ngờ, bạn nên luôn thực hiện lệnh terraform plan trước khi triển khai. Lệnh này sẽ phân tích các thay đổi so với trạng thái hiện tại và hiển thị cho bạn biết Terraform dự định tạo mới (Create), thay đổi (Modify) hay xóa bỏ (Destroy) tài nguyên nào. Hãy đọc kỹ kết quả của lệnh plan để đảm bảo logic mạng và các dải IP CIDR không bị xung đột với các tài nguyên có sẵn trên tài khoản AWS của bạn.
terraform plan
Nếu mọi thứ trong bản kế hoạch đều chính xác, bạn có thể tiến hành lệnh apply để Terraform bắt đầu tạo các tài nguyên trên AWS. Quá trình này có thể mất từ 1 đến 5 phút tùy thuộc vào tốc độ mạng và số lượng tài nguyên. Khi hoàn tất, Terraform sẽ xuất ra các ID của các tài nguyên đã tạo, ví dụ như ID của VPC, các Subnet, hay Internet Gateway. Những thông tin này có thể được sử dụng cho các bước triển khai tiếp theo như tạo EC2 instance.
terraform apply
Khi cơ sở hạ tầng không còn cần thiết nữa, hoặc khi bạn muốn dọn dẹp để tránh phát sinh chi phí, hãy sử dụng lệnh terraform destroy. Lệnh này sẽ xóa bỏ tất cả các tài nguyên mà Terraform đã quản lý trong file cấu hình hiện tại. Đây là một tính năng mạnh mẽ giúp bạn dễ dàng quản lý vòng đời của dự án mà không lo lắng về việc bị bỏ sót tài nguyên "câm lặng" gây tốn kém trên hóa đơn hàng tháng.
terraform destroy
Kết luận
Việc sử dụng Terraform để quản lý cơ sở hạ tầng AWS không chỉ giúp tự động hóa quy trình triển khai mà còn mang lại tính minh bạch và khả năng kiểm soát phiên bản cho cấu hình mạng của bạn. Bằng cách định nghĩa VPC, Subnet, Route Table và Internet Gateway dưới dạng mã nguồn, bạn có thể sao chép cấu trúc này sang nhiều môi trường khác nhau (Development, Staging, Production) một cách nhanh chóng và đáng tin cậy. Hãy nhớ luôn tuân thủ các nguyên tắc bảo mật, chẳng hạn như chỉ mở các cổng cần thiết trong Security Group và đặt các tài nguyên quan trọng như cơ sở dữ liệu trong các mạng con riêng tư, để đảm bảo hệ thống của bạn vừa mạnh mẽ vừa an toàn trước các mối đe dọa từ Internet.