AWS cơ bản: Region, IAM và các dịch vụ chính
1. Tổng quan
Bài này giúp bạn nắm nhanh ba trụ cột quan trọng nhất khi mới làm quen AWS: region (chọn hạ tầng đặt ở đâu), IAM (ai được làm gì) và các dịch vụ chính (EC2, S3, RDS, Lambda, VPC…). Đọc xong, bạn sẽ hiểu cách tổ chức tài khoản AWS an toàn, biết cách tạo IAM role cho ứng dụng, và viết được đoạn code Java gọi S3 qua AWS SDK v2.
2. Region và Availability Zone
AWS chia hạ tầng thành các region (khu vực địa lý, ví dụ ap-southeast-1 ở Singapore) và mỗi region có nhiều Availability Zone (AZ) — các data center độc lập về điện, mạng, nằm gần nhau để latency thấp nhưng vẫn cách ly lỗi (fault isolation).
aws ec2 describe-availability-zones --region ap-southeast-1
Lệnh trên liệt kê các AZ trong region Singapore. Kết quả thường có dạng:
ZoneName: ap-southeast-1a
ZoneName: ap-southeast-1b
ZoneName: ap-southeast-1c
Khi thiết kế hệ thống, bạn nên triển khai ít nhất 2 AZ để chịu lỗi (high availability). Ví dụ một Auto Scaling Group hay một RDS Multi-AZ instance đều dựa trên nguyên tắc này.
Lưu ý: Một số dịch vụ là global (không gắn với region cụ thể) như IAM, Route 53, CloudFront. Phần lớn dịch vụ còn lại (EC2, S3, RDS…) là regional, dữ liệu không tự động replicate sang region khác trừ khi bạn cấu hình.
2.1. Chọn region thế nào
Ba tiêu chí chính: latency (gần người dùng), compliance (yêu cầu dữ liệu lưu trong nước), và chi phí (giá dịch vụ khác nhau giữa các region). Với người dùng Việt Nam, ap-southeast-1 (Singapore) thường là lựa chọn mặc định vì độ trễ thấp và đầy đủ dịch vụ.
3. IAM: User, Group, Role, Policy
IAM (Identity and Access Management) kiểm soát ai được truy cập tài nguyên nào. Bốn khái niệm cốt lõi:
- User: một định danh cụ thể (người hoặc service) có credentials riêng.
- Group: tập hợp user, gắn policy chung cho tiện quản lý.
- Role: tập quyền tạm thời, không gắn credentials cố định — dùng cho EC2, Lambda, hoặc cross-account access.
- Policy: tài liệu JSON mô tả quyền (allow/deny) trên hành động và tài nguyên.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::order-invoices-bucket/*"
}
]
}
Policy này cho phép đọc/ghi object trong bucket order-invoices-bucket. Gắn policy vào một role rồi attach role đó cho EC2 instance hoặc Lambda function chạy service InvoiceStorageService — ứng dụng sẽ tự động có quyền mà không cần hard-code access key/secret key.
aws iam create-role \
--role-name InvoiceServiceRole \
--assume-role-policy-document file://trust-policy.json
aws iam attach-role-policy \
--role-name InvoiceServiceRole \
--policy-arn arn:aws:iam::123456789012:policy/InvoiceBucketAccess
Lệnh đầu tạo role với trust-policy.json xác định ai được “assume” role này (ví dụ EC2 service). Lệnh thứ hai gắn policy quyền cụ thể vào role.
Lưu ý: Không bao giờ nhúng access key/secret key trực tiếp vào code hoặc commit lên Git. Dùng IAM Role (cho tài nguyên chạy trên AWS) hoặc IAM Identity Center/SSO (cho người dùng).
3.1. Nguyên tắc least privilege
Chỉ cấp đúng quyền cần thiết, không dùng policy AdministratorAccess cho service account. Ví dụ một Lambda chỉ cần đọc một bucket thì không nên cấp s3:* trên toàn bộ tài khoản.
{
"Effect": "Deny",
"Action": "s3:DeleteBucket",
"Resource": "*"
}
Statement Deny luôn được ưu tiên hơn Allow khi có xung đột — đây là cách thêm “lưới an toàn” chống xóa nhầm bucket quan trọng.
4. Các dịch vụ chính
4.1. Compute
- EC2: máy ảo thuê theo giờ/giây, bạn tự quản lý OS.
- Lambda: chạy code theo sự kiện (event-driven), không quản lý server, tính phí theo số lần gọi và thời gian chạy.
- ECS/EKS: chạy container (Docker) có orchestration.
aws lambda invoke \
--function-name CalculateOrderTotal \
--payload '{"orderId":"ORD-1001"}' \
response.json
Lệnh này gọi function CalculateOrderTotal với payload JSON, kết quả trả về được ghi vào response.json.
4.2. Storage
- S3: object storage, lưu file bất kỳ (ảnh, log, backup), có độ bền 99.999999999%.
- EBS: ổ đĩa block gắn với EC2.
- EFS: file system chia sẻ được nhiều EC2 cùng mount.
4.3. Database
- RDS: database quan hệ quản lý (MySQL, PostgreSQL…), tự động backup, patching.
- DynamoDB: NoSQL, scale ngang tự động, latency một chữ số mili giây.
4.4. Network
- VPC: mạng riêng ảo, bạn định nghĩa subnet, route table, security group.
- Security Group: tường lửa stateful ở mức instance.
Resources:
OrderServiceSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTPS inbound
VpcId: vpc-0123456789abcdef0
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Đoạn CloudFormation này tạo một Security Group tên OrderServiceSG, chỉ mở port 443 (HTTPS) cho mọi IP — inbound rule còn lại mặc định bị deny.
5. Gọi S3 từ ứng dụng Java
Phần này minh họa cách một service Spring Boot upload file lên S3 bằng AWS SDK for Java v2.
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>2.25.16</version>
</dependency>
public class InvoiceStorageService {
private final S3Client s3Client;
private final String bucketName;
public InvoiceStorageService(S3Client s3Client, String bucketName) {
this.s3Client = s3Client;
this.bucketName = bucketName;
}
public void uploadInvoice(String orderId, byte[] content) {
PutObjectRequest request = PutObjectRequest.builder()
.bucket(bucketName)
.key("invoices/" + orderId + ".pdf")
.build();
s3Client.putObject(request, RequestBody.fromBytes(content));
}
}
S3Client được tiêm vào qua constructor (lấy credentials tự động từ IAM Role nếu chạy trên EC2/Lambda, không cần hard-code). Method uploadInvoice tạo PutObjectRequest với key là đường dẫn object trong bucket, rồi gọi putObject để đẩy nội dung lên S3.
Cấu hình bean S3Client:
@Bean
public S3Client s3Client() {
return S3Client.builder()
.region(Region.AP_SOUTHEAST_1)
.build();
}
Không cần truyền credentialsProvider tường minh — SDK tự dùng Default Credentials Provider Chain: tìm theo thứ tự biến môi trường, file ~/.aws/credentials, rồi IAM Role gắn với EC2/ECS/Lambda.
5.1. Test với mock S3Client
@Test
void shouldCallPutObjectWithCorrectKey() {
S3Client mockS3 = mock(S3Client.class);
InvoiceStorageService service = new InvoiceStorageService(mockS3, "order-invoices-bucket");
service.uploadInvoice("ORD-1001", "nội dung hóa đơn".getBytes());
ArgumentCaptor<PutObjectRequest> captor = ArgumentCaptor.forClass(PutObjectRequest.class);
verify(mockS3).putObject(captor.capture(), any(RequestBody.class));
assertThat(captor.getValue().bucket()).isEqualTo("order-invoices-bucket");
assertThat(captor.getValue().key()).isEqualTo("invoices/ORD-1001.pdf");
}
Test mock S3Client (dùng Mockito) để không gọi AWS thật khi chạy CI. ArgumentCaptor bắt lấy PutObjectRequest thực tế được gửi, rồi AssertJ kiểm tra bucket và key đúng như kỳ vọng — đảm bảo logic build request không bị sai mà không tốn chi phí network.
Lưu ý: Muốn test tích hợp thật với S3, dùng thư viện LocalStack hoặc Testcontainers thay vì gọi bucket thật trên production — tránh phát sinh chi phí và rủi ro dữ liệu.
6. Lỗi thường gặp
- Để bucket S3 public ngoài ý muốn: luôn bật “Block Public Access” ở cấp account trừ khi thực sự cần bucket public (ví dụ static website).
- Gắn policy quá rộng (
"Action": "*", "Resource": "*") cho role test rồi quên gỡ khi lên production. - Không bật MFA cho root account: root account có toàn quyền, mất quyền truy cập root là rủi ro nghiêm trọng nhất.
- Hard-code access key trong code: nên dùng IAM Role, Secrets Manager, hoặc biến môi trường qua CI/CD secret.
- Chọn region sai dẫn tới latency cao cho người dùng cuối, hoặc vi phạm yêu cầu lưu trữ dữ liệu nội địa.
7. Kết luận
Region giúp bạn chọn đúng vị trí hạ tầng cân bằng giữa latency, chi phí và tuân thủ. IAM là lớp bảo vệ đầu tiên và quan trọng nhất — luôn áp dụng least privilege và ưu tiên Role thay vì access key tĩnh. Nắm được bộ dịch vụ cốt lõi (EC2, S3, RDS, Lambda, VPC) cùng cách tích hợp qua AWS SDK là nền tảng đủ để bạn bắt đầu triển khai một hệ thống thực tế trên AWS.