LAB 18 ~4–5 giờ Capstone Project Tổng hợp toàn bộ kỹ năng AZ-104

Capstone Project — Hạ Tầng Azure End-to-End

Dự án tổng hợp cuối khóa: xây dựng hạ tầng Azure hoàn chỉnh cho một web application — VNet & subnets, NSG, 2 VM web sau Load Balancer Standard, Azure Storage & Files, Entra ID RBAC, Azure Backup, Azure Monitor & Alerts, và Azure Bastion để quản trị an toàn.

🎯 Mục Tiêu Dự Án

Thiết kế và xây dựng VNet với nhiều subnet phân tầng (web, management)

Triển khai 2 Linux VM web server sau Standard Load Balancer với health probe

Cấu hình Azure Storage Account và Azure Files mount vào VM

Phân quyền RBAC với Microsoft Entra ID: Admin và ReadOnly roles

Bật Azure Backup cho VM và cấu hình retention policy

Thiết lập Azure Monitor, Log Analytics và Alert khi CPU > 80%

Deploy Azure Bastion để RDP/SSH an toàn không cần public IP trên VM

Verify toàn bộ hệ thống hoạt động end-to-end trước khi dọn dẹp

🏗️ Sơ Đồ Kiến Trúc

┌─────────────────────────── Resource Group: rg-capstone-lab18 (southeastasia) ───────────────────────────────┐
│                                                                                                              │
│   ┌─────────────── VNet: vnet-capstone (10.0.0.0/16) ──────────────────────────────────────────────────┐   │
│   │                                                                                                     │   │
│   │  ┌─── subnet-web (10.0.1.0/24) ─────────────────────────────────────────────────────────────────┐  │   │
│   │  │                                                                                               │  │   │
│   │  │   ┌──────────────┐  NSG-web       ┌──────────────┐  NSG-web                                 │  │   │
│   │  │   │  vm-web-01   │◀──────────────▶│  vm-web-02   │                                          │  │   │
│   │  │   │  Ubuntu 22.04│  HTTP/SSH only  │  Ubuntu 22.04│                                          │  │   │
│   │  │   │  Nginx       │                │  Nginx       │                                          │  │   │
│   │  │   └──────┬───────┘                └──────┬───────┘                                          │  │   │
│   │  │          │                               │                                                   │  │   │
│   │  │          └───────────┬───────────────────┘                                                   │  │   │
│   │  │                      │                                                                        │  │   │
│   │  │              ┌───────▼──────────────────────┐                                                 │  │   │
│   │  │              │  Load Balancer Standard       │◀── Public IP (pip-lb) ── Internet              │  │   │
│   │  │              │  Backend Pool: vm-web-01/02   │                                                 │  │   │
│   │  │              │  Health Probe: HTTP :80 /      │                                                │  │   │
│   │  │              │  Rule: FE-IP:80 → Backend:80   │                                                │  │   │
│   │  │              └──────────────────────────────┘                                                 │  │   │
│   │  └───────────────────────────────────────────────────────────────────────────────────────────────┘  │   │
│   │                                                                                                     │   │
│   │  ┌─── AzureBastionSubnet (10.0.2.0/27) ─────────┐                                                  │   │
│   │  │   ┌──────────────────────────────────────┐    │                                                  │   │
│   │  │   │  Azure Bastion Host                  │◀── pip-bastion (Standard)                             │   │
│   │  │   │  RDP/SSH via HTTPS — không cần       │    │                                                  │   │
│   │  │   │  public IP trên VM                   │    │                                                  │   │
│   │  │   └──────────────────────────────────────┘    │                                                  │   │
│   │  └───────────────────────────────────────────────┘                                                  │   │
│   └─────────────────────────────────────────────────────────────────────────────────────────────────────┘   │
│                                                                                                              │
│   ┌── Storage Account ──────────────────────┐    ┌── Recovery Services Vault ─────────────────────────┐    │
│   │  st-capstone-lab18 (TLS 1.2, LRS)       │    │  vault-backup-lab18                                │    │
│   │  Azure Files: share-web-content         │    │  Policy: daily backup, 30-day retain               │    │
│   │  Blob: web-assets container             │    │  Protected: vm-web-01, vm-web-02                   │    │
│   └─────────────────────────────────────────┘    └──────────────────────────────────────────────────────┘   │
│                                                                                                              │
│   ┌── Monitor & Alerts ─────────────────────┐    ┌── Entra ID RBAC ───────────────────────────────────┐    │
│   │  Log Analytics: law-capstone-lab18       │    │  Contributor: group-web-admins                     │    │
│   │  VM Insights enabled on web VMs          │    │  Reader: group-web-readonly                        │    │
│   │  Alert: CPU > 80% → email notify         │    │  Scope: rg-capstone-lab18                          │    │
│   └─────────────────────────────────────────┘    └──────────────────────────────────────────────────────┘   │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

