0

🚀 Chapter 3 — Scale: Phần D — Reusable Workflow + Matrix

Ở Chapter 3B, chúng ta đã giải quyết vấn đề copy-paste bằng Reusable Workflow.

Hiện tại architecture:

frontend ──────────────┐
cartservice ───────────┤
productcatalogservice ─┼──→ reusable-ci-cd.yml
checkoutservice ───────┘
                              ↓
                         Build + Deploy
                              ↓
                             EC2

Nhưng vẫn còn một vấn đề.

Chúng ta vẫn phải tạo:

frontend.yml
cartservice.yml
productcatalogservice.yml
checkoutservice.yml

Nếu Online Boutique có:

4 services
   ↓
10 services
   ↓
20 services
   ↓
50 services

thì số lượng caller workflow vẫn tăng.

Chapter 3C sẽ tiếp tục tối ưu:

4 caller workflows
        ↓
1 workflow
        ↓
Matrix
        ↓
Reusable Workflow

1. Mục tiêu

scale-ci-cd.yml
       ↓
     Matrix
       ↓
 ┌─────┼─────┬──────────┐
 ↓     ↓     ↓          ↓
front  cart  product    checkout
  \     |      |          /
   \    |      |         /
        ↓
reusable-ci-cd.yml
        ↓
       EC2

Mục tiêu:

Một workflow có thể chạy CI/CD cho nhiều service bằng Matrix.


2. Kiểm tra trạng thái từ Chapter 3B

Trên local:

cd online-boutique-cicd

Kiểm tra:

git status

Sau đó:

find .github/workflows -type f

Bạn sẽ thấy:

.github/workflows/reusable-ci-cd.yml
.github/workflows/frontend.yml
.github/workflows/cartservice.yml
.github/workflows/productcatalogservice.yml
.github/workflows/checkoutservice.yml

Đây chính là trạng thái cuối của Chapter 3B.


3. Kiểm tra Reusable Workflow

Mở:

cat .github/workflows/reusable-ci-cd.yml

Bạn cần có cấu trúc tương tự:

name: Reusable CI/CD

on:
  workflow_call:
    inputs:
      service:
        required: true
        type: string

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Build Docker image
        run: |
          docker build \
            -t online-boutique-${{ inputs.service }} \
            src/${{ inputs.service }}

      - name: Deploy to EC2
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ubuntu
          key: ${{ secrets.EC2_SSH_KEY }}
          script: |
            cd ~/online-boutique
            git pull origin main
            docker compose build ${{ inputs.service }}
            docker compose up -d ${{ inputs.service }}

Ở đây:

workflow_call:

cho phép workflow này được workflow khác gọi.

Và:

inputs:
  service:

cho phép truyền service vào reusable workflow.


4. Xóa 4 caller workflow cũ

Chapter 3B có:

frontend.yml
cartservice.yml
productcatalogservice.yml
checkoutservice.yml

Bây giờ chúng ta không cần nữa.

Xóa:

rm .github/workflows/frontend.yml
rm .github/workflows/cartservice.yml
rm .github/workflows/productcatalogservice.yml
rm .github/workflows/checkoutservice.yml

Kiểm tra:

find .github/workflows -type f

Kết quả:

.github/workflows/reusable-ci-cd.yml

5. Tạo Matrix Workflow

Tạo file:

touch .github/workflows/scale-ci-cd.yml

Mở:

nano .github/workflows/scale-ci-cd.yml

Thêm:

name: Scale CI/CD

on:
  push:
    branches:
      - main
    paths:
      - "src/**"
      - ".github/workflows/**"

jobs:
  deploy:
    strategy:
      matrix:
        service:
          - frontend
          - cartservice
          - productcatalogservice
          - checkoutservice

    uses: ./.github/workflows/reusable-ci-cd.yml

    with:
      service: ${{ matrix.service }}

    secrets: inherit

Lưu file.


6. Hiểu Matrix

Phần quan trọng nhất:

strategy:
  matrix:
    service:
      - frontend
      - cartservice
      - productcatalogservice
      - checkoutservice

GitHub Actions sẽ tạo nhiều job từ một job definition.

Thay vì viết:

frontend
cartservice
productcatalogservice
checkoutservice

thành 4 workflow riêng, Matrix tạo chúng từ một danh sách.

GitHub gọi đây là matrix strategy. Một matrix có thể tạo nhiều job dựa trên các giá trị được khai báo trong matrix.


7. Kiểm tra toàn bộ workflow

Chạy:

cat .github/workflows/scale-ci-cd.yml

Bạn phải thấy:

name: Scale CI/CD

on:
  push:
    branches:
      - main
    paths:
      - "src/**"
      - ".github/workflows/**"

jobs:
  deploy:
    strategy:
      matrix:
        service:
          - frontend
          - cartservice
          - productcatalogservice
          - checkoutservice

    uses: ./.github/workflows/reusable-ci-cd.yml

    with:
      service: ${{ matrix.service }}

    secrets: inherit

8. Kiểm tra cấu trúc

Chạy:

find .github/workflows -type f

Kết quả:

.github/workflows/reusable-ci-cd.yml
.github/workflows/scale-ci-cd.yml

Đây là thay đổi quan trọng.

Trước — Chapter 3B

.github/workflows/

├── reusable-ci-cd.yml
├── frontend.yml
├── cartservice.yml
├── productcatalogservice.yml
└── checkoutservice.yml

Sau — Chapter 3C

.github/workflows/

├── reusable-ci-cd.yml
└── scale-ci-cd.yml

9. Kiểm tra Git diff

Chạy:

git status

Sau đó:

git diff -- .github/workflows

Bạn sẽ thấy:

DELETE frontend.yml
DELETE cartservice.yml
DELETE productcatalogservice.yml
DELETE checkoutservice.yml

ADD scale-ci-cd.yml

Reusable workflow:

reusable-ci-cd.yml

không cần thay đổi.


10. Commit

Chạy:

git add .github/workflows

Commit:

git commit -m "scale ci cd with matrix"

Push:

git push origin main

11. Kiểm tra GitHub Actions

Mở:

GitHub
→ Repository
→ Actions
→ Scale CI/CD

Bạn sẽ thấy một workflow run.

Trong workflow sẽ có nhiều job:

Scale CI/CD
│
├── deploy (frontend)
│
├── deploy (cartservice)
│
├── deploy (productcatalogservice)
│
└── deploy (checkoutservice)

Thay vì:

Frontend CI/CD
Cartservice CI/CD
Product Catalog CI/CD
Checkoutservice CI/CD

chúng ta chỉ còn:

Scale CI/CD

12. Kiểm tra Matrix thực tế

Trong GitHub Actions mở:

Scale CI/CD

Bạn sẽ thấy:

deploy (frontend)
deploy (cartservice)
deploy (productcatalogservice)
deploy (checkoutservice)

Mỗi job nhận một giá trị:

matrix.service

Ví dụ job frontend:

matrix.service = frontend

Job cart:

matrix.service = cartservice

Job product catalog:

matrix.service = productcatalogservice

Job checkout:

matrix.service = checkoutservice

13. Matrix gọi Reusable Workflow

Flow thực tế lúc này là:

                    GitHub
                       │
                       ↓
                scale-ci-cd.yml
                       │
                 Matrix Strategy
                       │
        ┌──────────────┼──────────────┐
        ↓              ↓              ↓
    frontend       cartservice     productcatalog
        │              │              │
        └──────────────┼──────────────┘
                       ↓
              reusable-ci-cd.yml
                       ↓
               Docker Build
                       ↓
                  SSH to EC2
                       ↓
              docker compose build
                       ↓
              docker compose up

Đây là điểm quan trọng nhất của Chapter 3C.

Chúng ta đang kết hợp:

Reusable Workflow
        +
Matrix
        ↓
Scalable CI/CD

14. Test bằng Frontend

Sửa một file:

echo "Chapter 3C" >> src/frontend/README.md

Commit:

git add .
git commit -m "test matrix frontend"
git push origin main

GitHub Actions sẽ chạy:

Scale CI/CD
    ↓
Matrix
    ↓
frontend
cartservice
productcatalogservice
checkoutservice

Ở phiên bản đầu tiên này, cả 4 service đều chạy.


15. Test bằng Product Catalog

Sửa product:

nano src/productcatalogservice/products/products.json

Thay đổi một tên sản phẩm.

Ví dụ:

Vintage Camera

thành:

Vintage Camera - Chapter 3C

Commit:

git add .
git commit -m "test matrix product catalog"
git push origin main

GitHub Actions chạy Matrix.

Sau khi deploy xong:

Browser
   ↓
Online Boutique
   ↓
Product Catalog

Refresh trang để kiểm tra thay đổi.


16. Kiểm tra EC2

SSH:

ssh -i ./chapter3-key.pem ubuntu@<EC2_PUBLIC_IP>

Đi tới project:

cd ~/online-boutique

Kiểm tra:

docker compose ps

Kiểm tra các service:

docker ps | grep frontend
docker ps | grep cartservice
docker ps | grep productcatalogservice
docker ps | grep checkoutservice

Các container cần ở trạng thái:

Up

17. Thử thêm service mới

Đây mới là phần thể hiện Scale.

Online Boutique hiện có nhiều microservice, bao gồm:

frontend
cartservice
productcatalogservice
currencyservice
paymentservice
shippingservice
emailservice
checkoutservice
recommendationservice
adservice

Repo chính thức của Google Online Boutique hiện có các service này và mỗi service sử dụng công nghệ khác nhau như Go, C#, Node.js, Python và Java.

Ví dụ chúng ta muốn thêm:

paymentservice

Mở:

nano .github/workflows/scale-ci-cd.yml

Thêm:

matrix:
  service:
    - frontend
    - cartservice
    - productcatalogservice
    - checkoutservice
    - paymentservice

Không cần tạo:

paymentservice.yml

Không cần copy:

reusable-ci-cd.yml

Chỉ cần thêm:

paymentservice

vào Matrix.


18. Test thêm Payment Service

Commit:

git add .github/workflows/scale-ci-cd.yml
git commit -m "add paymentservice to matrix"
git push origin main

GitHub Actions bây giờ tạo:

Scale CI/CD
│
├── frontend
├── cartservice
├── productcatalogservice
├── checkoutservice
└── paymentservice

19. So sánh 3A → 3B → 3C

Chapter 3A

frontend
   ↓
frontend-ci-cd.yml

cartservice
   ↓
cartservice-ci-cd.yml

productcatalog
   ↓
productcatalog-ci-cd.yml

checkout
   ↓
checkout-ci-cd.yml

Vấn đề:

Copy / Paste
      ↓
Pipeline Drift

Chapter 3B

frontend ──────────┐
cartservice ───────┤
productcatalog ────┼──→ reusable-ci-cd.yml
checkout ──────────┘

Giải quyết:

Duplicate CI/CD logic
          ↓
Reusable Workflow

Nhưng vẫn có:

4 caller workflows

Chapter 3C

                 scale-ci-cd.yml
                       │
                    Matrix
                       │
        ┌──────────────┼──────────────┐
        ↓              ↓              ↓
    frontend         cart        productcatalog
        │              │              │
        └──────────────┼──────────────┘
                       ↓
              reusable-ci-cd.yml
                       ↓
                     EC2

Bây giờ:

4 services
   ↓
1 Matrix workflow
   ↓
1 Reusable Workflow

Thêm service mới:

paymentservice

chỉ cần:

- paymentservice

20. Kiểm tra điểm quan trọng nhất

Mở:

cat .github/workflows/scale-ci-cd.yml

Bạn sẽ thấy phần:

strategy:
  matrix:
    service:
      - frontend
      - cartservice
      - productcatalogservice
      - checkoutservice

Và:

uses: ./.github/workflows/reusable-ci-cd.yml

Kết hợp hai thứ này:

Matrix
  ↓
service = frontend
  ↓
Reusable Workflow

Matrix
  ↓
service = cartservice
  ↓
Reusable Workflow

Matrix
  ↓
service = paymentservice
  ↓
Reusable Workflow

Đây chính là kiến trúc Reusable Workflow + Matrix.


21. Kiến trúc cuối Chapter 3C

                         GitHub
                            │
                            ↓
                   scale-ci-cd.yml
                            │
                     Matrix Strategy
                            │
       ┌────────────────────┼────────────────────┐
       ↓                    ↓                    ↓
   frontend            cartservice          productcatalog
       │                    │                    │
       └────────────────────┼────────────────────┘
                            ↓
                   reusable-ci-cd.yml
                            │
                  ┌─────────┴─────────┐
                  ↓                   ↓
             Docker Build        SSH → EC2
                                      │
                                      ↓
                              Docker Compose
                                      │
                                      ↓
                             Online Boutique

Kết quả đạt được

Chapter 3A
4 services
4 pipelines
        ↓
Chapter 3B
4 services
1 reusable workflow
4 caller workflows
        ↓
Chapter 3C
4+ services
1 Matrix workflow
1 reusable workflow

Từ đây, Chapter 3E có thể tiếp tục nâng cấp từ:

Matrix
   ↓
Docker Build
   ↓
EC2

thành:

Matrix
   ↓
Docker Build
   ↓
Amazon ECR
   ↓
Image per service

Phần ECR, image management, scanning, lifecycle và governance nên để trọng tâm sang Chapter 4, để Chapter 3 vẫn tập trung vào bài toán Scale CI/CD.


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í