Deploy Lên Auto Scaling Group và Deployment Config
Một instance là điểm yếu chí mạng: nó chết thì app sập. Production chạy nhiều instance sau một Auto Scaling Group (ASG) để chịu lỗi và co giãn theo tải. Deploy lên một nhóm như vậy đặt ra câu hỏi mới: cập nhật tất cả cùng lúc (nhanh nhưng gián đoạn) hay lần lượt từng máy (chậm nhưng luôn còn máy phục vụ)? Bài này deploy lên ASG và dùng deployment config để điều khiển chính xác điều đó.
💰 Chi phí
Bài này chạy ASG với 2 instance t3.micro. Nhớ terminate (xóa ASG) khi xong Part IV. Bài 11 dùng lại ASG này nên giữ tới hết bài 11.
Mục tiêu
Deploy lên ASG thay vì instance đơn lẻ, hiểu các deployment config và đánh đổi của chúng, và nắm cơ chế CodeDeploy tự deploy lên instance ASG khởi thêm sau này.
Launch template và ASG
ASG cần một launch template mô tả cách tạo mỗi instance — cùng AMI, instance type, instance profile, security group và user-data (cài agent + httpd) như bài 8, nhưng đóng thành khuôn để ASG nhân bản:
$ aws ec2 create-launch-template --launch-template-name awscicd-lt \
--launch-template-data file://lt-data.json
Rồi ASG dùng template đó, trải 2 instance trên 2 AZ:
$ aws autoscaling create-auto-scaling-group --auto-scaling-group-name awscicd-asg \
--launch-template "LaunchTemplateName=awscicd-lt,Version=1" \
--min-size 2 --max-size 2 --desired-capacity 2 \
--vpc-zone-identifier "subnet-aaa,subnet-bbb"
ASG tự khởi 2 instance; nếu một cái chết, nó thay ngay để giữ đủ desired-capacity. Chờ cả hai InService trước khi deploy.
Deployment group gắn vào ASG
Khác bài 8 (nhắm máy theo tag), giờ deployment group nhắm thẳng Auto Scaling group:
$ aws deploy create-deployment-group --application-name awscicd-demo \
--deployment-group-name awscicd-demo-asg-dg \
--service-role-arn arn:aws:iam::111122223333:role/awscicd-codedeploy-role \
--auto-scaling-groups awscicd-asg \
--deployment-config-name CodeDeployDefault.OneAtATime
Tham số --auto-scaling-groups là điểm khác biệt: CodeDeploy giờ gắn vòng đời với ASG, không chỉ với một tập máy tĩnh.
Deployment config: nhanh hay an toàn
Deployment config quy định bao nhiêu instance được cập nhật cùng lúc — đánh đổi giữa tốc độ và số máy luôn sẵn sàng phục vụ. CodeDeploy có sẵn ba cấu hình:
| Config | Cập nhật | Đánh đổi |
|---|---|---|
CodeDeployDefault.OneAtATime |
lần lượt từng máy | An toàn nhất — luôn còn (N−1) máy phục vụ; chậm nhất |
CodeDeployDefault.HalfAtATime |
một nửa số máy mỗi đợt | Cân bằng — còn 50% phục vụ |
CodeDeployDefault.AllAtOnce |
tất cả cùng lúc | Nhanh nhất — nhưng có thể gián đoạn toàn bộ |
Mỗi config thực chất khai một minimum healthy hosts (số/tỉ lệ máy phải luôn khỏe). OneAtATime nghĩa là "tối thiểu N−1 máy khỏe", nên CodeDeploy chỉ hạ một máy mỗi lần. Nếu một máy deploy fail, CodeDeploy dừng và không hạ tiếp các máy còn lại — số máy hỏng được chặn ở mức tối thiểu. Bạn cũng tạo được config tùy chỉnh với ngưỡng riêng.
Chạy deploy
$ DID=$(aws deploy create-deployment --application-name awscicd-demo \
--deployment-group-name awscicd-demo-asg-dg \
--s3-location bucket=awscicd-artifacts-...,key=revisions/awscicd-demo.zip,bundleType=zip \
--query 'deploymentId' --output text)
$ aws deploy get-deployment --deployment-id $DID \
--query 'deploymentInfo.[deploymentConfigName,status,deploymentOverview]'
[
"CodeDeployDefault.OneAtATime",
"Succeeded",
{ "Pending": 0, "InProgress": 0, "Succeeded": 2, "Failed": 0, "Skipped": 0 }
]
OneAtATime deploy máy thứ nhất xong mới sang máy thứ hai; tổng kết 2 máy Succeeded. Kiểm chứng cả hai phục vụ app:
$ # với mỗi instance trong ASG:
i-0491f5e9b43644647 -> awscicd demo app — v2
i-086fd09a5971b2da8 -> awscicd demo app — v2
Cơ chế quan trọng: deploy lên instance khởi sau
Đây là điểm khiến tích hợp ASG khác hẳn deploy theo tag. ASG có thể khởi instance mới bất cứ lúc nào — khi scale-out vì tải tăng, hay khi thay một máy chết. Một instance vừa sinh ra thì trống, chưa có app. CodeDeploy giải việc này bằng cách móc vào vòng đời ASG: mỗi khi ASG launch một instance mới vào group, CodeDeploy tự động chạy deploy revision thành công gần nhất lên đúng instance đó, trước khi nó được đưa vào phục vụ.
ASG (desired=2) ──┬── instance A ─┐
└── instance B ─┤ CodeDeploy deploy revision gần nhất
│
tải tăng → ASG launch instance C ─┘ ← CodeDeploy TỰ deploy lên C luôn
(C vào phục vụ với app đã có sẵn)
Hệ quả thực tế: bạn không bao giờ có instance "trống" nhận traffic. Đây là lý do deploy theo ASG là chuẩn cho production co giãn — cập nhật và scale-out đều giữ mọi máy ở đúng phiên bản. (Để cơ chế này chạy, instance profile phải đọc được revision từ S3 — đúng quyền ta cấp ở bài 8.)
🧹 Dọn dẹp
Bài 11 (blue/green) dùng lại ASG này, nên giữ tới hết bài 11. Khi dọn:
$ aws autoscaling delete-auto-scaling-group --auto-scaling-group-name awscicd-asg --force-delete
$ aws ec2 delete-launch-template --launch-template-name awscicd-lt
$ aws deploy delete-deployment-group --application-name awscicd-demo --deployment-group-name awscicd-demo-asg-dg
--force-delete terminate luôn các instance trong ASG. Đây là tài nguyên tốn tiền (2 EC2), đừng quên.
Tổng kết
Deploy lên ASG bắt đầu bằng launch template (khuôn tạo instance) và ASG (giữ đủ số máy, tự thay máy chết). Deployment group gắn vào ASG qua --auto-scaling-groups. Deployment config điều khiển tốc độ-an toàn: OneAtATime (an toàn nhất, từng máy), HalfAtATime, AllAtOnce (nhanh nhất, có thể gián đoạn) — thực chất là ngưỡng minimum healthy hosts, và deploy dừng khi vượt ngưỡng hỏng. Cơ chế cốt lõi: CodeDeploy tự deploy revision mới nhất lên mọi instance ASG khởi thêm về sau, nên không có máy trống nhận traffic.
Tất cả deploy tới giờ là in-place — cập nhật ngay trên máy đang chạy, có một khoảng máy đó offline. Bài tới là kiểu deploy an toàn hơn: blue/green — dựng một nhóm máy mới song song, kiểm tra, rồi chuyển traffic qua bằng load balancer, và tự rollback theo CloudWatch alarm nếu có sự cố.