📋 Chuẩn Bị

Yêu cầu tiên quyết:
  • Hoàn thành Lab 01 → Lab 17 (hoặc nắm vững các concept)
  • Azure subscription với Contributor role
  • Azure CLI 2.x đã cài và az login
  • Quyền tạo Entra ID groups và users (hoặc Global Admin)
Ước tính chi phí:
  • 2x Standard_B2s VM: ~$0.10/giờ → ~$0.50 nếu làm 5h
  • Load Balancer Standard: ~$0.025/giờ
  • Azure Bastion Developer: miễn phí (dev tier)
  • Xóa RG ngay sau lab để tránh phát sinh chi phí

🧪 Các Giai Đoạn Thực Hiện

Giai đoạn 1

Nền Tảng Mạng — VNet, Subnet, NSG

Cách 1 — Azure Portal
  1. 1.1Tạo RG: rg-capstone-lab18 tại Southeast Asia
  2. 1.2VNet: vnet-capstone, address: 10.0.0.0/16
  3. 1.3Subnet web: subnet-web10.0.1.0/24
  4. 1.4Subnet Bastion: AzureBastionSubnet10.0.2.0/27 (tên phải chính xác)
  5. 1.5NSG: nsg-web → Inbound: Allow HTTP 80 (priority 100), Allow HTTPS 443 (priority 110). Deny SSH/RDP từ internet (Bastion sẽ xử lý). Gắn NSG vào subnet-web.
Cách 2 — Azure CLI
Azure CLI— Giai đoạn 1: Network Foundation
# Biến môi trường dùng xuyên suốt dự án
RG="rg-capstone-lab18"
LOCATION="southeastasia"
VNET="vnet-capstone"

# Tạo Resource Group
az group create --name $RG --location $LOCATION \
  --tags "project=capstone" "lab=18" "owner=hoatranlab"

# Tạo VNet với 2 subnet
az network vnet create \
  --resource-group $RG \
  --name $VNET \
  --address-prefix 10.0.0.0/16 \
  --subnet-name subnet-web \
  --subnet-prefix 10.0.1.0/24 \
  --location $LOCATION

# Thêm AzureBastionSubnet (tên bắt buộc, /27 tối thiểu)
az network vnet subnet create \
  --resource-group $RG \
  --vnet-name $VNET \
  --name AzureBastionSubnet \
  --address-prefix 10.0.2.0/27

# Tạo NSG cho web subnet
az network nsg create \
  --resource-group $RG \
  --name nsg-web \
  --location $LOCATION

# Inbound rules: HTTP và HTTPS
az network nsg rule create \
  --resource-group $RG --nsg-name nsg-web \
  --name Allow-HTTP --priority 100 \
  --protocol Tcp --destination-port-range 80 --access Allow

az network nsg rule create \
  --resource-group $RG --nsg-name nsg-web \
  --name Allow-HTTPS --priority 110 \
  --protocol Tcp --destination-port-range 443 --access Allow

# Gắn NSG vào subnet-web
az network vnet subnet update \
  --resource-group $RG \
  --vnet-name $VNET \
  --name subnet-web \
  --network-security-group nsg-web
Giai đoạn 2

VM Web Servers & Standard Load Balancer

Cách 1 — Azure Portal
  1. 2.1Tạo vm-web-01: Ubuntu Server 22.04, size Standard_B2s, subnet-web, không có public IP, Availability Zone 1
  2. 2.2Tạo vm-web-02: tương tự, Availability Zone 2
  3. 2.3Load Balancer → + Create → SKU: Standard, Type: Public, Tier: Regional
  4. 2.4Frontend: tạo Public IP mới pip-lb-capstone (SKU Standard)
  5. 2.5Backend pool: thêm vm-web-01 và vm-web-02
  6. 2.6Health probe: HTTP, port 80, path /, interval 5 giây
  7. 2.7Load balancing rule: Frontend port 80 → Backend port 80, Session persistence: None
Azure CLI— Giai đoạn 2: VM + Load Balancer
RG="rg-capstone-lab18"
LOCATION="southeastasia"
VNET="vnet-capstone"

# Tạo Public IP Standard cho Load Balancer
az network public-ip create \
  --resource-group $RG --name pip-lb-capstone \
  --sku Standard --allocation-method Static \
  --zone 1 2 3 --location $LOCATION

# Tạo Load Balancer Standard
az network lb create \
  --resource-group $RG --name lb-capstone \
  --sku Standard --location $LOCATION \
  --frontend-ip-name fe-config \
  --public-ip-address pip-lb-capstone \
  --backend-pool-name backend-web

# Health probe HTTP
az network lb probe create \
  --resource-group $RG --lb-name lb-capstone \
  --name probe-http --protocol Http \
  --port 80 --path / --interval 5

# Load balancing rule
az network lb rule create \
  --resource-group $RG --lb-name lb-capstone \
  --name rule-http --protocol Tcp \
  --frontend-port 80 --backend-port 80 \
  --frontend-ip-name fe-config \
  --backend-pool-name backend-web \
  --probe-name probe-http

# Tạo vm-web-01 (không có public IP — dùng Bastion để truy cập)
az vm create \
  --resource-group $RG --name vm-web-01 \
  --image Ubuntu2204 --size Standard_B2s \
  --admin-username azureuser --generate-ssh-keys \
  --vnet-name $VNET --subnet subnet-web \
  --public-ip-address "" --nsg "" \
  --zone 1 --location $LOCATION

# Tạo vm-web-02
az vm create \
  --resource-group $RG --name vm-web-02 \
  --image Ubuntu2204 --size Standard_B2s \
  --admin-username azureuser --generate-ssh-keys \
  --vnet-name $VNET --subnet subnet-web \
  --public-ip-address "" --nsg "" \
  --zone 2 --location $LOCATION

# Lấy NIC ID để thêm vào backend pool
NIC01=$(az vm show -g $RG -n vm-web-01 --query "networkProfile.networkInterfaces[0].id" -o tsv)
NIC02=$(az vm show -g $RG -n vm-web-02 --query "networkProfile.networkInterfaces[0].id" -o tsv)
IPCONFIG01=$(az network nic show --ids $NIC01 --query "ipConfigurations[0].name" -o tsv)
IPCONFIG02=$(az network nic show --ids $NIC02 --query "ipConfigurations[0].name" -o tsv)

# Thêm VM vào backend pool
az network nic ip-config address-pool add \
  --resource-group $RG --lb-name lb-capstone \
  --address-pool backend-web \
  --nic-name $(basename $NIC01) --ip-config-name $IPCONFIG01

az network nic ip-config address-pool add \
  --resource-group $RG --lb-name lb-capstone \
  --address-pool backend-web \
  --nic-name $(basename $NIC02) --ip-config-name $IPCONFIG02

# Cài Nginx trên cả 2 VM qua run-command
az vm run-command invoke \
  --resource-group $RG --name vm-web-01 \
  --command-id RunShellScript \
  --scripts "apt-get update -y && apt-get install -y nginx && echo '<h1>vm-web-01 - HoaTranLab Capstone</h1>' > /var/www/html/index.html && systemctl enable nginx && systemctl start nginx"

az vm run-command invoke \
  --resource-group $RG --name vm-web-02 \
  --command-id RunShellScript \
  --scripts "apt-get update -y && apt-get install -y nginx && echo '<h1>vm-web-02 - HoaTranLab Capstone</h1>' > /var/www/html/index.html && systemctl enable nginx && systemctl start nginx"
Kết quả (Output)— Verify Load Balancer
# Lấy Public IP của Load Balancer
az network public-ip show -g rg-capstone-lab18 -n pip-lb-capstone --query ipAddress -o tsv
# Output: 20.xxx.xxx.xxx

