Lý Thuyết Cốt Lõi
1. Triển Khai App Service — Tạo App & CI/CD
Azure App Service là nền tảng PaaS (Platform as a Service) hỗ trợ nhiều runtime: .NET, Java, Node.js, Python, PHP, Ruby, và container tùy chỉnh. App được triển khai lên App Service Plan đã cấu hình ở Module 23.
- • Portal: App Services → Create → chọn Runtime stack, OS, Plan
- • Azure CLI:
az webapp createvới --runtime và --plan - • ARM/Bicep template: IaC tự động hóa toàn bộ stack
- • VS Code: Azure App Service extension deploy trực tiếp từ IDE
- • GitHub Actions: workflow YAML tự động build và deploy khi push
- • Azure DevOps Pipelines: enterprise CI/CD với gate và approvals
- • Bitbucket / GitLab: kết nối qua Deployment Center
- • Local Git: push code lên remote URL của App Service
- • ZIP deploy:
az webapp deploy --type zipcho CI đơn giản
| Phương thức Deploy | Ưu điểm | Phù hợp với |
|---|---|---|
| GitHub Actions | Tích hợp sẵn, marketplace phong phú, free cho public repos | Startup, open source |
| Azure DevOps | Gate/approval, artifact versioning, release management | Enterprise, nhiều team |
| ZIP Deploy | Đơn giản, không cần pipeline phức tạp | Script deploy tùy chỉnh |
| Container Registry | Docker image versioning, rollback bằng tag | Microservices, containerized app |
2. Deployment Slots — Zero-Downtime Deployment
Deployment slots là các live environment riêng biệt trong cùng 1 App Service app. Mỗi slot có URL riêng, app settings riêng, nhưng chạy trên cùng App Service Plan. Slot swap hoán đổi traffic giữa 2 slots gần như tức thì — không có downtime.
Deploy code mới lên đây, warm up, chạy smoke test. URL: app-staging.azurewebsites.net
Hoán đổi staging ↔ production. Traffic chuyển ngay lập tức. Rollback = swap lại.
Sau swap: code mới chạy production. Code cũ còn ở staging để rollback. URL: app.azurewebsites.net
App Settings và Connection Strings có thể đánh dấu là "slot setting" — giá trị không bị swap, mỗi slot giữ settings riêng.
- • Production DB connection: chỉ gắn production slot
- • Staging DB connection: chỉ gắn staging slot
- • Swap code nhưng giữ đúng DB cho từng env
Gửi một phần traffic đến staging slot để test với real users trước khi full swap.
- • VD: 10% traffic → staging (phiên bản mới)
- • 90% traffic → production (phiên bản cũ)
- • Xem metrics, sau đó tăng dần hoặc rollback
- • Yêu cầu Standard tier trở lên
3. Bảo Mật App Service
App Service cung cấp nhiều lớp bảo mật từ authentication built-in, network restriction, đến managed identity và secret management qua Key Vault.
- • Built-in auth middleware không cần code thay đổi
- • Provider: Microsoft Entra ID, Google, Facebook, Twitter, GitHub
- • Chế độ: Allow unauthenticated / Require authentication
- • Token store: lưu OAuth tokens trong App Service
- • Cấu hình qua Portal → Authentication → Add identity provider
- • Access Restrictions: whitelist/blacklist IP ranges, Service Tags
- • VNet Integration: outbound traffic qua VNet (Premium+)
- • Private Endpoint: inbound traffic chỉ qua VNet (không public)
- • Service Endpoint: app chỉ truy cập Azure services qua VNet
- • HTTPS Only: bắt buộc redirect HTTP → HTTPS
- • System-assigned Managed Identity: app tự có identity trong Entra ID
- • Key Vault References trong App Settings:
@Microsoft.KeyVault(SecretUri=...) - • App lấy secret từ Key Vault tự động — không lưu secret trong code
- • Xoay secret trong Key Vault: app tự cập nhật, không cần redeploy
- • Free Managed Certificate: App Service tự cấp và gia hạn cert cho custom domain
- • App Service Certificate: mua từ Azure, tự động gia hạn
- • Upload cert: upload .pfx cert từ CA bên ngoài
- • Minimum TLS version: cấu hình 1.2 hoặc 1.3
4. Custom Domain, Backup & Restore
- Verify domain ownership: thêm TXT record tại DNS registrar
- Map domain: thêm CNAME hoặc A record trỏ về app URL
- Thêm custom domain vào App Service → Custom domains
- Bind SSL certificate cho custom domain
- Enforce HTTPS Only để redirect toàn bộ HTTP traffic
CNAME vs A record: Dùng CNAME cho subdomain (www.domain.com). Dùng A record + TXT verify cho apex domain (domain.com). CNAME không thể dùng cho apex domain theo DNS standard.
Yêu cầu Standard tier trở lên. Backup lưu vào Azure Storage Account.
- • Backup gồm: app configuration, file content, database (SQL/MySQL)
- • Scheduled backup: cấu hình tần suất (1h đến 1 ngày) và retention
- • Manual backup: trigger ngay lập tức trước khi thay đổi lớn
- • Restore: khôi phục về app hiện tại hoặc app mới trong RG khác
- • Partial restore: chỉ restore database không cần restore toàn bộ app
- • Backup size limit: 10 GB (app + DB)
- • App Settings: key-value pairs được inject làm environment variable
- • Connection Strings: chuỗi kết nối DB — không expose qua source code
- • General Settings: .NET version, PHP version, Always On, ARR affinity
- • Always On: giữ app warm, tránh cold start (Standard+)
- • ARR Affinity: sticky session — cùng user vào cùng instance
- • App Service Logs: Application log (filesystem/Blob), Web server log
- • Log Stream: xem log real-time từ Portal hoặc CLI
- • Application Insights: APM — request rate, failure rate, latency, dependency tracking
- • Diagnostics: Diagnose and solve problems tự động phân tích sự cố
Bài Tập Thực Hành (Lab)
Tạo Resource Group, App Service Plan và Web App
# Tạo Resource Group
az group create \
--name rg-az104-m24 \
--location southeastasia \
--tags Course=AZ-104 Module=24 Environment=Lab
# Tạo App Service Plan Standard S1
az appservice plan create \
--name asp-az104-m24 \
--resource-group rg-az104-m24 \
--location southeastasia \
--sku S1 \
--is-windows
# Tạo Web App (Node.js 20 LTS)
# Tên app phải unique toàn cầu
APP_NAME="webapp-az104-m24-$(date +%s | tail -c 6)"
echo "App name: $APP_NAME"
az webapp create \
--name "$APP_NAME" \
--resource-group rg-az104-m24 \
--plan asp-az104-m24 \
--runtime "NODE:20-lts"
# Xem thông tin app
az webapp show \
--name "$APP_NAME" \
--resource-group rg-az104-m24 \
--query "{name:name, url:defaultHostName, state:state, runtime:siteConfig.linuxFxVersion}" \
--output table
echo "App URL: https://$APP_NAME.azurewebsites.net"
asp-az104-m24.
Tạo Deployment Slot và thực hiện Slot Swap
# Đặt biến APP_NAME (thay bằng tên thực tế từ bước 1)
APP_NAME="webapp-az104-m24-XXXXXX"
# Tạo staging slot
az webapp deployment slot create \
--name "$APP_NAME" \
--resource-group rg-az104-m24 \
--slot staging
# Xem danh sách slots
az webapp deployment slot list \
--name "$APP_NAME" \
--resource-group rg-az104-m24 \
--output table
# Thêm App Setting đánh dấu là slot-specific (sticky)
az webapp config appsettings set \
--name "$APP_NAME" \
--resource-group rg-az104-m24 \
--slot staging \
--settings ENVIRONMENT=Staging DB_NAME=db-staging
az webapp config appsettings set \
--name "$APP_NAME" \
--resource-group rg-az104-m24 \
--settings ENVIRONMENT=Production DB_NAME=db-prod
# Đánh dấu settings là slot-specific (không bị swap)
az webapp config appsettings set \
--name "$APP_NAME" \
--resource-group rg-az104-m24 \
--slot-settings ENVIRONMENT DB_NAME
# Deploy HTML đơn giản vào staging để test swap
az webapp deployment source config-zip \
--name "$APP_NAME" \
--resource-group rg-az104-m24 \
--slot staging \
--src "https://github.com/Azure-Samples/html-docs-hello-world/archive/master.zip" 2>/dev/null || true
# Thực hiện slot swap: staging → production
az webapp deployment slot swap \
--name "$APP_NAME" \
--resource-group rg-az104-m24 \
--slot staging \
--target-slot production
echo "Swap hoàn tất. Kiểm tra: https://$APP_NAME.azurewebsites.net"
echo "Staging slot: https://$APP_NAME-staging.azurewebsites.net"
Bật HTTPS Only, cấu hình Access Restriction và Managed Identity
APP_NAME="webapp-az104-m24-XXXXXX"
# Bật HTTPS Only (redirect HTTP → HTTPS)
az webapp update \
--name "$APP_NAME" \
--resource-group rg-az104-m24 \
--https-only true
# Đặt Minimum TLS Version = 1.2
az webapp config set \
--name "$APP_NAME" \
--resource-group rg-az104-m24 \
--min-tls-version 1.2
# Bật Always On (tránh cold start)
az webapp config set \
--name "$APP_NAME" \
--resource-group rg-az104-m24 \
--always-on true
# Thêm Access Restriction: chỉ cho phép IP của văn phòng
# Thay 203.0.113.0/24 bằng IP thực tế của bạn
az webapp config access-restriction add \
--name "$APP_NAME" \
--resource-group rg-az104-m24 \
--rule-name "AllowOfficeIP" \
--action Allow \
--ip-address "203.0.113.0/24" \
--priority 100
# Bật System-assigned Managed Identity
az webapp identity assign \
--name "$APP_NAME" \
--resource-group rg-az104-m24
# Xem Principal ID của identity (dùng để gán Key Vault access)
az webapp identity show \
--name "$APP_NAME" \
--resource-group rg-az104-m24 \
--query "{principalId:principalId, tenantId:tenantId}" \
--output table
# Xem cấu hình bảo mật tổng hợp
az webapp show \
--name "$APP_NAME" \
--resource-group rg-az104-m24 \
--query "{httpsOnly:httpsOnly, minTls:siteConfig.minTlsVersion, identity:identity.type}" \
--output table
Cấu hình Backup tự động vào Storage Account
APP_NAME="webapp-az104-m24-XXXXXX"
STORAGE_NAME="staz104m24bkp$(date +%s | tail -c 6)"
CONTAINER_NAME="appbackups"
# Tạo Storage Account cho backup
az storage account create \
--name "$STORAGE_NAME" \
--resource-group rg-az104-m24 \
--location southeastasia \
--sku Standard_LRS \
--kind StorageV2 \
--https-only true \
--min-tls-version TLS1_2
# Tạo container trong storage
az storage container create \
--name "$CONTAINER_NAME" \
--account-name "$STORAGE_NAME"
# Lấy SAS token có hiệu lực 1 năm cho backup
END_DATE=$(date -u -d "+365 days" +%Y-%m-%dT%H:%MZ 2>/dev/null || \
date -u -v+365d +%Y-%m-%dT%H:%MZ)
SAS_TOKEN=$(az storage account generate-sas \
--account-name "$STORAGE_NAME" \
--services b \
--resource-types co \
--permissions rwdlacup \
--expiry "$END_DATE" \
--output tsv)
STORAGE_URL="https://$STORAGE_NAME.blob.core.windows.net/$CONTAINER_NAME?$SAS_TOKEN"
# Cấu hình backup tự động: mỗi 24 giờ, giữ 30 bản
az webapp config backup update \
--resource-group rg-az104-m24 \
--webapp-name "$APP_NAME" \
--container-url "$STORAGE_URL" \
--frequency 1d \
--retain-one true \
--retention 30
# Trigger backup thủ công ngay lập tức
az webapp config backup create \
--resource-group rg-az104-m24 \
--webapp-name "$APP_NAME" \
--container-url "$STORAGE_URL" \
--backup-name "manual-backup-$(date +%Y%m%d)"
# Liệt kê các backup đã có
az webapp config backup list \
--resource-group rg-az104-m24 \
--webapp-name "$APP_NAME" \
--output table
Cleanup — Dọn dẹp tài nguyên
# Xóa toàn bộ Resource Group (app, plan, storage, backup config)
az group delete --name rg-az104-m24 --yes --no-wait
# Xác nhận RG đang xóa
az group show --name rg-az104-m24 --query "properties.provisioningState" -o tsv
# Kết quả mong đợi: Deleting
Kết Quả Đầu Ra
Tạo App Service trên Plan đã cấu hình, chọn đúng runtime, xác nhận app truy cập được qua URL mặc định
Tạo staging slot, hiểu sticky settings, thực hiện swap zero-downtime và biết cách rollback
Cấu hình HTTPS Only, TLS 1.2+, Access Restrictions IP, Managed Identity cho Key Vault integration
So sánh các phương thức deploy, biết cách setup GitHub Actions và ZIP deploy qua CLI
Hiểu quy trình verify domain, bind cert, phân biệt CNAME vs A record cho apex/subdomain
Cấu hình scheduled backup vào Storage Account, thực hiện manual backup và biết cách restore
Ứng Dụng Thực Tế
Tình huống 1: Chuỗi F&B — Deploy ứng dụng đặt bàn online không downtime
Hệ thống đặt bàn hoạt động 24/7, cần deploy phiên bản mới mỗi tuần mà không làm gián đoạn khách hàng đang đặt bàn.
GitHub Actions tự động deploy lên staging slot mỗi khi merge PR vào main. QA team test staging. Sau approve, slot swap production — không downtime. Connection string DB prod được sticky setting, staging dùng DB riêng.
App Service Standard S2 tại Southeast Asia. 2 slots: production + staging. Backup daily vào Storage Account lúc 2h sáng. Custom domain dat-ban.fbchain.vn với Free Managed Certificate. HTTPS Only + TLS 1.2.
Deploy mỗi tuần, zero downtime. Rollback trong 30 giây nếu phát hiện bug sau deploy. Khách hàng không bao giờ thấy trang lỗi. Backup 30 ngày đảm bảo recovery nếu data bị corrupt.
Tình huống 2: Phòng khám tư — API backend bảo mật cho app di động
API backend phục vụ app đặt lịch khám bệnh trên iOS/Android, cần xác thực bệnh nhân qua Microsoft Entra và không lộ secret trong code.
App Service Easy Auth với Entra ID — mobile app authenticate OAuth2 PKCE. Managed Identity để app đọc secrets từ Key Vault (DB connection string, API keys). Access Restriction chỉ cho phép Azure API Management IP.
App Service Premium P1v3 + VNet Integration. Private endpoint cho Azure SQL Database. Application Insights theo dõi API latency và error rate. Backup mỗi 6 giờ. Always On bật để không cold start cho bệnh nhân khẩn cấp.
Không có secret trong source code — pass security audit. Bệnh nhân xác thực Entra ID — SSO với Microsoft 365. API không exposed public — chỉ qua API Management. Tuân thủ quy định bảo vệ dữ liệu y tế.
Tình huống 3: Công ty fintech — A/B testing tính năng mới cho 10% users
Team product muốn thử nghiệm UI mới của màn hình chuyển khoản với 10% user trước khi rollout toàn bộ.
Deploy UI mới lên staging slot. Cấu hình Traffic Splitting: 10% traffic → staging (UI mới), 90% → production (UI cũ). Azure Application Insights so sánh conversion rate và error rate giữa 2 groups.
Standard S2 với 2 slots. Traffic Splitting 10%/90% qua Portal → Deployment slots → Traffic %. App Insights custom event tracking "transfer_completed" trên cả 2 slots. Sau 7 ngày thu thập đủ data để quyết định.
Data-driven decision: tăng traffic dần nếu UI mới tốt hơn. Nếu UI mới gây lỗi, chỉ 10% user bị ảnh hưởng, rollback trong 30 giây. Không cần deploy riêng — dùng slot đã có, tiết kiệm chi phí infrastructure.