0

🚀 Chapter 2 — Automation: Phần B — 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.

1. Kiến trúc ở chương này

image.png

Một số câu hỏi bạn sẽ thắc mắc ở kiến trúc trên:

  • Tại sao lại có Docker Build trước khi vào EC2?
  • SSM làm những gì?
  • Ưu nhược điểm của kiến trúc trên?

Tôi sẽ trả lời ở cuối chương này!

2. Chuẩn bị tài nguyên

Lấy những gì đã setup ở Chapter 2 — Automation: Phần A — Thiết lập CD với AWS CodeBuild + SSH làm cơ sở.

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

Tại sao lại cần tạo IAM Role cho EC2?

  • Để SSM Agent chạy bên trong EC2 có thể "báo danh" và nhận lệnh từ dịch vụ AWS Systems Manager, EC2 cần được cấp quyền qua IAM Role.
  • Có thể dùng IAM User thay cho IAM Role, nhưng sẽ có rủi ro lộ Access Key

AWS Console:

IAM
 ↓
Roles
 ↓
Create role

Chọn:

Trusted entity type:
AWS service

Use case:

EC2

Attach Inline Policy (JSON):

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"codestar-connections:GetConnectionToken",
				"codestar-connections:GetConnection",
				"codeconnections:GetConnectionToken",
				"codeconnections:GetConnection",
				"codeconnections:UseConnection"
			],
			"Resource": "*"
		},
        {
            "Sid": "AllowSSMSendCommand",
            "Effect": "Allow",
            "Action": [
                "ssm:SendCommand",
                "ssm:GetCommandInvocation",
                "ssm:ListCommandInvocations",
                "ssm:ListCommands"
            ],
            "Resource": "*"
        }
	]
}

Thiết lập 2 quyền là đọc truy cập Github và SSM

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 như ảnh:

Screenshot 2026-09-17 at 12.25.00.png

Nếu Online → tiếp tục.


3. Thực hiện sửa đổi workflow

Step 6 — Tạo IAM Role cho CodeBuild

Vào:

IAM
 ↓
Roles
 ↓
Create role

Chọn:

AWS service
 ↓
CodeBuild

Role name:

chapter2-codebuild-role-ssm

Ở 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

Hãy tạm thời tắt webhook để test codebuild thủ công

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 thủ công

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ó: Screenshot 2026-09-17 at 16.45.48.png


Step 15 — Kiểm tra SSM Command

AWS Console:

Systems Manager
 ↓
Run Command
 ↓
Command history

Bạn sẽ thấy:

Screenshot 2026-09-17 at 16.46.28.png


Step 16 — Kiểm tra EC2

SSH vào:

ssh -i ./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

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.


4. Thiết lập auto deploy

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.

Chapter 2 sau khi hoàn thành

image.png

Điểm quan trọng:

Tại sao lại có Docker Build trước khi vào EC2?

  • Ở version này, CodeBuild dùng Docker build để kiểm tra image có build được hay không
  • Docker image được build trong CodeBuild không phải image được deploy trực tiếp lên EC2.

SSM làm những gì?

  • SSM đóng vai trò là cầu nối thực thi lệnh từ xa an toàn giữa CodeBuild và EC2
  • Thực thi trên EC2 qua SSM Agent

Ưu điểm của kiến trúc trên?

  • Bảo mật cao hơn SSH

Nhược điểm của kiến trúc trên?

  • Lãng phí tài nguyên & thời gian khi build image 2 lần (Thực ra bỏ lần build đầu đi cũng được, nhưng lúc đó tôi nghĩ nên thêm 1 bước kiểm tra tính đúng đắn của docker image nên đã thêm vào)
  • Phụ thuộc vào EC2 Environment

Đâ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

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í