เทมเพลตแบบแยกส่วน
การทําให้เป็นโมดูลาร์ของเทมเพลต เป็นแนวทางปฏิบัติที่ดีที่สุดที่แบ่งเทมเพลตขนาดใหญ่ที่ซับซ้อนออกเป็นส่วนประกอบที่เล็กลงและนํากลับมาใช้ใหม่ได้ วิธีนี้ช่วยเพิ่มความสามารถในการบํารุงรักษา ส่งเสริมการนํากลับมาใช้ใหม่ และทําให้เทมเพลตง่ายต่อการทดสอบและทําความเข้าใจ
เหตุใดจึงต้องทําให้เทมเพลตเป็นโมดูล
ประโยชน์ของการทําให้เป็นโมดูลาร์:
- การนํากลับมาใช้ใหม่: สร้างเทมเพลตเครือข่ายเพียงครั้งเดียวและใช้กับหลายโครงการ
- การบํารุงรักษา: อัปเดตโมดูลหนึ่งโมดูลแทนการแก้ไขเทมเพลตขนาดใหญ่หลายรายการ
- การทํางานร่วมกันเป็นทีม: ทีมต่างๆ สามารถเป็นเจ้าของโมดูลที่แตกต่างกันได้ (เครือข่าย ความปลอดภัย การประมวลผล)
- การทดสอบ: ทดสอบแต่ละโมดูลแยกกันก่อนเขียน
- การแยกข้อกังวล: แต่ละเทมเพลตมุ่งเน้นไปที่โดเมนโครงสร้างพื้นฐานเฉพาะ
- การควบคุมเวอร์ชัน: ติดตามการเปลี่ยนแปลงของแต่ละส่วนประกอบอย่างอิสระ
ตัวอย่างในโลกแห่งความเป็นจริง: สร้างเทมเพลตแยกต่างหากสําหรับ:
- โมดูลเครือข่าย: เครือข่ายเสมือน, ซับเน็ต, NSG, ตารางเส้นทาง
- โมดูลการจัดเก็บข้อมูล: บัญชีที่เก็บข้อมูล คอนเทนเนอร์ Blob การแชร์ไฟล์
- โมดูลการประมวลผล: เครื่องเสมือน ชุดความพร้อมใช้งาน โหลดบาลานเซอร์
- โมดูลความปลอดภัย: Key Vault, ข้อมูลประจําตัวที่มีการจัดการ, การกําหนด RBAC
เทมเพลตที่เชื่อมโยง
แม่แบบที่เชื่อมโยง ช่วยให้คุณสามารถอ้างอิงไฟล์แม่แบบภายนอกจากแม่แบบหลักได้ นี่เป็นวิธีการหลักในการสร้างสถาปัตยกรรมเทมเพลต ARM แบบแยกส่วน
วิธีการทํางาน:
- จัดเก็บเทมเพลตย่อยในตําแหน่งที่สามารถเข้าถึงได้ (ที่เก็บข้อมูล Azure, GitHub เป็นต้น)
- เทมเพลตหลักอ้างอิงเทมเพลตภายนอกผ่าน URI
- Resource Manager ดาวน์โหลดและดําเนินการเทมเพลตที่เชื่อมโยงระหว่างการปรับใช้
วากยสัมพันธ์: เพิ่มทรัพยากรการปรับใช้ไปยังเทมเพลตหลักของคุณ:
"resources": [
{
"apiVersion": "2022-09-01",
"name": "linkedTemplate",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "https://mystorageaccount.blob.core.windows.net/templates/networking.json",
"contentVersion": "1.0.0.0"
},
"parameters": {
"vnetName": {
"value": "[parameters('virtualNetworkName')]"
},
"location": {
"value": "[parameters('location')]"
}
}
}
}
]
คุณสมบัติที่สําคัญ:
-
ประเภท:
Microsoft.Resources/deploymentsระบุการปรับใช้ที่ซ้อนกันหรือเชื่อมโยง - โหมด: โหมดการปรับใช้ (ส่วนเพิ่มหรือเสร็จสมบูรณ์)
- templateLink: ชี้ไปที่ URI เทมเพลตภายนอก
- พารามิเตอร์: ค่าที่ส่งผ่านไปยังเทมเพลตที่เชื่อมโยง
ตัวอย่างที่สมบูรณ์พร้อมเทมเพลตที่เชื่อมโยงหลายแบบ:
"resources": [
{
"name": "networkingDeployment",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[concat(parameters('templateBaseUrl'), '/networking.json')]"
},
"parameters": {
"vnetName": { "value": "[parameters('vnetName')]" }
}
}
},
{
"name": "storageDeployment",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"dependsOn": [
"[resourceId('Microsoft.Resources/deployments', 'networkingDeployment')]"
],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[concat(parameters('templateBaseUrl'), '/storage.json')]"
}
}
}
]
เทมเพลตที่ซ้อนกัน
เทมเพลตที่ซ้อนกันช่วยให้คุณสามารถฝังเทมเพลตที่สมบูรณ์ได้โดยตรงภายในเทมเพลตหลักโดยใช้templateคุณสมบัติแทนtemplateLink
เมื่อใดที่ควรใช้เทมเพลตที่ซ้อนกัน:
- สถานการณ์ง่ายๆ: ส่วนประกอบขนาดเล็กในตัวเองที่ไม่ต้องการไฟล์ภายนอก
- ตรรกะส่วนตัว: ตรรกะของเทมเพลตที่คุณไม่ต้องการเปิดเผยต่อภายนอก
- การสร้างแบบไดนามิก: สร้างเนื้อหาเทมเพลตโดยทางโปรแกรมระหว่างการปรับใช้
ข้อเสียเปรียบ: การซ้อนคอมโพเนนต์ขนาดใหญ่จะสร้างไฟล์หลักขนาดใหญ่ ทําให้ดูแลรักษาและอ่านได้ยากขึ้น
"resources": [
{
"apiVersion": "2022-09-01",
"name": "nestedStorageTemplate",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2023-01-01",
"name": "[variables('storageName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard_LRS"
},
"kind": "StorageV2",
"properties": {
"supportsHttpsTrafficOnly": true
}
}
]
}
}
}
]
ข้อจํากัดที่สําคัญ:
โน้ต
ขอบเขตเทมเพลตที่ซ้อนกัน: เทมเพลตที่ซ้อนกันสามารถใช้พารามิเตอร์และตัวแปรจากเทมเพลตหลักเท่านั้น คุณไม่สามารถกําหนดพารามิเตอร์หรือตัวแปรใหม่ภายในเทมเพลตที่ซ้อนกันได้
เทมเพลตที่เชื่อมโยงกับเทมเพลตที่ซ้อนกัน:
| คุณสมบัติ | เทมเพลตที่เชื่อมโยง | เทมเพลตที่ซ้อนกัน |
|---|---|---|
| ตำแหน่ง | ไฟล์ภายนอก (URI) | อินไลน์ภายในเทมเพลตหลัก |
| ความสามารถในการนํากลับมาใช้ใหม่ | สูง - ใช้ในทุกโครงการ | ต่ํา - ผูกกับเทมเพลตหลัก |
| ความสามารถในการดูแลรักษา | ง่าย - แยกไฟล์ | ยากขึ้น - ฝังอยู่ในไฟล์หลัก |
| พารามิเตอร์ | สามารถกําหนดพารามิเตอร์ของตัวเองได้ | ใช้พารามิเตอร์เทมเพลตหลักเท่านั้น |
| ตัว แปร | สามารถกําหนดตัวแปรของตัวเองได้ | ใช้ตัวแปรเทมเพลตหลักเท่านั้น |
| ขนาด | ไม่มีผลกระทบต่อเทมเพลตหลัก | เพิ่มขนาดเทมเพลตหลัก |
| ที่ดีที่สุดสําหรับ | สถาปัตยกรรมโมดูลาร์การผลิต | ส่วนประกอบที่เรียบง่ายและครั้งเดียว |
การแนะนํา: ใช้ เทมเพลตที่เชื่อมโยง สําหรับสถานการณ์การใช้งานจริงและ เทมเพลตที่ซ้อนกัน สําหรับส่วนประกอบที่เรียบง่ายและไม่สามารถนํากลับมาใช้ใหม่ได้เท่านั้น
โหมดการปรับใช้
เมื่อปรับใช้เทมเพลต คุณต้องเลือก โหมดการปรับใช้ ที่กําหนดวิธีที่ Resource Manager จัดการกับทรัพยากรที่มีอยู่ในกลุ่มทรัพยากรเป้าหมาย
สามตัวเลือกการปรับใช้
โหมดตรวจสอบความถูกต้อง
วัตถุประสงค์: ทดสอบเทมเพลตโดยไม่ต้องทําการเปลี่ยนแปลง
หน้าที่:
- คอมไพล์เทมเพลตและตรวจสอบไวยากรณ์ JSON
- ตรวจสอบตรรกะการปรับใช้ (ไม่มีการขึ้นต่อกันแบบวงกลม)
- ตรวจสอบให้แน่ใจว่าทรัพยากรประเภทและเวอร์ชัน API ทั้งหมดถูกต้อง
- ไม่ปรับใช้ ทรัพยากรใดๆ
ควรใช้เมื่อใด: ก่อนการปรับใช้การผลิตเพื่อตรวจจับข้อผิดพลาดตั้งแต่เนิ่นๆ
ตัวอย่างคําสั่ง:
az deployment group validate \
--resource-group myResourceGroup \
--template-file main.json \
--parameters @parameters.json
โหมดส่วนเพิ่ม (ค่าเริ่มต้น)
วัตถุประสงค์: เพิ่มหรืออัปเดตทรัพยากรโดยไม่ส่งผลกระทบต่อทรัพยากรที่มีอยู่
หน้าที่:
- ปรับใช้ทรัพยากร ที่กําหนดไว้ในเทมเพลต
- ปล่อยให้ทรัพยากรที่ไม่เปลี่ยนแปลง ไม่ได้กําหนดไว้ในเทมเพลต
- อัปเดต ทรัพยากรหากมีการเปลี่ยนแปลงการกําหนดค่า
สถานการณ์ตัวอย่าง:
- เทมเพลตกําหนด VM1, VM2, Storage1
- กลุ่มทรัพยากรมี VM1, VM3, Storage1
- หลังการปรับใช้: VM1 (อัปเดต), VM2 (เพิ่ม), VM3 (ไม่เปลี่ยนแปลง), Storage1 (อัปเดต)
ควรใช้เมื่อใด:
- การเพิ่มทรัพยากรใหม่ให้กับสภาพแวดล้อมที่มีอยู่
- การอัปเดตทรัพยากรเฉพาะโดยไม่เสี่ยงต่อผู้อื่น
- สภาพแวดล้อมการพัฒนาและการทดสอบ
โหมดสมบูรณ์
วัตถุประสงค์: ตรวจสอบให้แน่ใจว่ากลุ่มทรัพยากรตรงกับเทมเพลตทุกประการ (idempotency)
หน้าที่:
- ปรับใช้ทรัพยากร ที่กําหนดไว้ในเทมเพลต
- ลบทรัพยากร ที่ไม่ได้กําหนดไว้ในเทมเพลต
- กลุ่มทรัพยากรมีเฉพาะสิ่งที่อยู่ในเทมเพลตเท่านั้น
สถานการณ์ตัวอย่าง:
- เทมเพลตกําหนด VM1, VM2, Storage1
- กลุ่มทรัพยากรมี VM1, VM3, Storage1, VM4
- หลังการปรับใช้: VM1 (อัปเดต), VM2 (เพิ่ม), Storage1 (อัปเดต), VM3 (ลบ), VM4 (ลบ)
ควรใช้เมื่อใด:
- สภาพแวดล้อมการผลิตที่ต้องการการควบคุมของรัฐอย่างเข้มงวด
- บรรลุอุดมการณ์ (ผลการปรับใช้เดียวกันทุกครั้ง)
- การลบทรัพยากรที่ไม่ต้องการหรือด้วยตนเอง
คำเตือน
โหมดสมบูรณ์สามารถลบทรัพยากรได้ ทดสอบอย่างละเอียดก่อนใช้ในการผลิต!
การตั้งค่าโหมดการปรับใช้
Azure CLI:
# Incremental (default)
az deployment group create \
--resource-group myResourceGroup \
--template-file main.json \
--mode Incremental
# Complete
az deployment group create \
--resource-group myResourceGroup \
--template-file main.json \
--mode Complete
พาวเวอร์เชลล์:
# Incremental
New-AzResourceGroupDeployment `
-ResourceGroupName myResourceGroup `
-TemplateFile main.json `
-Mode Incremental
# Complete
New-AzResourceGroupDeployment `
-ResourceGroupName myResourceGroup `
-TemplateFile main.json `
-Mode Complete
แนวทางปฏิบัติที่ดีที่สุด
โน้ต
หนึ่งกลุ่มทรัพยากรต่อการปรับใช้: ใช้กลุ่มทรัพยากรเฉพาะสําหรับแต่ละแอปพลิเคชันเชิงตรรกะหรือสภาพแวดล้อมเพื่อลดความซับซ้อนในการจัดการและหลีกเลี่ยงการลบโดยไม่ได้ตั้งใจ
โน้ต
ข้อจํากัดของเทมเพลตที่เชื่อมโยง/ซ้อนกัน: คุณสามารถใช้ โหมดส่วนเพิ่ม ได้เฉพาะสําหรับทั้งเทมเพลตที่เชื่อมโยงและแบบซ้อนกันเท่านั้น โหมดสมบูรณ์ไม่ได้รับการสนับสนุนสําหรับการปรับใช้รอง
คำแนะนำ:
- พัฒนาการ: ใช้โหมดส่วนเพิ่มเพื่อความยืดหยุ่นและการทําซ้ําที่รวดเร็วขึ้น
- การผลิต: ใช้โหมดสมบูรณ์กับไปป์ไลน์ CI/CD เพื่อให้แน่ใจว่าสถานะสอดคล้องกัน
- ก่อนโหมดสมบูรณ์: ตรวจสอบความถูกต้องก่อนเสมอและทดสอบในสภาพแวดล้อมที่ไม่ใช่การผลิต
- ล็อคทรัพยากร: ใช้การล็อกกับทรัพยากรที่สําคัญเพื่อป้องกันการลบโดยไม่ได้ตั้งใจ
เทมเพลตและพารามิเตอร์ภายนอก
เทมเพลตภายนอก เป็นรากฐานสําหรับสถาปัตยกรรมเทมเพลต ARM แบบแยกส่วนอย่างแท้จริง คุณจัดเก็บเทมเพลตย่อยในตําแหน่งที่เข้าถึงได้และอ้างอิงผ่าน URI
ข้อกําหนดการช่วยสําหรับการเข้าถึงเทมเพลต
Resource Manager ต้องสามารถเข้าถึงเทมเพลตที่เชื่อมโยง ระหว่างการปรับใช้:
สิ่งที่ได้ผล:
- ที่เก็บข้อมูล Azure Blob : สาธารณะหรือส่วนตัวด้วยโทเค็น SAS
- จีทฮับ: ที่เก็บสาธารณะหรือส่วนตัวที่มีโทเค็นการเข้าถึง
- ปลายทาง HTTPS : URL HTTPS ที่เข้าถึงได้แบบสาธารณะ
- อินสแตนซ์คอนเทนเนอร์ Azure: การโฮสต์ไฟล์เทมเพลตในคอนเทนเนอร์
สิ่งที่ไม่ได้ผล:
- ไฟล์ในเครื่อง: ไฟล์บนคอมพิวเตอร์หรือเครือข่ายท้องถิ่นของคุณ
- โปรโตคอล File://: เส้นทางระบบไฟล์ภายในเครื่อง
- HTTP (ไม่ปลอดภัย): รองรับเฉพาะ HTTPS เท่านั้น
การใช้ templateLink และ parametersLink
templateLink: อ้างอิงไฟล์เทมเพลตภายนอก
พารามิเตอร์ลิงค์: อ้างอิงไฟล์พารามิเตอร์ภายนอก (ทางเลือกแทนพารามิเตอร์แบบอินไลน์)
สําคัญ
คุณไม่สามารถใช้ทั้งพารามิเตอร์แบบอินไลน์และพารามิเตอร์ลิงก์พร้อมกันได้ เลือกหนึ่งวิธี
ตัวอย่างที่สมบูรณ์ด้วย templateLink:
"resources": [
{
"name": "linkedStorageDeployment",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "https://mystorageaccount.blob.core.windows.net/templates/storage.json?sv=2021-06-08&sr=b&sig=ABC123...&se=2025-12-31T23:59:59Z&sp=r",
"contentVersion": "1.0.0.0"
},
"parameters": {
"storageAccountName": {
"value": "[variables('storageAccountName')]"
},
"location": {
"value": "[parameters('location')]"
},
"sku": {
"value": "Standard_GRS"
}
}
}
}
]
ส่วนประกอบที่สําคัญ:
- URI: URL HTTPS แบบเต็มไปยังเทมเพลตที่ลิงก์ (รวมถึงโทเค็น SAS หากใช้ที่เก็บข้อมูลส่วนตัว)
- เนื้อหาเวอร์ชัน: เวอร์ชันของเทมเพลตที่ลิงก์ (ต้องตรงกับสิ่งที่อยู่ในไฟล์เทมเพลตที่ลิงก์)
- พารามิเตอร์: ค่าที่ส่งผ่านไปยังเทมเพลตที่เชื่อมโยง (สามารถอ้างอิงพารามิเตอร์/ตัวแปรเทมเพลตหลักได้)
การใช้ไฟล์พารามิเตอร์ภายนอก
ทางเลือกแทนพารามิเตอร์แบบอินไลน์:
{
"name": "linkedDeployment",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "https://mystorageaccount.blob.core.windows.net/templates/main.json"
},
"parametersLink": {
"uri": "https://mystorageaccount.blob.core.windows.net/parameters/prod.json"
}
}
}
ประโยชน์:
- แยกไฟล์พารามิเตอร์ตามสภาพแวดล้อม (dev.json, staging.json, prod.json)
- พารามิเตอร์ที่ละเอียดอ่อนที่จัดเก็บไว้อย่างปลอดภัยในไฟล์พารามิเตอร์
- ง่ายต่อการจัดการการปรับใช้หลายสภาพแวดล้อม
การรักษาความปลอดภัยแม่แบบภายนอก
เทมเพลตภายนอกไม่จําเป็นต้องเป็นแบบสาธารณะ คุณสามารถจัดเก็บไว้ในบัญชีพื้นที่จัดเก็บข้อมูลส่วนตัวและใช้ โทเค็นลายเซ็นการเข้าถึงที่ใช้ร่วมกัน (SAS) เพื่อการเข้าถึงที่ปลอดภัย
ขั้นตอนในการรักษาความปลอดภัยเทมเพลต
- จัดเก็บเทมเพลตในที่เก็บข้อมูล Azure Blob ส่วนตัว:
# Create storage account and container
az storage account create \
--name mytemplatestorage \
--resource-group myResourceGroup \
--location eastus \
--sku Standard_LRS
az storage container create \
--name templates \
--account-name mytemplatestorage \
--public-access off
- อัปโหลดไฟล์เทมเพลต:
az storage blob upload \
--account-name mytemplatestorage \
--container-name templates \
--name networking.json \
--file ./templates/networking.json
- สร้างโทเค็น SAS เมื่อหมดอายุ:
# Create SAS token valid for 30 days
az storage blob generate-sas \
--account-name mytemplatestorage \
--container-name templates \
--name networking.json \
--permissions r \
--expiry 2025-12-31T23:59:59Z \
--https-only \
--output tsv
- ใช้โทเค็น SAS ใน URI ของ templateLink:
"templateLink": {
"uri": "https://mytemplatestorage.blob.core.windows.net/templates/networking.json?sv=2021-06-08&sr=b&sig=ABC123...&se=2025-12-31T23:59:59Z&sp=r"
}
ข้อควรพิจารณาด้านความปลอดภัย
การบันทึกโทเค็น SAS:
- แม้ว่าโทเค็นจะถูกส่งผ่านอย่างปลอดภัย แต่ URI (รวมถึงโทเค็น SAS) จะถูกบันทึกไว้ในการดําเนินการปรับใช้
- ทุกคนที่มีสิทธิ์อ่านกลุ่มทรัพยากรจะมองเห็นบันทึกการปรับใช้
แนวทางปฏิบัติที่ดีที่สุดสําหรับการรักษาความปลอดภัย:
- กําหนดวันหมดอายุ: สร้างโทเค็น SAS แบบจํากัดเวลา (30-90 วัน)
-
ใช้สิทธิ์แบบอ่านอย่างเดียว: โทเค็น SAS ควรให้สิทธิ์การอ่าน (
r) เท่านั้น - หมุนเวียนโทเค็นอย่างสม่ําเสมอ: สร้างโทเค็นใหม่และอัปเดตเทมเพลตเป็นระยะ
- ใช้ Azure Key Vault: จัดเก็บโทเค็น SAS ใน Key Vault และอ้างอิงในเทมเพลต
- ข้อมูลประจําตัวที่มีการจัดการ: พิจารณาใช้ข้อมูลประจําตัวที่มีการจัดการสําหรับการเข้าถึงเทมเพลตแทนโทเค็น SAS
- ปลายทางส่วนตัว: ใช้จุดสิ้นสุดส่วนตัวของ Azure Storage เพื่อความปลอดภัยเครือข่ายเพิ่มเติม
ตัวอย่างที่มีการอ้างอิง Key Vault:
"templateLink": {
"uri": "[concat('https://mytemplatestorage.blob.core.windows.net/templates/networking.json', reference(resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), 'storageAccountSasToken')).secretValue)]"
}
วิธีการนี้ป้องกันไม่ให้โทเค็น SAS อยู่ในโค้ดเทมเพลตและบันทึกการปรับใช้ของคุณ