# Test load balancing (chạy nhiều lần để thấy round-robin)
curl http://20.xxx.xxx.xxx
# Lần 1: <h1>vm-web-01 - HoaTranLab Capstone</h1>
# Lần 2: <h1>vm-web-02 - HoaTranLab Capstone</h1>
# Xác nhận: Load Balancer phân phối traffic đều giữa 2 VM
Giai đoạn 3

Azure Storage Account & Azure Files

Cách 1 — Azure Portal
  1. 3.1Storage accounts → + Create → RG: rg-capstone-lab18, Name: stcapstonelab18 (lowercase, unique)
  2. 3.2Performance: Standard, Redundancy: LRS, TLS: 1.2 minimum
  3. 3.3File shares → + File share → Name: share-web-content, Tier: Transaction optimized
  4. 3.4Containers → + Container → Name: web-assets, Access: Private
Azure CLI— Giai đoạn 3: Storage
RG="rg-capstone-lab18"
STORAGE="stcapstonelab18"

# Tạo Storage Account với TLS 1.2 bắt buộc
az storage account create \
  --resource-group $RG \
  --name $STORAGE \
  --location southeastasia \
  --sku Standard_LRS \
  --kind StorageV2 \
  --min-tls-version TLS1_2 \
  --allow-blob-public-access false

# Tạo Azure Files share
az storage share create \
  --account-name $STORAGE \
  --name share-web-content \
  --quota 50

# Tạo Blob container
az storage container create \
  --account-name $STORAGE \
  --name web-assets \
  --public-access off

# Lấy connection string để mount Azure Files trên VM
CONN=$(az storage account show-connection-string \
  --resource-group $RG \
  --name $STORAGE \
  --query connectionString -o tsv)

# Mount Azure Files vào vm-web-01
az vm run-command invoke \
  --resource-group $RG --name vm-web-01 \
  --command-id RunShellScript \
  --scripts "
    sudo mkdir -p /mnt/web-content
    sudo apt-get install -y cifs-utils
    STORAGE_KEY=\$(az storage account keys list --account-name $STORAGE --query '[0].value' -o tsv 2>/dev/null || echo 'KEY_HERE')
    sudo mount -t cifs //$STORAGE.file.core.windows.net/share-web-content /mnt/web-content \
      -o vers=3.0,username=$STORAGE,password=\$STORAGE_KEY,dir_mode=0777,file_mode=0777
  "
Giai đoạn 4

Microsoft Entra ID — RBAC & Identity

Cách 1 — Azure Portal
  1. 4.1Microsoft Entra ID → Groups → + New group → group-web-admins (Security type)
  2. 4.2Tạo group thứ 2: group-web-readonly
  3. 4.3Tạo test user: webadmin@<tenant>.onmicrosoft.com → thêm vào group-web-admins
  4. 4.4RG rg-capstone-lab18 → Access control (IAM) → + Add role assignment
  5. 4.5Role: Contributor → Members: group-web-admins → Review + Assign
  6. 4.6Thêm assignment thứ 2: Role: Reader → Members: group-web-readonly
Azure CLI— Giai đoạn 4: Entra ID RBAC
RG="rg-capstone-lab18"

# Tạo Entra ID groups
az ad group create \
  --display-name "group-web-admins" \
  --mail-nickname "group-web-admins"

az ad group create \
  --display-name "group-web-readonly" \
  --mail-nickname "group-web-readonly"

# Lấy Object ID của các group
ADMIN_GRP=$(az ad group show --group "group-web-admins" --query id -o tsv)
READ_GRP=$(az ad group show --group "group-web-readonly" --query id -o tsv)

# Lấy Subscription ID và RG resource ID
SUB_ID=$(az account show --query id -o tsv)
RG_ID="/subscriptions/$SUB_ID/resourceGroups/$RG"

# Gán Contributor cho group-web-admins ở scope RG
az role assignment create \
  --assignee-object-id $ADMIN_GRP \
  --assignee-principal-type Group \
  --role "Contributor" \
  --scope $RG_ID

# Gán Reader cho group-web-readonly
az role assignment create \
  --assignee-object-id $READ_GRP \
  --assignee-principal-type Group \
  --role "Reader" \
  --scope $RG_ID

# Xác nhận assignments
az role assignment list --scope $RG_ID --output table
Giai đoạn 5

Azure Backup — Bảo Vệ VM

Cách 1 — Azure Portal
  1. 5.1Recovery Services vaults → + Create → RG: rg-capstone-lab18, Name: vault-backup-lab18, Region: Southeast Asia
  2. 5.2Vault → Backup → Workload: Azure, What to backup: Virtual machine → Backup
  3. 5.3Backup policy: DefaultPolicy (daily backup, 30-day retention) hoặc tạo custom policy
  4. 5.4Add VMs: chọn vm-web-01vm-web-02 → Enable Backup
  5. 5.5Backup items → Azure Virtual Machine → thấy 2 VM với status "Backup not triggered" → Backup now để trigger ngay
Azure CLI— Giai đoạn 5: Azure Backup
RG="rg-capstone-lab18"

# Tạo Recovery Services Vault
az backup vault create \
  --resource-group $RG \
  --name vault-backup-lab18 \
  --location southeastasia

# Bật backup cho vm-web-01 với DefaultPolicy
az backup protection enable-for-vm \
  --resource-group $RG \
  --vault-name vault-backup-lab18 \
  --vm vm-web-01 \
  --policy-name DefaultPolicy

# Bật backup cho vm-web-02
az backup protection enable-for-vm \
  --resource-group $RG \
  --vault-name vault-backup-lab18 \
  --vm vm-web-02 \
  --policy-name DefaultPolicy

# Trigger backup ngay (không chờ schedule)
az backup protection backup-now \
  --resource-group $RG \
  --vault-name vault-backup-lab18 \
  --container-name "IaasVMContainer;iaasvmcontainerv2;$RG;vm-web-01" \
  --item-name "VM;iaasvmcontainerv2;$RG;vm-web-01" \
  --retain-until 2026-06-21

# Kiểm tra backup jobs
az backup job list \
  --resource-group $RG \
  --vault-name vault-backup-lab18 \
  --output table
Giai đoạn 6

Azure Monitor, Log Analytics & Alert Rules

Cách 1 — Azure Portal
  1. 6.1Log Analytics workspaces → + Create → RG: rg-capstone-lab18, Name: law-capstone-lab18
  2. 6.2vm-web-01 → Insights → Enable → chọn workspace law-capstone-lab18
  3. 6.3Tương tự vm-web-02 → Enable Insights
  4. 6.4Monitor → Alerts → + Create alert rule → Scope: vm-web-01
  5. 6.5Condition: Percentage CPU → Threshold: 80, Aggregation: Average, Frequency: 5 phút
  6. 6.6Action group → + Create → Email action → nhập email của bạn
  7. 6.7Alert rule name: alert-cpu-high-web01, Severity: 2 — Warning → Create
Azure CLI— Giai đoạn 6: Monitor & Alerts
RG="rg-capstone-lab18"
SUB_ID=$(az account show --query id -o tsv)

# Tạo Log Analytics Workspace
az monitor log-analytics workspace create \
  --resource-group $RG \
  --workspace-name law-capstone-lab18 \
  --location southeastasia

LAW_ID=$(az monitor log-analytics workspace show \
  --resource-group $RG \
  --workspace-name law-capstone-lab18 \
  --query id -o tsv)

# Tạo Action Group với email alert
az monitor action-group create \
  --resource-group $RG \
  --name ag-web-ops \
  --short-name web-ops \
  --action email email-admin [email protected]

AG_ID=$(az monitor action-group show \
  --resource-group $RG \
  --name ag-web-ops \
  --query id -o tsv)

VM01_ID=$(az vm show -g $RG -n vm-web-01 --query id -o tsv)

# Tạo Alert Rule: CPU > 80%
az monitor metrics alert create \
  --resource-group $RG \
  --name alert-cpu-high-web01 \
  --scopes $VM01_ID \
  --condition "avg Percentage CPU > 80" \
  --window-size 5m \
  --evaluation-frequency 5m \
  --severity 2 \
  --action $AG_ID \
  --description "CPU vượt 80% trên vm-web-01"

# Xem alert rules đã tạo
az monitor metrics alert list \
  --resource-group $RG \
  --output table
Giai đoạn 7

Azure Bastion — Quản Trị VM An Toàn

Azure Bastion cung cấp RDP/SSH qua HTTPS trực tiếp từ trình duyệt — VM không cần có public IP, không cần mở RDP/SSH ra ngoài internet. Đây là best practice bảo mật theo Zero-Trust model.

Cách 1 — Azure Portal
  1. 7.1Bastions → + Create → RG: rg-capstone-lab18, Name: bastion-capstone
  2. 7.2Tier: Developer (miễn phí, không cần public IP riêng cho Bastion Developer)
  3. 7.3VNet: vnet-capstone (AzureBastionSubnet tự detect) → Review + Create
  4. 7.4Chờ ~5-10 phút → vm-web-01 → Connect → Bastion → nhập username: azureuser và SSH key
  5. 7.5Browser mở terminal SSH — xác nhận kết nối thành công, chạy nginx -v
Azure CLI— Giai đoạn 7: Bastion (Standard tier)
RG="rg-capstone-lab18"
VNET="vnet-capstone"

# Tạo Public IP cho Bastion Standard (nếu không dùng Developer tier)
az network public-ip create \
  --resource-group $RG \
  --name pip-bastion-capstone \
  --sku Standard \
  --allocation-method Static \
  --location southeastasia

# Tạo Bastion Standard tier
az network bastion create \
  --resource-group $RG \
  --name bastion-capstone \
  --vnet-name $VNET \
  --public-ip-address pip-bastion-capstone \
  --location southeastasia \
  --sku Standard

# Sau khi tạo xong, SSH vào VM qua Bastion (mở browser)
# Portal → vm-web-01 → Connect → Bastion → SSH

# Hoặc dùng CLI tunnel (yêu cầu az network bastion extension)
az network bastion ssh \
  --resource-group $RG \
  --name bastion-capstone \
  --target-resource-id $(az vm show -g $RG -n vm-web-01 --query id -o tsv) \
  --auth-type "ssh-key" \
  --username azureuser \
  --ssh-key ~/.ssh/id_rsa
Kết quả (Output)— Verify trong SSH session qua Bastion
azureuser@vm-web-01:~$ nginx -v
nginx version: nginx/1.18.0 (Ubuntu)

azureuser@vm-web-01:~$ systemctl status nginx
● nginx.service - A high performance web server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled)
     Active: active (running) since Wed 2026-05-21 10:00:00 UTC

azureuser@vm-web-01:~$ ls /mnt/web-content
# Azure Files share mount thành công

azureuser@vm-web-01:~$ hostname
vm-web-01
# Xác nhận đang trong VM đúng, không có public IP expose
Giai đoạn 8

Verify End-to-End — Kiểm Tra Toàn Bộ Hệ Thống

Azure CLI— Final verification checklist
RG="rg-capstone-lab18"

# 1. Verify Load Balancer và web traffic
LB_IP=$(az network public-ip show -g $RG -n pip-lb-capstone --query ipAddress -o tsv)
echo "Load Balancer IP: $LB_IP"
for i in {1..6}; do curl -s http://$LB_IP | grep -o 'vm-web-0[12]'; done
# Expected: round-robin giữa vm-web-01 và vm-web-02

# 2. Verify NSG rules
az network nsg rule list -g $RG --nsg-name nsg-web --output table

# 3. Verify Storage Account TLS
az storage account show -g $RG -n stcapstonelab18 \
  --query "minimumTlsVersion" -o tsv
# Expected: TLS1_2

# 4. Verify RBAC assignments
az role assignment list --scope "/subscriptions/$(az account show --query id -o tsv)/resourceGroups/$RG" \
  --output table

# 5. Verify Backup protection
az backup protection check-vm \
  --resource-group $RG \
  --vault-name vault-backup-lab18 \
  --vm vm-web-01

# 6. Verify Alert rules
az monitor metrics alert list -g $RG --output table

