0

🚀 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

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí