Mục Tiêu Lab
Tạo App Service Plan với đúng tier và region
Deploy ASP.NET Core 8 Web App bằng ZIP deploy và az webapp deploy
Tạo deployment slot staging và thực hiện slot swap zero-downtime
Cấu hình App Settings và Connection Strings (sticky vs non-sticky)
Xem Application Logs và Live Log Stream để debug
Scale out (manual và auto-scale) App Service Plan
Yêu Cầu Chuẩn Bị
- Azure CLI 2.50+ đã đăng nhập (az login)
- .NET 8 SDK: dotnet.microsoft.com/download
- Git đã cài (git --version)
- Hoàn thành Lab 01 + Lab 02
- App Service Plan B1: ~$0.018/giờ (~$13.14/tháng)
- Deployment slots yêu cầu Standard tier (S1+) trở lên
- S1 tier: ~$0.10/giờ — nhớ xóa sau lab
- Free tier (F1) không hỗ trợ custom domains, slots
Kịch Bản & Tài Nguyên
Bạn cần deploy ứng dụng web ASP.NET Core 8 lên Azure App Service với quy trình CI/CD đơn giản: code deploy lên staging slot → test → swap sang production — zero downtime, rollback được ngay.
Standard S1
Southeast Asia
Linux
ASP.NET Core 8
Runtime: dotnet:8
staging
Swap → zero downtime
APP_VERSION
Sticky per slot
Các Bước Thực Hiện
Tạo Resource Group & App Service Plan
App Service Plan xác định compute resources (CPU, RAM, số instances) và tier (features). Nhiều Web Apps có thể chia sẻ cùng một Plan để tiết kiệm chi phí.
- 1.Portal → App Services → + Create → Web App
- 2.RG: tạo mới
rg-hoatranlab-lab17 - 3.Name:
app-hoatranlab-17xxx(thay xxx = random) - 4.Runtime stack: .NET 8 (LTS) | OS: Linux | Region: Southeast Asia
- 5.App Service Plan: Create new → Name: plan-hoatranlab-lab17 → Tier: Standard S1
- 6.Review + Create → Create (đợi ~1 phút)
# Tạo Resource Group
az group create \
--name rg-hoatranlab-lab17 \
--location southeastasia
# Tạo App Service Plan Standard S1 (Linux)
az appservice plan create \
--name plan-hoatranlab-lab17 \
--resource-group rg-hoatranlab-lab17 \
--location southeastasia \
--sku S1 \
--is-linux
# Tạo Web App (.NET 8 runtime)
SUFFIX=$RANDOM
APP_NAME="app-hoatranlab-17${SUFFIX}"
az webapp create \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17 \
--plan plan-hoatranlab-lab17 \
--runtime "DOTNETCORE:8.0"
echo "Web App URL: https://${APP_NAME}.azurewebsites.net"
# Xác nhận web app đang chạy
az webapp show \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17 \
--query "{state:state,defaultHostName:defaultHostName}" \
--output json
Tạo ASP.NET Core App & Deploy bằng ZIP
Cách đơn giản nhất để deploy: dotnet publish → zip → az webapp deploy. Phù hợp cho demo và manual deploy; production nên dùng GitHub Actions hoặc Azure DevOps.
- 1.Vào Web App → Deployment Center (left menu)
- 2.Source: GitHub → Authorize → chọn repo
- 3.Branch: main → Runtime: .NET 8 → Save
- 4.Azure tự tạo GitHub Actions workflow → commit deploy tự động
- 5.Xem logs deploy trong Logs tab
- 6.Click URL web app → xác nhận app chạy
# Tạo ASP.NET Core Web App mới dotnet new webapp -n HoaTranLabApp --framework net8.0 cd HoaTranLabApp # Sửa nhanh nội dung để phân biệt version cat > Pages/Index.cshtml << 'EOF' @page @model IndexModelHoaTranLab - Azure App Service Lab 17
Version: 1.0.0 | Slot: Production
Deploy time: @DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") UTC
EOF # Build và publish dotnet publish -c Release -o ./publish # Zip artifacts cd publish zip -r ../deploy.zip . cd .. # Deploy lên production slot az webapp deploy \ --resource-group rg-hoatranlab-lab17 \ --name $APP_NAME \ --src-path deploy.zip \ --type zip # Verify: mở browser echo "Mở: https://${APP_NAME}.azurewebsites.net" curl -s "https://${APP_NAME}.azurewebsites.net" | head -20
Getting scm site credentials for zip deployment
Starting zip deployment. This operation can take a while to complete ...
Deployment endpoint responded with status code 202
You can track the url status: https://app-hoatranlab-17xxxx.scm.azurewebsites.net/api/deployments/latest
{
"complete": true,
"deployer": "ZipDeploy",
"id": "latest",
"message": "Deployment successful.",
"status": 4
}
Cấu Hình App Settings & Connection Strings
App Settings trong Azure App Service được inject vào ứng dụng dưới dạng environment variables — ghi đè appsettings.json. Slot settings (sticky) không bị swap khi swap slots, giúp staging và production dùng database khác nhau.
- 1.Web App → Configuration → tab Application settings
- 2.Click + New application setting
- 3.Name:
APP_VERSION| Value:1.0.0-production - 4.Tick Deployment slot setting (sticky) → OK
- 5.Thêm:
ASPNETCORE_ENVIRONMENT=Production(sticky) - 6.Click Save (App sẽ restart)
# Thêm App Settings (non-sticky — sẽ swap cùng slot)
az webapp config appsettings set \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17 \
--settings \
"GREETING=Hello from Azure App Service" \
"LAB_NAME=AZ-104 Lab 17"
# Thêm sticky settings (không swap cùng slot)
az webapp config appsettings set \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17 \
--slot-settings \
"APP_VERSION=1.0.0-production" \
"ASPNETCORE_ENVIRONMENT=Production"
# Xem tất cả app settings
az webapp config appsettings list \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17 \
--output table
# Thêm Connection String (sticky theo slot)
az webapp config connection-string set \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17 \
--connection-string-type SQLServer \
--slot-settings \
DefaultConnection="Server=prod-sql.database.windows.net;Database=ProdDB;"
Deployment Slots — Staging & Swap Zero-Downtime
Deployment slots cho phép chạy nhiều phiên bản app trên cùng App Service Plan. Workflow tiêu chuẩn: deploy lên staging → warm up → test → swap sang production. Rollback = swap ngược lại.
Tạo staging slot:
- 1.Web App → Deployment slots → + Add Slot
- 2.Name:
staging| Clone settings: từ production → Add - 3.URL staging:
app-hoatranlab-17xxx-staging.azurewebsites.net
Swap staging → production:
- 4.Deployment slots → click Swap
- 5.Source: staging | Target: production
- 6.Xem Preview changes → Start Swap
- 7.Sau swap: production URL hiển thị version staging, staging hiển thị version cũ (rollback ready)
# Tạo staging slot
az webapp deployment slot create \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17 \
--slot staging \
--configuration-source $APP_NAME
# Đặt sticky setting riêng cho staging slot
az webapp config appsettings set \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17 \
--slot staging \
--slot-settings \
"APP_VERSION=2.0.0-staging" \
"ASPNETCORE_ENVIRONMENT=Staging"
# Tạo version 2 của app (giả lập new release)
sed -i 's/Version: 1.0.0<\/strong>/Version: 2.0.0<\/strong>/' \
Pages/Index.cshtml
sed -i 's/Slot: Production/Slot: Staging/' Pages/Index.cshtml
# Deploy version 2 lên staging slot
dotnet publish -c Release -o ./publish
cd publish && zip -r ../deploy-v2.zip . && cd ..
az webapp deploy \
--resource-group rg-hoatranlab-lab17 \
--name $APP_NAME \
--slot staging \
--src-path deploy-v2.zip \
--type zip
# Test staging trước khi swap
STAGING_URL="https://${APP_NAME}-staging.azurewebsites.net"
echo "Test staging: $STAGING_URL"
curl -s $STAGING_URL | grep Version
# Swap staging → production (zero downtime)
az webapp deployment slot swap \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17 \
--slot staging \
--target-slot production
# Confirm production đang chạy v2
curl -s "https://${APP_NAME}.azurewebsites.net" | grep Version
# Rollback: swap ngược lại nếu cần
# az webapp deployment slot swap \
# --name $APP_NAME \
# --resource-group rg-hoatranlab-lab17 \
# --slot staging \
# --target-slot production
Logging, Scale Out & Monitoring
Bật App Logs:
- 1.Web App → App Service Logs → Application Logging: File System → Level: Verbose → Save
- 2.Web App → Log stream → xem real-time logs khi truy cập app
Scale Out Manual:
- 3.App Service Plan → Scale out (App Service plan)
- 4.Manual scale: tăng instance count lên 2 → Apply
- 5.Custom autoscale: thêm rule khi CPU > 70% → scale out +1 instance
# Bật app logging vào filesystem
az webapp log config \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17 \
--application-logging filesystem \
--level verbose \
--web-server-logging filesystem
# Stream logs real-time (Ctrl+C để dừng)
az webapp log tail \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17
# Download logs về local
az webapp log download \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17 \
--log-file webapp-logs.zip
# Scale out App Service Plan lên 2 instances
az appservice plan update \
--name plan-hoatranlab-lab17 \
--resource-group rg-hoatranlab-lab17 \
--number-of-workers 2
# Xem metrics (CPU, requests, response time)
az monitor metrics list \
--resource $(az webapp show \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17 \
--query id -o tsv) \
--metric CpuTime \
--interval PT1H \
--output table
Cấu Hình HTTPS Redirect, Always On & Health Check
Các cài đặt production cần thiết: bắt buộc HTTPS, bật Always On (tránh cold start), cấu hình Health Check để load balancer tự loại instance bệnh.
- 1.Web App → Configuration → tab General settings
- 2.HTTPS Only: On (redirect HTTP → HTTPS tự động)
- 3.Always On: On (giữ app warm, tránh cold start 10–30 giây)
- 4.Minimum TLS Version: 1.2 → Save
- 5.Web App → Health check → Enable → Path:
/health→ Save - 6.Thử truy cập http:// → bị redirect sang https:// tự động
# Bật HTTPS Only và Always On
az webapp update \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17 \
--https-only true
# Cấu hình Always On, TLS 1.2, HTTP/2
az webapp config set \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17 \
--always-on true \
--min-tls-version 1.2 \
--http20-enabled true
# Cấu hình Health Check endpoint
az webapp config set \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17 \
--health-check-path "/health"
# Xác nhận cấu hình
az webapp config show \
--name $APP_NAME \
--resource-group rg-hoatranlab-lab17 \
--query "{httpsOnly:httpsOnly,alwaysOn:alwaysOn,minTlsVersion:minTlsVersion,healthCheckPath:healthCheckPath}" \
--output json
# Test: HTTP phải redirect sang HTTPS
curl -I "http://${APP_NAME}.azurewebsites.net"
# Expect: HTTP/1.1 301 Moved Permanently
# Location: https://app-hoatranlab-17xxx.azurewebsites.net/
Kết Quả Đầu Ra Lab 17
https://app-hoatranlab-17xxx.azurewebsites.net hiển thị trang HTML, state: Running
APP_VERSION, ASPNETCORE_ENVIRONMENT có dấu khóa (sticky) trong Portal Configuration
app-hoatranlab-17xxx-staging.azurewebsites.net chạy version 2.0.0
Production URL hiển thị v2.0.0; staging giữ v1.0.0 sẵn sàng rollback
curl -I http://... trả về 301 redirect sang https://... tự động
az webapp log tail hiển thị real-time HTTP request logs khi truy cập URL
Dọn Dẹp Tài Nguyên
App Service Plan S1 tốn ~$0.10/giờ. Xóa ngay sau khi hoàn thành.
# Xóa toàn bộ Resource Group (bao gồm App + Plan + slots) az group delete \ --name rg-hoatranlab-lab17 \ --yes \ --no-wait # Dọn dẹp files local rm -rf HoaTranLabApp publish deploy.zip deploy-v2.zip webapp-logs.zip
Câu Hỏi Ôn Tập
1. Deployment slot swap hoạt động như thế nào? Tại sao swap được coi là "zero downtime" deployment?
Gợi ý: Swap thực chất là đổi routing rules giữa hai slots (đổi IP virtual), không restart app. Staging đã được warm up trước — khi swap, traffic được điều hướng sang staging instance đang chạy sẵn, không có cold start. Rollback = swap lần nữa.
2. Slot settings (sticky settings) khác gì với regular app settings khi thực hiện slot swap?
Gợi ý: Sticky settings gắn với slot, KHÔNG đi theo app khi swap. Regular settings đi theo app content khi swap. Ví dụ: Connection String production DB nên sticky ở production slot — sau swap, staging app vẫn dùng staging DB, production app vẫn dùng production DB.
3. Sự khác biệt giữa Scale Up và Scale Out trong App Service? Khi nào nên dùng mỗi loại?
Gợi ý: Scale Up = tăng tier (B1→S1→P1) — nhiều CPU/RAM hơn cho 1 instance; Scale Out = tăng số instances (1→2→3) — load balancing. Scale Up có giới hạn max tier; Scale Out linh hoạt hơn, tốt cho horizontal workloads. Auto-scale chỉ dùng được với Scale Out.
4. Always On là gì và tại sao quan trọng cho production? Free tier có hỗ trợ Always On không?
Gợi ý: Always On giữ app process luôn chạy, tránh bị unload sau 20 phút idle. Không có Always On → request đầu tiên sau idle sẽ chờ cold start (10–30 giây). Free/Shared tier KHÔNG hỗ trợ Always On — yêu cầu Basic (B1) trở lên.
5. Một App Service Plan có thể chứa tối đa bao nhiêu deployment slots? Tier nào bắt đầu hỗ trợ slots?
Gợi ý: Standard S1 = tối đa 5 slots; Premium P1v3 = tối đa 20 slots. Free và Basic tier KHÔNG hỗ trợ slots. Mỗi slot chạy như một app riêng biệt nhưng chia sẻ compute resources của Plan.