🚀 Chapter 2 — Automation: Thiết lập CD với SSH
Step 1 — Tạo SSH key cho CodeBuild
Có một vấn đề:
Mac
└── chapter1-key.pem
CodeBuild không tự có file chapter1-key.pem.
Vì vậy CodeBuild cần có private key để SSH vào EC2.
Cho lab này, cách đơn giản nhất là lưu private key trong AWS Secrets Manager.
Tại sao lại cần SSH key để CodeBuild SSH vào EC2, ko còn cách nào khác để vào EC2 à?
➠ Có, và thậm chí các cách dưới đây còn bảo mật và khuyên dùng hơn việc dùng SSH Key truyền thống:
AWS Systems Manager (SSM) Run Command / Session Manager :
- CodeBuild không cần mở port SSH (22) hay giữ SSH Key.
- Chỉ cần gán quyền IAM (Role) cho CodeBuild và EC2, CodeBuild có thể ra lệnh và chạy script trực tiếp trên EC2 qua AWS API.
Dùng Username & Password:
- Vẫn là SSH nhưng dùng mật khẩu thay vì Key.
- Cách này kém bảo mật, không khuyến khích.
Step 2 — Tạo Secret
AWS Console:
Secrets Manager
↓
Store a new secret
Chọn:
Other type of secret
Tạo key:
SSH_PRIVATE_KEY
Value:
<contents of chapter1-key.pem>
Nội dung phải là toàn bộ:
-----BEGIN OPENSSH PRIVATE KEY-----
...
...
-----END OPENSSH PRIVATE KEY-----
Secret name:
chapter2/ec2-ssh-key
Create secret.
Trong lab thực tế, đây là cách an toàn hơn việc commit private key vào GitHub.
Step 6 — Lấy EC2 Public IP
AWS:
EC2
↓
Instances
Copy:
Public IPv4 address
Ví dụ:
3.112.xxx.xxx
Step 7 — Kiểm tra SSH host
Từ Mac:
ssh-keyscan -H <EC2_PUBLIC_IP>
Ví dụ:
ssh-keyscan -H 3.112.xxx.xxx
Kết quả sẽ giống:
3.112.xxx.xxx ssh-ed25519 AAAA...
Chúng ta sẽ dùng ssh-keyscan trong CodeBuild để tránh lỗi:
Host key verification failed
Step 8 — IAM Role cho CodeBuild
CodeBuild cần quyền đọc Secret.
AWS:
IAM
↓
Roles
↓
CodeBuild role
Role của project Chapter 2, ví dụ:
chapter2-codebuild-role
Thêm permission:
secretsmanager:GetSecretValue
Có thể tạo policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "arn:aws:secretsmanager:<REGION>:<ACCOUNT_ID>:secret:chapter2/ec2-ssh-key*"
}
]
}
Thay:
<REGION>
<ACCOUNT_ID>
bằng AWS account của bạn.
Step 9 — Cài SSH client trong CodeBuild
CodeBuild environment thường có SSH client, nhưng để chắc chắn chúng ta cài:
version: 0.2
phases:
install:
commands:
- apt-get update -y
- apt-get install -y openssh-client
Step 10 — Lấy SSH private key từ Secrets Manager
Trong buildspec.yml:
phases:
install:
commands:
- apt-get update -y
- apt-get install -y openssh-client
- aws secretsmanager get-secret-value --secret-id chapter2/ec2-ssh-key --query SecretString --output text > /tmp/ec2-key.pem
- chmod 400 /tmp/ec2-key.pem
Sau đó CodeBuild sẽ có:
/tmp/ec2-key.pem
Step 11 — Test SSH từ CodeBuild
Thêm:
post_build:
commands:
- ssh-keyscan -H <EC2_PUBLIC_IP> >> ~/.ssh/known_hosts
- ssh -i /tmp/ec2-key.pem ubuntu@<EC2_PUBLIC_IP> "echo SSH connection successful"
Thay:
<EC2_PUBLIC_IP>
bằng IP thật.
Ví dụ:
- ssh-keyscan -H 3.112.xxx.xxx >> ~/.ssh/known_hosts
- ssh -i /tmp/ec2-key.pem ubuntu@3.112.xxx.xxx "echo SSH connection successful"
Step 12 — Test CodeBuild
Commit:
git add buildspec.yml
git commit -m "test ssh deployment"
git push
Start CodeBuild.
Nếu thành công:
SSH connection successful
Bạn đã chứng minh:
CodeBuild
↓ SSH
EC2
Step 13 — Deploy bằng SSH
Bây giờ thay command test bằng deploy thật:
post_build:
commands:
- ssh-keyscan -H <EC2_PUBLIC_IP> >> ~/.ssh/known_hosts
- ssh -i /tmp/ec2-key.pem ubuntu@<EC2_PUBLIC_IP> "cd ~/todo-list-app && git pull origin main && docker compose build && docker compose up -d"
Flow:
CodeBuild
↓
SSH
↓
EC2
↓
cd ~/todo-list-app
↓
git pull origin main
↓
docker compose build
↓
docker compose up -d
Step 14 — buildspec.yml hoàn chỉnh
Nếu Chapter 2 của bạn đang build Docker image trước khi deploy, có thể dùng:
version: 0.2
phases:
install:
commands:
- apt-get update -y
- apt-get install -y openssh-client
- aws secretsmanager get-secret-value --secret-id chapter2/ec2-ssh-key --query SecretString --output text > /tmp/ec2-key.pem
- chmod 400 /tmp/ec2-key.pem
build:
commands:
- echo "Running Docker build..."
- docker build -t todo-list-app .
post_build:
commands:
- echo "Deploying to EC2..."
- mkdir -p ~/.ssh
- ssh-keyscan -H <EC2_PUBLIC_IP> >> ~/.ssh/known_hosts
- ssh -i /tmp/ec2-key.pem ubuntu@<EC2_PUBLIC_IP> "cd ~/todo-list-app && git pull origin main && docker compose build && docker compose up -d"
Step 15 — Test deployment
Trên Mac sửa Todo App.
Sau đó:
git add .
git commit -m "update todo app"
git push
CodeBuild chạy:
GitHub
↓
CodeBuild
↓
Docker Build
↓
SSH
↓
EC2
↓
git pull
↓
docker compose build
↓
docker compose up -d
Step 16 — Kiểm tra EC2
SSH thủ công vào EC2:
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
Sau đó mở:
http://<EC2_PUBLIC_IP>
Bạn sẽ thấy version mới.
Step 17 — Bật tự động Build + Deploy
Khi manual CodeBuild đã chạy OK, bật GitHub webhook.
GitHub
↓ git push
CodeBuild webhook
↓
Build
↓
Deploy
Lúc này bạn chỉ cần:
git add .
git commit -m "update app"
git push
Không cần:
❌ SSH vào EC2
❌ git pull
❌ docker compose build
❌ docker compose up
Chapter 2 hoàn chỉnh
Developer
↓
git push
↓
GitHub
↓
CodeBuild
├── Test
├── Docker Build
│
└── SSH
↓
EC2
↓
git pull
↓
docker compose build
↓
docker compose up
All rights reserved