使用 GitHub Copilot 產生 Bicep 範本

已完成

Bicep 是 Microsoft 用於部署 Azure 資源的領域專用語言。 它可以編譯成 Azure Resource Manager 的 JSON 範本,但更易讀且簡潔。 Bicep 移除了 Azure Resource Manager 的樣板程式碼,同時保留宣告式模型。

基本 Bicep 資源定義如下所示:

param location string = 'eastus'
param storageAccountName string

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    accessTier: 'Hot'
    supportsHttpsTrafficOnly: true
    minimumTlsVersion: 'TLS1_2'
  }
}

有三點需要注意: @ 符號將資源類型與 API 版本分開,參數在頂端宣告,資源參考使用符號名稱而非資源 ID。 這些模式在檢視 Copilot 的產出時很重要。

本單元著重於使用 Copilot 來產生、擴充及優化 Bicep 模板。 完整的Bicep介紹請參見Bicep導論。

從自然語言提示產生範本

預設情況下,Copilot 會根據訓練資料產生 Bicep。 不涉及外部工具或即時架構資料。 對於具有特定需求的常見資源類型,這已經能產生可靠的輸出。

產生簡單範本

先用一個聚焦於單一資源的提示,看看 Copilot 會產生什麼結果。 像這樣條件明確的提示詞,能為 Copilot 提供所需的一切:

Generate a Bicep template for an Azure Storage Account with these requirements:
- Standard_LRS SKU
- StorageV2 kind
- HTTPS-only access enforced
- Minimum TLS version: TLS 1.2
- Blob soft delete enabled with 7-day retention
- Public blob access disabled
- Parameters for: storageAccountName, location (default: eastus),
  environment, owner, costCenter
- Apply tags using a tags object built from the environment, owner,
  and costCenter parameters
- Output the storage account's primary blob endpoint

你應該會得到一個完整的 Bicep 檔案,包含參數、資源區塊和輸出。 在做任何其他事情之前,先立即使用 az bicep build 驗證它。

產生多資源範本

當多個資源相互依賴時,複雜度會增加。 在某個資源的符號名稱出現在另一個資源的屬性中時,資源參考是 Copilot 有時需要修正的地方。

試試這個提示來產生一組連結的資源:

Generate a Bicep template that deploys the following resources:
- An App Service Plan (Standard S1 SKU) on Linux
- An App Service (Web App) using Node 20 on the App Service Plan
- A Key Vault with RBAC authorization enabled and soft delete (90 days)
- A Role Assignment giving the Web App's system-assigned managed identity
  the "Key Vault Secrets User" role on the Key Vault
- Application settings on the Web App pointing to the Key Vault URI

Parameters: appName, location, environment, owner, costCenter
Use symbolic name references for all cross-resource dependencies.
Do not use hardcoded resource IDs.

檢查在此層級的輸出結果是否有三個常見問題:

  • Circular dependencies:如果兩個資源互相引用,Bicep 不會編譯。 檢查依賴關係圖。
  • Role assignment scoperoleAssignment 資源需要以 金鑰保存庫 作為其作用範圍,而非資源群組。 確認 scope: 屬性。
  • 身分識別參考webApp.identity.principalId 是參照受控識別的正確方式。 確認 Copilot 使用符號名稱,而非硬編碼值。

模板模組化

隨著模板的成長,維護起來變得越來越困難。 Bicep 模組可以讓你把大型範本拆分成可重複使用的元件。 Copilot 可以幫你拆分。

Refactor this Bicep template into modules. Create:
- A module for the App Service Plan and Web App (modules/webapp.bicep)
- A module for the Key Vault and Role Assignment (modules/keyvault.bicep)
- A main.bicep that calls both modules and passes parameters between them

Show me the content of all three files. Ensure the output of the Key Vault
module (the Key Vault URI) is passed to the Web App module as an input.

Copilot 會產生模組檔案和主編排檔案。 關鍵是要確認,某個模組的 output 值是否已正確連接為另一個模組的 param 輸入。 這種跨模組連接是拆分模板時最常見的錯誤。

Bicep MCP:內容感知產生

什麼是MCP?

模型情境協定(Model Context Protocol,MCP)是一項開放標準,允許 AI 模型連接外部工具與 API。 支援 MCP 的 Copilot 並非僅依賴訓練資料,還能即時查詢資料來源。

Bicep MCP 伺服器 將 GitHub Copilot 連線到即時 Bicep 類型登錄。 多虧了這個連結,GitHub Copilot 能存取:

  • 每個 Azure 資源類型的目前 API 版本
  • 每種資源類型的完整屬性結構
  • 在您執行 bicep build 之前標示設定錯誤的驗證規則
  • API 版本即將淘汰時的棄用通知

沒有 MCP 時,Copilot 會根據其訓練資料中的模式產生 Bicep。 這些資料有知識截止日期,而 Azure 的 API 版本會持續演進。 結果可能是使用過時的 API 版本、遺漏近期新增的必要屬性,或包含已淘汰的參數。 啟用 MCP 後,Copilot 會在產生每個資源區塊前查詢即時登錄檔。

