Mục tiêu học tập
- Nắm chuỗi Developer Tools (CodeBuild/CodeDeploy/CodePipeline) và vai trò CodeConnections với Git provider bên ngoài
- Phân biệt các deployment strategy (rolling, blue/green, canary) theo trade-off
- Biết pattern multi-account pipeline và IaC selection ở mức Professional
Tổng quan CI/CD
AWS Developer Tools
1. Source control: GitHub/GitLab/Bitbucket qua CodeConnections
Deprecation note (quan trọng cho đề 2026): AWS CodeCommit ngừng nhận khách hàng mới từ 25/07/2024. AWS khuyến nghị dùng GitHub, GitLab hoặc Bitbucket kết nối vào CodePipeline/CodeBuild qua AWS CodeConnections (tên cũ: CodeStar Connections). Scenario "new workload cần Git repo" trên đề hiện hành sẽ KHÔNG lấy CodeCommit làm đáp án — tương tự cặp SMS → MGN trong Common Traps.
2. AWS CodeBuild
buildspec.yml Example:
version: 0.2
phases:
install:
runtime-versions:
nodejs: 18
pre_build:
commands:
- npm install
build:
commands:
- npm run build
- npm test
post_build:
commands:
- echo "Build completed"
artifacts:
files:
- '**/*'
base-directory: dist
cache:
paths:
- node_modules/**/*
3. AWS CodeDeploy
appspec.yml (EC2):
version: 0.0
os: linux
files:
- source: /
destination: /var/www/html
hooks:
BeforeInstall:
- location: scripts/before_install.sh
AfterInstall:
- location: scripts/after_install.sh
ApplicationStart:
- location: scripts/start.sh
ValidateService:
- location: scripts/validate.sh
4. AWS CodePipeline
Deployment Strategies Deep Dive
1. Rolling Deployment
2. Blue/Green Deployment
3. Canary Deployment
Infrastructure as Code
AWS CloudFormation
AWS CDK (Cloud Development Kit)
Terraform on AWS
CodeGuru
CodeGuru Reviewer
CodeGuru Profiler
Exam Scenarios
Scenario 1: Zero-Downtime Deployment
Scenario 2: Multi-Account Pipeline
Scenario 3: Container CI/CD
Quick Reference
CloudFormation Custom Resources & Resource Import
Custom Resources — chạy logic CloudFormation không hỗ trợ
Khi stack cần làm việc mà CloudFormation không có resource type tương ứng, dùng Custom Resource: một resource "ảo" mà lifecycle (Create/Update/Delete) được xử lý bởi code của bạn — Lambda-backed (phổ biến nhất) hoặc SNS-backed (gửi event tới topic, thường cho hệ thống on-premises/bên ngoài xử lý).
Cơ chế:
- Template khai báo
Custom::<Tên>với thuộc tính bắt buộcServiceTokentrỏ tới Lambda ARN (hoặc SNS topic ARN). - Khi stack Create/Update/Delete, CFN invoke Lambda với event chứa
RequestType(Create/Update/Delete),ResourceProperties, vàResponseURL— một pre-signed S3 URL. - Lambda PHẢI gửi response (SUCCESS/FAILED) về
ResponseURL— dùng modulecfn-response(có sẵn khi viết inline code) hoặc thư việncrhelper. Quên gửi response = stack treo ởCREATE_IN_PROGRESS/DELETE_IN_PROGRESScho tới timeout (mặc định có thể vài giờ) — lỗi kinh điển.
Use case kinh điển trên đề:
- Empty S3 bucket trước khi delete stack — CFN không xoá được bucket còn object; custom resource nhận event
Delete→ xoá hết object (kể cả version) → bucket xoá được. (Từ 2023AWS::S3::Bucketkhông có thuộc tính auto-empty; custom resource vẫn là đáp án chuẩn.) - Gọi API bên thứ ba trong lúc provision (đăng ký license, tạo record ở SaaS, lookup AMI ID mới nhất...).
- Provision resource CFN chưa hỗ trợ (service mới, tính năng mới chưa có resource type).
Snippet YAML (Lambda-backed, empty bucket on delete):
Resources:
MyBucket:
Type: AWS::S3::Bucket
EmptyBucketOnDelete:
Type: Custom::EmptyBucket
Properties:
ServiceToken: !GetAtt EmptyBucketFunction.Arn # Lambda ARN — bắt buộc
BucketName: !Ref MyBucket
# Trong Lambda handler (rút gọn)
import cfnresponse
def handler(event, context):
if event['RequestType'] == 'Delete':
empty_bucket(event['ResourceProperties']['BucketName'])
cfnresponse.send(event, context, cfnresponse.SUCCESS, {}) # BẮT BUỘC
Lưu ý Professional: với nhu cầu tái sử dụng nhiều account/nhiều team, cân nhắc nâng cấp custom resource thành CloudFormation Registry private resource type / hook — nhưng khi đề chỉ hỏi "one-off logic trong stack", custom resource là đáp án gọn nhất.
Resource Import — đưa resource tạo thủ công vào stack
Vấn đề: hạ tầng legacy tạo tay (console/CLI) nằm ngoài IaC — muốn quản lý bằng CloudFormation mà không tạo lại (không downtime, không đổi ARN).
Giải pháp: Resource Import (cloudformation import, console: Stack actions → Import resources into stack):
- Template phải mô tả resource với identifier thực tế (vd BucketName) và mọi resource được import BẮT BUỘC có
DeletionPolicy(thườngRetain) — đây là điều kiện cứng của import operation. - Resource type phải hỗ trợ import (đa số resource phổ biến đều hỗ trợ).
- Import vào stack mới hoặc stack đang có đều được; import không thay đổi resource — chỉ gắn vào stack.
- Best practice sau import: chạy Drift Detection ngay để xác nhận template khớp 100% cấu hình thực tế — template viết tay dễ thiếu thuộc tính, drift detection lộ ra chênh lệch trước khi update stack gây thay đổi ngoài ý muốn.
Use case: chuẩn hoá hạ tầng legacy vào IaC theo lộ trình (governance, review qua change set) mà không cần migration/tạo lại resource.
Exam keywords
| Keyword trên đề | Đáp án |
|---|---|
| "Delete stack fails because S3 bucket is not empty" | Lambda-backed custom resource empty bucket khi nhận event Delete |
| "Provision resource/call API CloudFormation doesn't support" | Custom resource (ServiceToken → Lambda/SNS) |
| "Bring existing resources under CloudFormation management without recreating" | Resource Import (+ DeletionPolicy bắt buộc, drift detection sau import) |
| "Stack stuck in CREATE_IN_PROGRESS with custom resource" | Lambda quên gửi cfn-response về pre-signed URL |
EC2 Image Builder
Bài toán: tổ chức cần golden image (AMI/container image đã hardened, cài sẵn agent, patch mới nhất) build lại định kỳ và phân phối cho nhiều region, nhiều account — làm tay bằng Packer/script + Lambda + EventBridge là nhiều moving part. EC2 Image Builder là managed service làm trọn pipeline này.
Thành phần chính:
- Components: bước build (cài software, hardening, patch) và test (validate image trước khi distribute) — viết bằng YAML document, AWS có sẵn nhiều managed component (vd
update-linux, STIG hardening, Inspector test). - Image recipe (AMI) / container recipe (Docker image cho ECR): base image + danh sách components + version.
- Infrastructure configuration: instance type, subnet, IAM instance profile dùng để build/test.
- Distribution configuration: copy AMI sang nhiều region, share cross-account (launch permission cho account/OU, hoặc qua AWS RAM / AWS Organizations), gắn license configuration, output alias ECR cho container.
- Pipeline + schedule: chạy theo cron (vd hàng tháng khi có patch) hoặc khi dependency có bản mới (semantic versioning trên base image/component) — golden image luôn mới mà không cần chạm tay.
Điểm Professional cần nhớ:
- Build instance cần Systems Manager Agent — Image Builder điều khiển build qua SSM (base image AWS đã có sẵn SSM Agent; Image Builder tự cài nếu thiếu).
- Miễn phí — chỉ trả tiền tài nguyên bên dưới (EC2 build instance, EBS, S3 log, data transfer/copy AMI).
- Build cả AMI và container image (output ECR).
- Kết hợp: pipeline output AMI mới → EventBridge/SNS notification → update Launch Template version cho ASG, hoặc dùng làm base cho CodePipeline.
Exam keyword: "automate golden AMI creation and distribution across accounts/regions with least operational overhead" → EC2 Image Builder (KHÔNG phải tự viết Packer + Lambda + Step Functions — nhiều operational overhead hơn); "monthly patched AMI shared to all accounts in the organization" → Image Builder pipeline schedule hàng tháng + distribution configuration share qua Organizations/RAM.
Câu hỏi ôn tập
-
Vì sao "new workload cần Git repo" trên đề 2026 không chọn CodeCommit?
Xem đáp án
CodeCommit đóng với khách hàng mới từ 25/07/2024 — account chưa từng dùng không tạo repo được. Đáp án hiện hành: GitHub/GitLab/Bitbucket + AWS CodeConnections (tên cũ CodeStar Connections) làm source stage cho CodePipeline — connection quản lý bằng IAM, không lưu credentials trong pipeline. CodeCommit chỉ còn hợp lệ cho khách hàng hiện hữu (legacy). Cùng dạng bẫy "deprecated service" như SMS → MGN.
-
Blue/Green khác Canary ở trade-off nào?
Xem đáp án
Blue/Green: chuyển 100% traffic một lần sau khi test Green — rollback tức thì (switch ngược), nhưng tốn gấp đôi infrastructure trong lúc deploy và lỗi (nếu lọt qua test) ảnh hưởng toàn bộ user. Canary: đưa 10% traffic vào version mới, monitor rồi tăng dần — phát hiện lỗi sớm với blast radius nhỏ, nhưng cần routing + monitoring phức tạp hơn và deploy lâu hơn. Lambda dùng canary/linear qua alias traffic shifting; ECS blue/green qua CodeDeploy + ALB.
-
Multi-account pipeline (dev → staging → prod) cần những mảnh ghép nào?
Xem đáp án
(1) CodePipeline ở account trung tâm (tooling/shared services), (2) cross-account IAM roles cho deploy action assume vào từng account đích, (3) artifact bucket + KMS key cho phép account đích đọc (bucket policy + key policy), (4) manual approval gate trước prod, (5) CloudFormation StackSets nếu deploy hạ tầng chuẩn hoá nhiều account. Bẫy hay gặp: quên grant KMS key cross-account → deploy fail dù role đúng.
-
CodeDeploy hỗ trợ những compute target nào và chiến lược tương ứng?
Xem đáp án
(1) EC2/on-premises: in-place (theo deployment config: OneAtATime, HalfAtATime, AllAtOnce) hoặc blue/green với ASG mới; hooks trong appspec.yml. (2) ECS: blue/green qua ALB target groups (task set mới, test listener, switch). (3) Lambda: canary (10% rồi 100%) hoặc linear (10% mỗi X phút) qua alias — kèm alarms + hooks (
BeforeAllowTraffic/AfterAllowTraffic) để auto-rollback. Chọn theo compute của đề bài — không có "CodeDeploy cho S3 static site" (đó là pipeline + S3 deploy action). -
Delete stack fail vì S3 bucket còn object — giải quyết thế nào bằng CloudFormation? Nếu muốn đưa một bucket tạo tay vào stack thì sao?
Xem đáp án
Bucket not empty: CloudFormation không xoá được bucket còn object → dùng Lambda-backed custom resource (
Custom::EmptyBucketvớiServiceTokentrỏ Lambda ARN); Lambda nhận eventDelete, xoá hết object (kể cả version) rồi bắt buộc gửi response (cfn-response) về pre-signed S3 URL — quên gửi = stack treo tới timeout. Bucket tạo tay: dùng Resource Import (cloudformation import) — template mô tả bucket đúng cấu hình thực tế và phải cóDeletionPolicy; import không tạo lại/không đổi resource, sau import chạy drift detection để xác nhận template khớp thực tế. -
Yêu cầu "golden AMI patch hàng tháng, phân phối mọi region và mọi account trong Organization, least operational overhead" — chọn gì và vì sao không tự dựng?
Xem đáp án
EC2 Image Builder: pipeline managed build → test → distribute; image recipe (base image + build/test components), schedule cron hàng tháng (hoặc trigger khi base image có version mới), distribution configuration copy AMI multi-region + share cross-account qua AWS RAM/Organizations. Build qua SSM Agent, service miễn phí (chỉ trả EC2/EBS/S3 lúc build). Tự dựng Packer + Lambda + EventBridge + script copy/share AMI cũng ra kết quả nhưng nhiều operational overhead hơn — sai keyword của đề. Image Builder cũng build được container image ra ECR.
Bài tập thực hành
-
Pipeline GitHub → CodeBuild → S3: tạo CodeConnections connection tới GitHub repo cá nhân, dựng CodePipeline 3 stage (Source → Build → Deploy S3 static site); push commit và xem pipeline tự chạy.
-
Lambda canary deployment: deploy Lambda có alias
live, cấu hình CodeDeployCanary10Percent5Minuteskèm CloudWatch alarm error rate; deploy version lỗi có chủ đích và quan sát auto-rollback. -
Blue/Green ECS: với service ECS từ bài tuần 5, tạo CodeDeploy application blue/green qua ALB 2 target groups; deploy image mới và thử rollback thủ công trước khi hết thời gian chờ terminate.
Tài liệu tham khảo chính thức
- AWS CodePipeline User Guide
- AWS CodeBuild User Guide
- AWS CodeDeploy User Guide
- AWS CloudFormation User Guide
- CloudFormation Custom Resources
- Import existing resources into a CloudFormation stack
- EC2 Image Builder User Guide
Tiếp theo: Cost Management