VINUNI K4 · DAY 12 Cloud Service & Deployment · Instructor Flow
CP0 Setup
CP1 Config
CP2 Docker
CP3 Security
CP4 Scaling
CP5 Cloud
K4-L3A CLOUD SERVICE AND DEPLOYMENT · INSTRUCTOR GUIDE

Cloud Infrastructure &
Service Deployment

⏱️ Thời lượng: 240 phút
👤 Hình thức: Bài làm cá nhân
🎯 Thang điểm: 100 điểm bắt buộc + 10đ Bonus
🧭 Mục tiêu: Production-ready FastAPI Agent
📌 Hướng dẫn cho Lab Coach & Giảng viên
Slide deck này định hình toàn bộ lộ trình 240 phút trên lớp. Giữ đúng nhịp độ từng Checkpoint, giải thích bản chất kỹ thuật thay vì chỉ đưa code giải, và kiểm tra tính liêm chính học thuật qua các câu hỏi vấn đáp trực tiếp.
📋 QUY ĐỊNH BẮT BUỘC

Lab Meta & Chuẩn Đặt Tên Repo

🏷️ Định danh Repository (Trừ 5 điểm nếu sai)
Quy tắc đặt tên repo GitHub public:
K4-L3A-DAY12-<HoVaTen>-<MSSV>-CloudServicesAndDeployment

Ví dụ: K4-L3A-DAY12-NguyenVanAn-L3A202600280-CloudServicesAndDeployment
• Họ tên viết liền không dấu, giữ đúng chữ hoa/thường.
• MSSV thật do trường cấp. Đúng hậu tố CloudServicesAndDeployment.

🚀 Cơ chế nộp & Môi trường Mock LLM
  • Nộp bài: Nộp link repository GitHub public lên hệ thống Codelab / LMS của VinUni.
  • Mock LLM Offline: Lab sử dụng module mock nội bộ (utils/mock_llm.py), học viên không cần OpenAI API key và không phát sinh chi phí LLM ngoài.
  • Kỷ luật phiên bản: Tạo mốc lưu trữ code cục bộ thường xuyên sau mỗi Checkpoint (CP0 → CP5).
🎯 CHUẨN ĐẦU RA KỸ THUẬT

Mục Tiêu Học Tập Trọng Tâm

1. 12-Factor App Config
Tách biệt hoàn toàn code và configuration. Sử dụng Pydantic Settings đọc biến môi trường, thiết lập fail-fast khi thiếu secret quan trọng.
2. Multi-stage Container
Xây dựng Dockerfile 2 tầng siêu nhẹ (<500MB), tận dụng layer cache, chạy non-root user và tuân thủ nguyên tắc bảo mật image.
3. API Key & Cost Guard
Bảo vệ API qua xác thực secrets.compare_digest, giới hạn tốc độ (rate limit) sliding-window Redis ZSET và chốt chặn chi phí trước khi gọi LLM.
4. Liveness & Readiness
Phân biệt rạch ròi endpoint /health (tiến trình sống) và /ready (sẵn sàng kết nối phụ thuộc như Redis).
5. Stateless & Scale Ngang
Lưu trữ chat history trong Redis có TTL và Max Turns, xử lý tín hiệu SIGTERM để shutdown êm ái (graceful shutdown).
6. Production Cloud Deploy
Đưa ứng dụng lên hạ tầng Cloud thực tế (Railway / Render) với public HTTPS, đọc biến $PORT dynamic.
⏱️ KẾ HOẠCH THỜI GIAN 240 PHÚT

Lộ Trình Checkpoints & Điểm Số

Giai đoạn Khung thời gian Mốc hoàn thành Điểm số Trọng tâm
CP0 — Setup Start +0 – 20 phút (20m) Start +20 phút 0 đ (Baseline) Repo naming, venv, requirements, .env, Redis/fake
CP1 — Config, Health & Logging Start +20 – 60 phút (40m) Start +60 phút 15 đ Settings 6 trường, JSON log 1-line, /health
CP2 — Multi-stage Docker Start +60 – 105 phút (45m) Start +105 phút 15 đ Dockerfile multi-stage, non-root, compose agent+redis
☕ Giải lao giữa giờ Start +105 – 115 phút (10m) Start +115 phút — Nghỉ ngơi, reset tinh thần trước phần bảo mật
CP3 — API Security & Cost Guard Start +115 – 160 phút (45m) Start +160 phút 20 đ compare_digest, sliding-window ZSET, cost limit
CP4 — Scaling & Reliability Start +160 – 200 phút (40m) Start +200 phút 20 đ Redis history TTL, /ready ping, SIGTERM chain
CP5 — Cloud Deployment Start +200 – 230 phút (30m) Start +230 phút 15 đ Railway/Render HTTPS public, DEPLOYMENT.md (fallback 9đ)
Wrap-up & Nộp bài Start +230 – 240 phút (10m) Start +240 phút 15 đ (Exercises) Kiểm tra 10 câu exercises.md, chạy grade.py, submit LMS
🛠️ MÔI TRƯỜNG & THIẾT LẬP BAN ĐẦU

Chuẩn Bị Trước Khi Code (Prep Checklist)

📦 1. Công cụ & Môi trường cục bộ
  • Python 3.11+ đã cài đặt và cấu hình đường dẫn PATH.
  • Docker Desktop & Docker Compose đang chạy nền.
  • Khởi tạo môi trường ảo:
    python3 -m venv .venv
    source .venv/bin/activate
    pip install -r requirements.txt
  • Kho lưu trữ mã nguồn khởi tạo đúng tên chuẩn.
⚙️ 2. Biến môi trường & Redis
  • Sao chép file mẫu: cp .env.example .env
  • Tự tạo khóa bảo mật an toàn:
    python3 -c "import secrets; print(secrets.token_urlsafe(32))"
  • Điền giá trị vào biến AGENT_API_KEY trong .env.
  • Khởi động Redis: docker compose up -d redis
    (Mẹo: Nếu chưa bật được Docker, tạm thời dùng REDIS_URL=fake:// cho CP1, nhưng CP2+ bắt buộc Redis thật!)
📐 KIẾN TRÚC HỆ THỐNG (PIPELINE VIZ)

Tổng Quan Kiến Trúc Đa Tầng Của Agent

💻
Client Request
localhost:8000 / HTTPS
Header X-API-Key
➔
🐳
Docker Multi-stage
Non-root runner
Healthcheck & $PORT
➔
🛡️
Auth & Guards
API Key ➔ Rate Limit
➔ Cost Guard (401/429/402)
➔
⚡
Redis Memory
ZSET sliding window
Session history & TTL
➔
☁️
Cloud Production
Railway / Render
Public live URL
🗺️ Sơ đồ mã nguồn (App Map)
app/config.py (Settings) · app/logging_utils.py (JSON logger) · app/main.py (FastAPI endpoints)
app/auth.py (Key validator) · app/rate_limiter.py (ZSET limiter) · app/cost_guard.py (Monthly budget)
app/store.py (Redis session manager) · app/lifecycle.py (Signal handlers) · utils/mock_llm.py (Mock generator)
🟢 CHECKPOINT 0 · START +0–20 PHÚT · BASELINE

CP0 — Setup & Kiểm Tra Môi Trường

Làm Gì
  • Tạo hoặc đổi tên repo theo định dạng chuẩn quy định.
  • Tạo Python virtual environment và cài đặt requirements.txt.
  • Sao chép file mẫu: cp .env.example .env và sinh API Key.
  • Bật Redis bằng docker compose up -d redis hoặc cấu hình tạm REDIS_URL=fake://.
Sản Phẩm Đạt Được
  • Repository GitHub có cấu trúc thư mục hoàn chỉnh, đúng tên.
  • Môi trường ảo .venv kích hoạt thành công, không thiếu package.
  • File .env cục bộ có đủ key cần thiết và KHÔNG bị lộ.
  • Redis server đang chạy hoặc backend fake đã sẵn sàng.
Hiểu Bản Chất
  • Bảo mật bí mật: Vì sao .env bắt buộc phải nằm trong file ignore không được đẩy lên remote.
  • Red-Green-Refactor: Chạy test trước khi viết code sẽ gặp lỗi (đỏ) là hoàn toàn bình thường.
  • Hiểu vai trò của file requirements và cách ly dependencies.
Tự Kiểm Tra (Self-Check)
  • Chạy lệnh kiểm thử ban đầu:
    pytest tests/ -v -m "not docker"
  • Lệnh phải thực thi bình thường (không văng lỗi ModuleNotFoundError hay cú pháp).
🟢 CHECKPOINT 1 · START +20–60 PHÚT · 15 ĐIỂM

CP1 — 12-Factor Config, Health & Logging

Làm Gì
  • Hoàn thiện app/config.py: Sử dụng Pydantic BaseSettings khai báo đủ 6 trường cấu hình.
  • Thiết lập trường agent_api_key bắt buộc (fail-fast nếu thiếu).
  • Cấu hình logging định dạng JSON 1 dòng trong app/logging_utils.py.
  • Tạo endpoint /health trả 200 OK độc lập với các phụ thuộc ngoài.
Sản Phẩm Đạt Được
  • Đối tượng Settings tự động load và validate biến môi trường chính xác.
  • Logs in ra console chuẩn cấu trúc JSON 1 dòng (timestamp, level, event, metadata).
  • Endpoint /health luôn trả {"status": "ok"} ngay cả khi Redis tắt.
Hiểu Bản Chất
  • Nguyên tắc III của 12-Factor: Code không đổi qua các môi trường, chỉ có cấu hình thay đổi theo môi trường.
  • Fail-fast: Ứng dụng phải dừng ngay từ lúc khởi động nếu cấu hình bắt buộc không hợp lệ.
  • Liveness probe: Kiểm tra tiến trình web có sống không; không được gọi DB/Redis tại đây để tránh cascade failure.
Tự Kiểm Tra (Self-Check)
  • Chạy bộ test suite cho CP1:
    pytest tests/test_cp1.py -v
  • Tất cả các ca kiểm thử về config validation, log JSON format và health check phải PASS xanh hoàn toàn.
🟢 CHECKPOINT 2 · START +60–105 PHÚT · 15 ĐIỂM

CP2 — Multi-stage Docker & Compose

Làm Gì
  • Xây dựng Dockerfile 2 giai đoạn: stage 1 builder (cài wheels), stage 2 runner (chỉ copy wheels, python-slim).
  • Tạo non-root user (appuser) và gán quyền sở hữu mã nguồn.
  • Khai báo chỉ thị HEALTHCHECK và lệnh khởi động đọc biến $PORT.
  • Viết .dockerignore và docker-compose.yml cho 2 service: agent & redis.
Sản Phẩm Đạt Được
  • Docker image gọn nhẹ (kích thước tối ưu < 500MB).
  • Container thực thi dưới user đặc quyền thấp, loại bỏ nguy cơ root breakout.
  • Lệnh docker compose up -d khởi chạy thành công cả ứng dụng và Redis trên mạng nội bộ.
Hiểu Bản Chất
  • Layer Caching: Luôn COPY requirements.txt và cài đặt trước khi COPY . ..
  • Bảo mật: Không chạy process trong container dưới quyền root; không để rò rỉ build cache và file .env vào image context.
  • Cloud readiness: Platform cloud sẽ tự gán ngẫu nhiên $PORT, ứng dụng phải lắng nghe trên cổng này.
Tự Kiểm Tra (Self-Check)
  • Kiểm tra tự động và build thử nghiệm:
    pytest tests/test_cp2.py -v
    docker build -t day12-agent:prod .
    docker compose up -d
    curl http://localhost:8000/health
🟢 CHECKPOINT 3 · START +115–160 PHÚT · 20 ĐIỂM

CP3 — API Security & Cost Guard

🛡️ Giai đoạn 1: Ba chốt chặn bảo vệ (Chặn TRƯỚC khi gọi LLM)
1. AUTH GUARD ➔ 401
verify_api_key
Kiểm tra Header X-API-Key.
Dùng secrets.compare_digest.
Sai key ➔ 401 Unauthorized
2. RATE LIMITER ➔ 429
limiter.check
Sliding-window Redis ZSET.
Check zcard trước, zadd sau.
Quá tải ➔ 429 Too Many Req
3. COST GUARD ➔ 402
guard.check
Theo dõi tích lũy chi phí tháng.
Chặn TRƯỚC khi gọi LLM.
Hết tiền ➔ 402 Payment Required
⚡ Giai đoạn 2: Chuỗi thực thi & Lưu trữ phiên (Sau khi vượt qua 3 chốt)
BƯỚC 4
get_history
Đọc context lịch sử từ Redis store trước khi gọi model
BƯỚC 5
ask_llm
Gửi prompt + history tới mock LLM an toàn
BƯỚC 6
append × 2
Lưu cả user query & assistant response vào Redis
BƯỚC 7
guard.record
Cộng dồn chi phí token phát sinh vào Redis tháng
BƯỚC 8
log_event
Ghi JSON structured log 1 dòng ra console
Làm Gì
  • Implement app/auth.py với secrets.compare_digest.
  • Implement app/rate_limiter.py với Redis ZSET sliding window.
  • Implement app/cost_guard.py kiểm soát chi phí tháng.
  • Wire thứ tự bảo vệ trong /ask trước mock LLM.
Sản Phẩm Đạt Được
  • Xác thực API key constant-time (compare_digest).
  • Sliding-window rate limit với member duy nhất.
  • Cost guard theo dõi ngân sách theo user/tháng.
  • Endpoint /ask chặn trước khi gọi LLM (401/429/402).
Hiểu Bản Chất
  • Chống Timing Attack bằng so sánh chuỗi hằng số thời gian.
  • Phân biệt Rate limit (tần suất/phút) vs Budget (USD/tháng).
  • Thao tác ZSET: xóa cũ ➔ đếm zcard ➔ kiểm tra ➔ add member duy nhất.
Tự Kiểm Tra
  • Chạy bộ test suite cho CP3:
    pytest tests/test_cp3.py -v
  • Kiểm chứng thứ tự: Sai key văng 401 trước khi kiểm tra rate limit hay tính phí.
🟢 CHECKPOINT 4 · START +160–200 PHÚT · 20 ĐIỂM

CP4 — Scaling, Readiness & Graceful Shutdown

Làm Gì
  • Quản lý session chat trong Redis (app/store.py): Cắt tỉa lịch sử theo MAX_HISTORY_TURNS và gán SESSION_TTL_SECONDS.
  • Viết endpoint /ready: Gửi lệnh ping() đến Redis; trả 200 OK nếu sẵn sàng, trả 503 Service Unavailable nếu mất kết nối.
  • Cài đặt Signal Handler bắt tín hiệu SIGTERM và SIGINT trong app/lifecycle.py, chain tới handler cũ.
Sản Phẩm Đạt Được
  • FastAPI backend hoàn toàn stateless, có thể scale ngang thành nhiều container mà không lệch state.
  • Endpoint /ready báo trạng thái tin cậy cho load balancer điều phối traffic.
  • Khi nhận lệnh stop từ Docker/K8s, ứng dụng dọn dẹp kết nối êm ái trước khi thoát.
Hiểu Bản Chất
  • Liveness vs Readiness: /health (tiến trình có treo không? Nếu treo restart) vs /ready (phụ thuộc có đủ không? Chưa đủ thì ngừng cấp traffic).
  • Stateless: Bất kỳ instance nào cũng có thể xử lý bất kỳ request nào vì state nằm tập trung tại Redis.
Tự Kiểm Tra (Self-Check)
  • Chạy test suite cho CP4:
    pytest tests/test_cp4.py -v
  • Thử tắt Redis và xác nhận: /health vẫn trả 200, nhưng /ready phải trả về 503!
🟢 CHECKPOINT 5 · START +200–230 PHÚT · 15 ĐIỂM

CP5 — Cloud Deployment & Fallback Policy

☁️ Kịch bản 1: Live Cloud Deploy (15/15 Điểm)
Deploy ứng dụng lên Railway hoặc Render kèm Cloud Redis; cấu hình đầy đủ biến môi trường trên Dashboard platform.
⚠️ Kịch bản 2: LOCAL_FALLBACK=true (Tối đa 9/15 Điểm)
Nếu gặp sự cố thẻ/tài khoản platform: bật cờ export LOCAL_FALLBACK=true để test cục bộ; điểm tối đa 9/15.
Làm Gì
  • Deploy HTTPS URL công khai lên Railway hoặc Render kèm Cloud Redis.
  • Cấu hình Environment Variables trên Platform Dashboard.
  • Soạn thảo DEPLOYMENT.md kèm lệnh curl mẫu và ảnh screenshots.
  • Fallback nếu có sự cố: LOCAL_FALLBACK=true.
Sản Phẩm Đạt Được
  • URL HTTPS công khai + Redis đám mây + biến môi trường trên platform.
  • File DEPLOYMENT.md đầy đủ URL, curl test, và ảnh trong screenshots/.
  • Hoặc cờ fallback: LOCAL_FALLBACK=true ➔ CP5 tối đa 9/15 điểm.
Hiểu Bản Chất
  • Cách platform cấp phát dynamic $PORT và ứng dụng phải bind vào cổng này.
  • Phân biệt Build Logs (đóng gói image) vs Runtime Logs (xử lý request).
  • Nơi lưu trữ an toàn Secrets trên Dashboard, không commit file .env.
  • Chẩn đoán lỗi healthcheck và readiness khi deploy thực tế.
Tự Kiểm Tra
  • Chạy bộ test suite cho CP5:
    pytest tests/test_cp5.py -v
  • Thực thi trực tiếp các lệnh curl kiểm chứng được nêu trong DEPLOYMENT.md tới HTTPS URL công khai.
📝 ĐÁNH GIÁ THẤU HIỂU LÝ THUYẾT · 15 ĐIỂM

Phần Tự Luận: exercises.md (10 Câu Hỏi)

💡 Tiêu chí đánh giá tự luận (15 điểm bắt buộc)
Học viên mở file exercises.md và hoàn thành 10 câu hỏi phản ánh bằng chính ngôn ngữ của mình. Không sao chép nguyên văn tài liệu hoặc dùng AI tạo lời giải vô nghĩa.
Câu 1 – 5: Nền Tảng & Container
1. Nguyên tắc 12-Factor config & rủi ro hardcode secret.
2. Cơ chế Fail-fast khi khởi chạy service.
3. Tại sao endpoint /health không được kiểm tra Redis?
4. Lợi ích của Multi-stage Docker build so với single-stage.
5. Vì sao không chạy container dưới quyền user root?
Câu 6 – 10: Bảo Mật & Hệ Thống Phân Tán
6. Timing Attack là gì và tại sao cần secrets.compare_digest?
7. So sánh Sliding Window (ZSET) vs Fixed Window Rate Limiting.
8. Tại sao Cost Guard phải kiểm tra trước khi gọi model LLM?
9. Sự khác biệt cốt lõi giữa Liveness probe và Readiness probe.
10. Bản chất Stateless và vai trò của Redis trong việc scale ngang.
🌟 NÂNG CAO · ĐIỂM THƯỞNG +10 ĐIỂM

Bonus: GitHub Actions CI/CD Pipeline

⚙️ Yêu cầu Pipeline (.github/workflows/ci.yml)
  • Tự động kích hoạt trên cả 2 sự kiện: push và pull_request (bắt lỗi kiểm thử TRƯỚC khi merge).
  • Thực thi tuần tự các giai đoạn chất lượng:
    1. Dependencies: Cài đặt thư viện từ requirements.txt trên Ubuntu runner.
    2. Test Suite: Chạy pytest (loại trừ các test cần live deploy như test_cp5).
    3. Build Image: Build thử Dockerfile xác nhận image không lỗi cú pháp.
    4. Deploy: Chỉ deploy lên nhánh chính main sau khi toàn bộ test xanh (Green Build qua needs: và if: github.ref == \x27refs/heads/main\x27).
  • Gắn badge trạng thái CI/CD passing lên đầu file README.md.
⚠️ Quy định tính điểm thưởng
  • Chỉ bắt đầu làm Bonus SAU KHI đã hoàn thành đầy đủ CP1 đến CP5.
  • Điểm thưởng tối đa: +10 điểm.
  • Script chấm tự động grade.py sẽ tính điểm bonus nhưng tổng điểm cuối cùng luôn bị CAP Ở 100 ĐIỂM.
  • Lệnh kiểm thử tự động bonus:
    pytest tests/test_bonus_cicd.py -v
⚖️ THANG ĐIỂM & CHÍNH SÁCH XỬ PHẠT

Rubric Chi Tiết & Các Lỗi Bị Trừ Điểm Nặng

📊 Bảng phân bổ điểm (Tổng 100 điểm)
CP1 — Config, Health & Logging15 đ
CP2 — Multi-stage Docker15 đ
CP3 — API Security & Cost Guard20 đ
CP4 — Scaling & Graceful Shutdown20 đ
CP5 — Cloud Deployment (Fallback max 9đ)15 đ
Exercises (10 câu phản ánh lý thuyết)15 đ
Bonus CI/CD (GitHub Actions)+10 đ (Cap 100)
🚫 Các lỗi bị phạt nghiêm khắc
  • Trừ 5 điểm: Đặt sai quy cách tên repository GitHub.
  • Trừ 10 điểm: Lưu file chứa bí mật (.env, API key, credential, token) lên repo công khai.
  • Hủy điểm phần tương ứng: Coach phỏng vấn vấn đáp nhanh trên lớp mà học viên không giải thích được cơ chế hoạt động của code do mình nộp.
  • 0 điểm toàn bài: Phát hiện gian lận, sao chép code giữa các học viên.
📦 QUY TRÌNH KẾT THÚC LAB

Checklist Kiểm Tra Trước Khi Nộp Bài

✅ Checklist 6 Bước Hoàn Tất
  • [ ] Repo GitHub đang ở chế độ Public.
  • [ ] Tên repo chuẩn dạng: K4-L3A-DAY12-HoVaTen-MSSV-CloudServicesAndDeployment.
  • [ ] Tuyệt đối KHÔNG có file .env trong lịch sử lưu trữ mã nguồn.
  • [ ] File DEPLOYMENT.md đầy đủ public URL và đính kèm ảnh screenshots.
  • [ ] Đã trả lời đầy đủ 10 câu hỏi trong exercises.md.
  • [ ] Chạy python grade.py đạt số điểm kỳ vọng.
📤 Cách thức Submit Lên Hệ Thống

Sao chép đường dẫn URL của GitHub repository public và nộp lên hệ thống Codelab / LMS theo đúng thông báo của giảng viên trước thời điểm kết thúc lab (Start +240m).

Lưu ý: Mọi cập nhật sau thời hạn kết thúc lab sẽ không được tính điểm trừ khi có sự đồng ý của Giảng viên phụ trách.
🔍 BÁC SĨ CHẨN ĐOÁN LỖI (PHỤ LỤC A)

Các Lỗi Thường Gặp & Cách Khắc Phục

Triệu chứng / Báo lỗi Nguyên nhân gốc rễ Cách khắc phục nhanh chóng
agent_api_key Field required Chưa tạo .env hoặc thiếu trường Chạy cp .env.example .env và gán key
Redis Error 61 (Connection refused) Redis container chưa được khởi động Chạy docker compose up -d redis (hoặc tạm fake://)
No module named 'app' Đứng sai thư mục khi gọi pytest Luôn chạy lệnh từ thư mục gốc của repository
curl localhost fail trong container Uvicorn bind cổng vào localhost Cấu hình Uvicorn lắng nghe trên --host 0.0.0.0
Docker build chậm, mất cache Copy toàn bộ source code quá sớm Copy requirements.txt và cài pip trước khi copy source
Kích thước Docker image > 500MB Dùng base image nặng, thừa toolchain Dùng multi-stage build với base python:3.11-slim
Bị lỗi 429 Too Many Requests quá sớm Thực hiện lệnh zadd trước khi kiểm tra Kiểm tra số lượng request bằng zcard trước, chỉ add khi hợp lệ
Endpoint /ready luôn trả về 200 Hardcode 200 thay vì kiểm tra Redis Gọi lệnh ping() đến Redis; bắt ngoại lệ và trả về 503
Deploy lên Cloud bị health check timeout Cổng lắng nghe cố định cổng 8000 Đọc biến môi trường $PORT do platform cấp
⏱️ BẮT ĐẦU BUỔI THỰC HÀNH

Sẵn Sàng & Bắt Đầu Đếm Ngược 240 Phút!

⏱️ Quản lý thời gian hiệu quả
  • Bật đồng hồ bấm giờ: Giữ đúng nhịp mốc hoàn thành của từng Checkpoint (CP0: 20m, CP1: 60m, CP2: 105m...).
  • Quy tắc 10 phút: Nếu gặp một lỗi blocker debug quá 10 phút không ra, hãy lập tức giơ tay nhờ Lab Coach trợ giúp.
  • Kỷ luật quản lý code: Tạo điểm lưu trữ an toàn ngay khi hoàn thành mỗi CP.
🙋 Hỏi & Đáp (Q&A)

Có bất kỳ câu hỏi nào về thể lệ, kiến trúc hệ thống hoặc yêu cầu nộp bài không?

Chúc các bạn hoàn thành xuất sắc lab Cloud Service & Deployment hôm nay! 🚀