啟用 Bicep MCP 伺服器

  1. 在 VS Code 中,開啟指令面板(Ctrl+Shift+P)。
  2. 搜尋 MCP:啟用 Bicep 伺服器
  3. 確認伺服器在 Copilot 狀態列中顯示為活躍狀態。

啟用後,當您處理 .bicep 檔案或詢問 Bicep 資源時,Copilot Chat 會自動使用 Bicep MCP 伺服器。

啟動 MCP 會有什麼變化

同一個提示執行時,使用或不使用 MCP 會產生三個明顯不同的輸出。

API 版本

若無 MCP,Copilot 可能會產生:

resource firewall 'Microsoft.Network/azureFirewalls@2022-07-01' = {

使用 MCP,Copilot 查詢登錄檔並產生目前穩定版本:

resource firewall 'Microsoft.Network/azureFirewalls@2024-03-01' = {

較新的 API 版本通常包含安全性改進、新增的必需屬性及錯誤修正。

必要屬性

部分資源類型在較新的 API 版本中獲得了所需的屬性。 若沒有 MCP,Copilot 可能會產生一個本地建置的範本,但在部署時 Azure 驗證請求時會失敗。 使用 MCP,Copilot 知道這些需求並包含在內。

生成過程中的驗證

啟用 MCP 時,Copilot 可以在執行 bicep build 前標記問題。 如果你寫了一個結構中不存在的屬性名稱,Copilot 可以立即辨識,類似 IntelliSense 對類型語言的識別。

範例:帶有 MCP 的樞紐輻射網路

在啟用 MCP 的情況下使用此提示詞,即可產生完整的輪輻式拓撲:

Generate a Bicep template for a hub-spoke VNet topology:
- Hub VNet: 10.0.0.0/16 with AzureFirewallSubnet (/26) and GatewaySubnet (/27)
- Spoke VNet: 10.1.0.0/16 with an application subnet (/24)
- VNet peering between hub and spoke (both directions)
- Azure Firewall Standard tier in the hub
- Azure Firewall Policy linked to the firewall
- Public IP for the firewall
- NSG on the application subnet blocking inbound SSH and RDP from internet
- Log Analytics Workspace for diagnostic logging
- Diagnostic settings on the firewall sending logs to the workspace
Parameters: location, environment, owner, costCenter
Use latest stable API versions.

啟用 MCP 後,Copilot 會使用目前的 API 版本,將 firewallPolicy 正確連結至 AzureFirewall 資源,並以正確的 logsmetrics 陣列格式產生 diagnosticSettings 資源,且僅在符號參照不足時才使用 dependsOn

驗證與最佳實務

一律執行 az bicep build

每次 Copilot 產生後,請執行:

az bicep build --file main.bicep

此指令會將 Bicep 編譯成 Azure Resource Manager 的 JSON,並偵測語法錯誤、缺少必要屬性及無效引用。 這是一個快速的驗證步驟,能在部署前發現許多問題。

在每次部署之前使用 what-if

what-if 指令會精確顯示 Azure 創建、修改或刪除的內容,且不做任何更改:

az deployment group what-if \
  --resource-group rg-iaclab \
  --template-file main.bicep \
  --parameters @params.json

每次部署前都要檢視產出內容。 留意是否有你原本無意刪除的資源正被刪除、是否有看起來出乎意料的修改,以及資源數量是否與你的設計相符。

使用參數檔案來設定環境特定的數值

Copilot 可以從你的範本產生參數檔案:

Generate a Bicep parameters file (bicepparam format) for the template above.
Create values appropriate for a staging environment.
Include comments explaining what each parameter controls.

這類提示詞會產生 .bicepparam 檔案,你可以將其與範本一起納入版本控制,且每個環境各有一個檔案。

要求 Copilot 記錄其輸出內容

Add @description() decorators to every parameter and output in this template.
The descriptions should be clear enough for someone who has never seen the template
to understand what each parameter controls and what constraints apply.

此提示詞範例可讓範本自我記錄,並改善顯示參數描述的 what-if 輸出。

解決 Copilot 常見問題

無效的資源引用

徵兆bicep build 失敗並出現 "The referenced resource could not be found."

This Bicep template has an invalid resource reference at line [X].
The resource [name] references [other resource] but uses a hardcoded string
instead of the symbolic name. Fix all cross-resource references to use
symbolic names.

迴圈相依性

徵兆bicep build 失敗並出現 "A cycle was detected in the template."

This Bicep template has a circular dependency between [resource A] and
[resource B]. Restructure the template to break the cycle. One approach
is to use an existing() reference for one of the resources.

API 版本過時

症狀:部署失敗 "The resource type [X] was not found in the namespace."

The resource type [Microsoft.Network/azureFirewalls@2021-02-01] appears to
use an outdated API version. Update it to the current stable API version
and adjust any properties that have changed.