🚀 Chapter 2 — Automation: Thiết lập CD với SSM Agent
Tại sao lại sử dụng SSM thay vì SSH ở production?
Đại khái thì:
- SSH = CodeBuild đăng nhập vào EC2 và chạy lệnh.
- SSM = CodeBuild yêu cầu AWS Systems Manager chạy lệnh trên EC2.
➠ Vì vậy, SSH đơn giản và dễ hiểu hơn để học, còn SSM an toàn và phù hợp hơn khi triển khai production, đặc biệt khi muốn tránh mở SSH port 22 và quản lý private key.
Step 1 — Kiểm tra EC2
SSH vào EC2:
ssh -i ./chapter1-key.pem ubuntu@<EC2_PUBLIC_IP>
Kiểm tra project:
cd ./todo-list-app
docker compose ps
Đảm bảo app đang chạy.
Step 2 — Kiểm tra SSM Agent
Trên EC2:
sudo systemctl status snap.amazon-ssm-agent.amazon-ssm-agent
Nếu thấy:
Active: active (running)
thì OK.
Nếu chưa chạy:
sudo systemctl enable --now snap.amazon-ssm-agent.amazon-ssm-agent
Kiểm tra lại:
sudo systemctl status snap.amazon-ssm-agent.amazon-ssm-agent
Step 3 — Tạo IAM Role cho EC2
AWS Console:
IAM
↓
Roles
↓
Create role
Chọn:
Trusted entity type:
AWS service
Use case:
EC2
Attach policy:
AmazonSSMManagedInstanceCore
Role name:
chapter2-ec2-ssm-role
Create role.
Step 4 — Gắn Role vào EC2
AWS Console:
EC2
↓
Instances
↓
Chọn EC2 Chapter 1
↓
Actions
↓
Security
↓
Modify IAM role
Chọn:
chapter2-ec2-ssm-role
Save.
Step 5 — Kiểm tra EC2 đã xuất hiện trong Systems Manager
AWS Console:
Systems Manager
↓
Fleet Manager
↓
Managed nodes
EC2 của bạn phải xuất hiện.
Trạng thái:
Online
Nếu Online → tiếp tục.
Step 6 — Tạo IAM Role cho CodeBuild
Vào:
IAM
↓
Roles
↓
Create role
Chọn:
AWS service
↓
CodeBuild
Role name:
chapter2-codebuild-role
Ở bước này CodeBuild cần quyền để:
CodeBuild
↓
SSM
↓
EC2
Attach:
AmazonSSMFullAccess
Cho lab học tập có thể dùng policy này trước.
Sau khi hiểu flow, có thể chuyển sang IAM policy giới hạn hơn.
Step 7 — Lấy EC2 Instance ID
AWS Console:
EC2
↓
Instances
Copy:
Instance ID
Ví dụ:
i-0123456789abcdef0
Bạn sẽ dùng ID này trong CodeBuild.
Step 8 — Sửa buildspec.yml
Bây giờ buildspec sẽ có thêm bước Deploy.
Ví dụ:
version: 0.2
phases:
install:
commands:
- echo "Installing dependencies..."
build:
commands:
- echo "Running Docker build..."
- docker build -t todo-list-app .
post_build:
commands:
- echo "Deploying to EC2..."
- aws ssm send-command
--instance-ids "i-0123456789abcdef0"
--document-name "AWS-RunShellScript"
--parameters 'commands=["cd ~/todo-list-app","git pull origin main","docker compose build","docker compose up -d"]'
--comment "Deploy Todo App"
Thay:
i-0123456789abcdef0
bằng Instance ID EC2 của bạn.
Step 9 — Quan trọng: kiểm tra Git branch trên EC2
SSH vào EC2:
cd ~/todo-list-app
Kiểm tra:
git branch
Nếu EC2 đang deploy từ main:
* main
thì:
git pull origin main
là đúng.
Nếu EC2 đang dùng branch khác thì sửa lại command tương ứng.
Step 10 — Kiểm tra GitHub authentication trên EC2
Trên EC2:
cd ~/todo-list-app
git pull
Nếu pull được:
Already up to date.
hoặc pull được commit mới → OK.
Bước này quan trọng vì SSM sẽ chạy:
git pull
trên EC2.
Step 11 — Cập nhật CodeBuild project
AWS:
CodeBuild
↓
Build projects
↓
todo-list-ci
↓
Edit
Ở phần:
Environment
chọn service role:
chapter2-codebuild-role
Lưu lại.
Step 12 — Commit buildspec.yml
Trên Mac:
git add buildspec.yml
git commit -m "add EC2 deployment"
git push
Step 13 — Start Build
AWS:
CodeBuild
↓
todo-list-ci
↓
Start build
Flow bây giờ:
DOWNLOAD_SOURCE
↓
INSTALL
↓
BUILD
↓
docker build
↓
POST_BUILD
↓
SSM send-command
↓
EC2 Deploy
Step 14 — Kiểm tra CodeBuild
Trong log:
Deploying to EC2...
Sau đó CodeBuild gọi:
aws ssm send-command
Nếu thành công sẽ có:
CommandId
Ví dụ:
abc12345-....
Step 15 — Kiểm tra SSM Command
AWS Console:
Systems Manager
↓
Run Command
↓
Command history
Tìm command vừa chạy.
Chọn command.
Bạn sẽ thấy:
Status: Success
Step 16 — Kiểm tra EC2
SSH vào:
ssh -i ~/Downloads/chapter1-key.pem ubuntu@<EC2_PUBLIC_IP>
cd ~/todo-list-app
Kiểm tra commit:
git log -1
Kiểm tra container:
docker compose ps
Kết quả:
todo-list-app-app-1 Up
todo-list-app-mysql-1 Up
Step 17 — Test bằng thay đổi thật
Trên Mac sửa Todo App.
Ví dụ thay đổi một text trong source.
Sau đó:
git add .
git commit -m "update todo app"
git push
CodeBuild:
GitHub
↓
CodeBuild
↓
Docker Build
↓
SSM
↓
EC2
↓
git pull
↓
docker compose build
↓
docker compose up -d
Không cần SSH vào EC2 để deploy nữa.
Step 18 — Kiểm tra website
Mở:
http://<EC2_PUBLIC_IP>
Bạn phải thấy version mới của Todo App.
Step 19 — Hoàn thiện Automation
Sau khi manual Start build hoạt động, bật GitHub webhook.
CodeBuild:
todo-list-ci
↓
Edit
↓
Source
↓
Webhook
Bật:
Rebuild every time a code change is pushed
Sau đó test:
git add .
git commit -m "test automatic deployment"
git push
Không cần nhấn Start build.
Flow hoàn chỉnh:
git push
│
▼
┌──────────┐
│ GitHub │
└────┬─────┘
│
Webhook
│
▼
┌───────────────┐
│ CodeBuild │
└───────┬───────┘
│
Docker Build
│
▼
┌───────────────┐
│ SSM │
└───────┬───────┘
│
▼
┌─────────┐
│ EC2 │
└────┬────┘
│
docker compose build
│
docker compose up -d
│
▼
APP 🚀
Chapter 2 sau khi hoàn thành
Bạn sẽ chuyển được từ:
Chapter 2
Developer
↓
git push
↓
GitHub
↓
CodeBuild
↓
Test
↓
Docker Build
↓
SSM
↓
EC2
↓
Deploy
Điểm quan trọng: Docker image được build trong CodeBuild không phải image được deploy trực tiếp lên EC2. Ở version này, CodeBuild dùng Docker build để kiểm tra image có build được hay không, sau đó SSM yêu cầu EC2 git pull source mới và EC2 tự build lại image rồi docker compose up -d.
Đây là cách đơn giản nhất để hoàn thành Chapter 2 mà chưa cần đưa ECR vào. Sang Chapter 4, khi học Artifact/Governance, ta mới chuyển thành:
CodeBuild
↓
Docker Build
↓
ECR
↓
EC2/ECS/EKS
để thực hiện đúng tư tưởng Build once → Deploy the same artifact.
All Rights Reserved