🎯 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ị
- 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)
- 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
Nền Tảng Mạng — VNet, Subnet, NSG
- 1.1Tạo RG:
rg-capstone-lab18tại Southeast Asia - 1.2VNet:
vnet-capstone, address: 10.0.0.0/16 - 1.3Subnet web:
subnet-web→ 10.0.1.0/24 - 1.4Subnet Bastion:
AzureBastionSubnet→ 10.0.2.0/27 (tên phải chính xác) - 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.
# 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
VM Web Servers & Standard Load Balancer
- 2.1Tạo vm-web-01: Ubuntu Server 22.04, size Standard_B2s, subnet-web, không có public IP, Availability Zone 1
- 2.2Tạo vm-web-02: tương tự, Availability Zone 2
- 2.3Load Balancer → + Create → SKU: Standard, Type: Public, Tier: Regional
- 2.4Frontend: tạo Public IP mới
pip-lb-capstone(SKU Standard) - 2.5Backend pool: thêm vm-web-01 và vm-web-02
- 2.6Health probe: HTTP, port 80, path /, interval 5 giây
- 2.7Load balancing rule: Frontend port 80 → Backend port 80, Session persistence: None
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"
# 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
Azure Storage Account & Azure Files
- 3.1Storage accounts → + Create → RG: rg-capstone-lab18, Name:
stcapstonelab18(lowercase, unique) - 3.2Performance: Standard, Redundancy: LRS, TLS: 1.2 minimum
- 3.3File shares → + File share → Name:
share-web-content, Tier: Transaction optimized - 3.4Containers → + Container → Name:
web-assets, Access: Private
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
"
Microsoft Entra ID — RBAC & Identity
- 4.1Microsoft Entra ID → Groups → + New group →
group-web-admins(Security type) - 4.2Tạo group thứ 2:
group-web-readonly - 4.3Tạo test user:
webadmin@<tenant>.onmicrosoft.com→ thêm vào group-web-admins - 4.4RG rg-capstone-lab18 → Access control (IAM) → + Add role assignment
- 4.5Role: Contributor → Members: group-web-admins → Review + Assign
- 4.6Thêm assignment thứ 2: Role: Reader → Members: group-web-readonly
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
Azure Backup — Bảo Vệ VM
- 5.1Recovery Services vaults → + Create → RG: rg-capstone-lab18, Name:
vault-backup-lab18, Region: Southeast Asia - 5.2Vault → Backup → Workload: Azure, What to backup: Virtual machine → Backup
- 5.3Backup policy: DefaultPolicy (daily backup, 30-day retention) hoặc tạo custom policy
- 5.4Add VMs: chọn vm-web-01 và vm-web-02 → Enable Backup
- 5.5Backup items → Azure Virtual Machine → thấy 2 VM với status "Backup not triggered" → Backup now để trigger ngay
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
Azure Monitor, Log Analytics & Alert Rules
- 6.1Log Analytics workspaces → + Create → RG: rg-capstone-lab18, Name:
law-capstone-lab18 - 6.2vm-web-01 → Insights → Enable → chọn workspace law-capstone-lab18
- 6.3Tương tự vm-web-02 → Enable Insights
- 6.4Monitor → Alerts → + Create alert rule → Scope: vm-web-01
- 6.5Condition: Percentage CPU → Threshold: 80, Aggregation: Average, Frequency: 5 phút
- 6.6Action group → + Create → Email action → nhập email của bạn
- 6.7Alert rule name:
alert-cpu-high-web01, Severity: 2 — Warning → Create
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
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.
- 7.1Bastions → + Create → RG: rg-capstone-lab18, Name:
bastion-capstone - 7.2Tier: Developer (miễn phí, không cần public IP riêng cho Bastion Developer)
- 7.3VNet: vnet-capstone (AzureBastionSubnet tự detect) → Review + Create
- 7.4Chờ ~5-10 phút → vm-web-01 → Connect → Bastion → nhập username: azureuser và SSH key
- 7.5Browser mở terminal SSH — xác nhận kết nối thành công, chạy
nginx -v
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
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
Verify End-to-End — Kiểm Tra Toàn Bộ Hệ Thống
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
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
# 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-capstone, subnet-web, AzureBastionSubnet — NSG bảo vệ subnet-web
curl LB IP → round-robin giữa vm-web-01 và vm-web-02, health probe HTTP hoạt động
minimumTlsVersion: TLS1_2, Azure Files mount thành công trên VM
group-web-admins: Contributor, group-web-readonly: Reader — cả hai ở scope RG
vault-backup-lab18, DefaultPolicy, vm-web-01 và vm-web-02 đều Protected
alert-cpu-high-web01: CPU > 80% → email notification qua Action Group
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.