# 7. Verify tất cả resources trong RG
az resource list -g $RG --output table
Kết quả (Output)— az resource list -g rg-capstone-lab18
Name                    ResourceType                                     Location
----------------------  -----------------------------------------------  -------------
vnet-capstone           Microsoft.Network/virtualNetworks                southeastasia
nsg-web                 Microsoft.Network/networkSecurityGroups          southeastasia
pip-lb-capstone         Microsoft.Network/publicIPAddresses              southeastasia
lb-capstone             Microsoft.Network/loadBalancers                  southeastasia
vm-web-01               Microsoft.Compute/virtualMachines                southeastasia
vm-web-02               Microsoft.Compute/virtualMachines                southeastasia
stcapstonelab18         Microsoft.Storage/storageAccounts                southeastasia
vault-backup-lab18      Microsoft.RecoveryServices/vaults                southeastasia
law-capstone-lab18      Microsoft.OperationalInsights/workspaces         southeastasia
bastion-capstone        Microsoft.Network/bastionHosts                   southeastasia
pip-bastion-capstone    Microsoft.Network/publicIPAddresses              southeastasia
alert-cpu-high-web01    Microsoft.Insights/metricAlerts                  southeastasia

🧹 Dọn Dẹp Tài Nguyên

Azure CLI— Xóa toàn bộ capstone project
# Xóa toàn bộ Resource Group (bao gồm mọi resource)
az group delete \
  --name rg-capstone-lab18 \
  --yes \
  --no-wait

# Xóa Entra ID groups
az ad group delete --group "group-web-admins"
az ad group delete --group "group-web-readonly"

# Xác nhận dọn sạch
az group list --output table | grep capstone
# Expected: không có kết quả nào

📊 Kết Quả Đầu Ra — Capstone Project

VNet với subnet phân tầng

vnet-capstone, subnet-web, AzureBastionSubnet — NSG bảo vệ subnet-web

Load Balancer phân phối traffic

curl LB IP → round-robin giữa vm-web-01 và vm-web-02, health probe HTTP hoạt động

Storage TLS 1.2 và Files mount

minimumTlsVersion: TLS1_2, Azure Files mount thành công trên VM

Entra ID RBAC cấu hình đúng

group-web-admins: Contributor, group-web-readonly: Reader — cả hai ở scope RG

Backup đang bảo vệ cả 2 VM

vault-backup-lab18, DefaultPolicy, vm-web-01 và vm-web-02 đều Protected

Alert CPU kích hoạt email

alert-cpu-high-web01: CPU > 80% → email notification qua Action Group

Bastion SSH thành công, không cần public IP

Kết nối SSH vào vm-web-01/02 qua browser mà không expose RDP/SSH ra internet — Zero-Trust model

❓ Câu Hỏi Ôn Tập — Tổng Hợp

1. Tại sao Load Balancer Standard bắt buộc dùng Public IP Standard? Điều gì xảy ra nếu dùng Public IP Basic?

Gợi ý: Basic LB + Basic IP đã deprecated. Standard LB yêu cầu Standard IP vì hỗ trợ zone-redundancy, cross-zone balancing. Basic không hỗ trợ Availability Zones.

2. Tại sao Azure Bastion Subnet phải đặt tên CHÍNH XÁC là "AzureBastionSubnet"? Kích thước tối thiểu là bao nhiêu?

Gợi ý: Azure platform check tên chính xác để deploy Bastion. Tối thiểu /27 (32 địa chỉ) — Azure dùng một số IP cho internal components.

3. Trong kiến trúc này, tại sao VM web không có public IP? Lợi ích bảo mật là gì?

Gợi ý: Giảm attack surface — không có IP công khai thì không thể scan/attack trực tiếp. Traffic vào chỉ qua LB port 80/443. Quản trị chỉ qua Bastion. Zero-Trust networking.

4. RBAC scope ở Resource Group level khác gì với Subscription level và Resource level?

Gợi ý: Subscription = toàn bộ Azure resources. RG = chỉ resources trong RG đó. Resource = chỉ một resource cụ thể. Nguyên tắc: grant minimum privilege cần thiết — prefer RG scope thay vì Subscription.

5. Nếu vm-web-01 bị crash, hệ thống này hoạt động thế nào? Các service nào bị ảnh hưởng, service nào không?

Gợi ý: LB health probe phát hiện vm-web-01 down → stop routing traffic → 100% sang vm-web-02. Bastion vẫn kết nối được vm-web-02. Backup vault vẫn bảo vệ vm-web-02. Monitor vẫn alert. → High availability nhờ 2-VM + LB.

Lab 17: ASP.NET Web App Về Thư Viện Labs
Zalo