規劃 Bicep 檔案的結構

已完成

Bicep 提供您決定如何設計程式碼結構的彈性。 在本單元中,您會學到可以設計 Bicep 程式碼結構的方式,以及 Bicep 程式碼樣式一致、清晰易懂的重要性。

您的 Bicep 程式碼應遵循何種順序?

您的 Bicep 範本可包含許多元素,包括參數、變數、資源、模組、輸出,以及整個範本的 targetScope。 Bicep 不會要求您的元素遵循某個順序。 然而,請務必考慮您的元素順序,以確保範本清晰易懂。

有兩個排序您程式碼的主要方法:

  • 依元素類型分組元素
  • 依資源分組元素

您與您的小組應同意其中一個,並保持一致的用法。

依元素類型分組元素

您可以將相同類型的所有元素分組在一起。 您所有的參數都會在一個位置,通常是在檔案的頂端。 接下來則是變數,後面接著資源和模組,而輸出則在底部。 例如,您可能會有部署 Azure SQL 資料庫與儲存體帳戶的 Bicep 檔案。

當依類型將元素分組時,看起來可能會像這樣:

圖表顯示依元素類型分組的元素。參數分組在一起,接著依序是變數、資源與輸出。

提示

若要遵循此慣例,請考慮將 targetScope 放在檔案的頂端。

當習慣使用其他基礎結構作為程式碼語言 (例如,Azure Resource Manager 範本中的語言) 時,此順序就很合理。 因為該順序能清楚顯示尋找特定類型元素的位置,所以也可讓範本更容易理解。 然而,在較長的範本中,要在元素之間巡覽及切換可能相當困難。

您仍然必須決定如何排序這些類別中的元素。 最好是將相關參數分組在一起。 例如,與儲存體帳戶相關的所有參數都屬於同一個分組,而儲存體帳戶的 SKU 參數則會在該分組中。

同樣地,您可以將相關的資源分組在一起。 這可協助使用您範本的任何人快速瀏覽,並了解範本的重點。

有時,您會建立範本來部署主要資源,以及多個次要支援資源。 例如,您可以建立範本來部署裝載於 Azure App Service 上的網站。 主要資源是 App Service 應用程式。 相同範本中的次要資源可能包含 App Service 方案、儲存體帳戶、Application Insights 執行個體與其他資源。 當有像這樣的範本時,最好將主要資源或某些資源放在範本的資源區段頂端,讓任何開啟範本的人都可以快速識別範本的用途,並找到重要的資源。

依資源分組元素

或者,您可以根據要部署的資源類型將元素分組。 繼續上述範例,您可以將與 Azure SQL Database 資源相關的所有參數、變數、資源和輸出分組在一起。 然後,您可以新增儲存體帳戶的參數、變數、資源和輸出,如下所示:

顯示依資源分組元素的圖表。儲存體帳戶元素已分組在一起,然後是 Azure SQL Database 元素。

依資源分組可讓您更輕鬆地讀取範本,因為特定資源所需的所有元素都在同一處。 但是,這會讓您更難快速檢查特定元素類型的宣告方式,例如當想要檢閱所有參數時。

您也必須考慮如何處理常見於多個資源的參數與變數,例如:使用設定對應時的 environmentType 參數。 常見參數與變數應放在一起,通常會放在 Bicep 檔案的頂端。

提示

請先考慮建立相關資源群組的「模組」是否更合理,再使用較簡單的範本將這些模組合併在一起。 我們會在 Bicep 學習路徑中更詳細地討論 Bicep 模組。

空白字元如何協助建立結構?

空白行 (或空白字元) 可協助將視覺化結構新增至範本。 透過審慎地使用空白字元,您可以依照邏輯將 Bicep 程式碼區段分組,這可協助釐清資源間的關聯性。 若要進行此操作,請考慮在主要區段間新增空白行,無論所偏好的分組樣式為何。

如何定義數個類似的資源?

透過 Bicep,您可以使用迴圈部署單一定義中類似的資源。 藉由使用 for 關鍵字來定義資源迴圈,可讓 Bicep 程式碼更簡潔,並減少不必要的資源定義重複。 當未來需要變更資源的定義時,只需要更新一個位置。 根據預設,當 Azure Resource Manager 部署您的資源時,其會同時在迴圈中部署所有資源,因此您的部署會盡可能地有效率。

尋找您用以定義多個完全相同或其屬性有一些差異之資源的位置。 然後,將變數新增至清單來列出要建立的資源,以及與其他資源不同的屬性。 下列範例會使用迴圈定義一組 Azure Cosmos DB 容器,每個容器都有自己的名稱與分割區索引鍵:

var cosmosDBContainerDefinitions = [
  {
    name: 'customers'
    partitionKey: '/customerId'
  }
  {
    name: 'orders'
    partitionKey: '/orderId'
  }
  {
    name: 'products'
    partitionKey: '/productId'
  }
]

resource cosmosDBContainers 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers@2024-05-15' = [for cosmosDBContainerDefinition in cosmosDBContainerDefinitions: {
  parent: cosmosDBDatabase
  name: cosmosDBContainerDefinition.name
  properties: {
    resource: {
      id: cosmosDBContainerDefinition.name
      partitionKey: {
        kind: 'Hash'
        paths: [
          cosmosDBContainerDefinition.partitionKey
        ]
      }
    }
    options: {}
  }
}]

如何將資源部署至特定環境?

有時,您會定義只應部署至特定環境,或在特定條件下部署的資源。 使用 if 關鍵字可讓您根據參數值、設定對應變數或其他條件,選擇性地部署資源。 下列範例使用設定對應部署生產環境的記錄資源,但不會針對測試環境進行部署:

var environmentConfigurationMap = {
  Production: {
    enableLogging: true
  }
  Test: {
    enableLogging: false
  }
}

resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' = if (environmentConfigurationMap[environmentType].enableLogging) {
  name: logAnalyticsWorkspaceName
  location: location
}

resource cosmosDBAccountDiagnostics 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (environmentConfigurationMap[environmentType].enableLogging) {
  scope: cosmosDBAccount
  name: cosmosDBAccountDiagnosticSettingsName
  properties: {
    workspaceId: logAnalyticsWorkspace.id
    // ...
  }
}

如何表達資源之間的相依性?

在任何複雜的 Bicep 範本中,您都必須表達資源之間的「相依性」。 當 Bicep 了解資源之間的相依性時,即會以正確的順序加以部署。

Bicep 可讓您使用 dependsOn 屬性明確地指定相依性。 然而,在大部分的情況下,您可以讓 Bicep 自動偵測相依性。 當在另一個資源的屬性中使用某個資源的符號名稱時,Bicep 會偵測到關聯性。 最好可以隨時讓 Bicep 自行管理。 如此一來,當變更範本時,Bicep 就會確保這些相依性一律正確,而且您不會新增不必要的程式碼,讓您的範本更繁瑣且更難以閱讀。

如何表達父子式關聯性?

Azure Resource Manager 與 Bicep 都有「子資源」的概念,該資源只有在其父系的內容中部署時才有意義。 例如,Azure SQL Database 是 SQL Server 執行個體的子系。 有數種方式可定義子資源,但在大部分的情況下,最好使用 parent 屬性。 這有助於 Bicep 了解其關聯性,以便在 Visual Studio Code 中提供驗證,並讓其他讀取範本的任何人都清楚關聯性。

如何設定資源屬性?

您必須在 Bicep 檔案中指定資源屬性的值。 在將值直接硬式編碼到資源定義中時,最好先經過深思熟慮。 若您知道該值不會變更,則最好是直接硬式編碼這些值,而不是使用另一個參數,使範本更難以測試及使用。 但是,若值可能會變更,請考慮將值定義為參數或變數,以讓 Bicep 程式碼更動態且可重複使用。

當將值硬式編碼時,請確定其他人可理解這些值。 例如,若必須將某個屬性設為特定值才能讓資源針對您的解決方案正常運作時,請考慮建立提供說明且命名適當的變數,然後使用該變數指派值。 在無法從變數名稱了解整個案例的情況下,請考慮新增註解。 您將會在本課程模組的稍後部分了解註解。

針對某些資源屬性,您必須建立包含函式與字串插補的複雜運算式,以自動建構值。 通常在宣告變數並在資源程式碼區塊中加以參考時,您的 Bicep 程式碼會更清楚。

提示

建立輸出時,請嘗試在何處使用資源屬性。 避免將資源運作方式的假設納入自己的假設,因為這些假設可能會隨著時間而變更。

例如,如果您需要輸出App Service應用程式的 URL,請避免建構 URL:

output hostname string = '${app.name}.azurewebsites.net'

如果 App Service 將主機名稱指派給應用程式的方式變更,或部署至使用不同的 URL 的 Azure 環境,上述方法將會中斷。

請改用應用程式資源的 defaultHostname 屬性:

output hostname string = app.properties.defaultHostname

如何有效地使用版本控制?

當重構程式碼時,版本控制系統 (例如 Git) 有助於簡化工作。

因為版本控制系統的設計目的是追蹤檔案的變更,所以您可以將其用於發生錯誤時,以便輕鬆地返回較舊版本的程式碼。 建議經常認可您的工作,以便可以返回所需的確切時間點。

版本控制也可協助從 Bicep 檔中移除舊的程式碼。 若 Bicep 程式碼包含您不再需要的資源定義時會怎樣? 您未來可能會再次需要定義,而將其標記為註解並將其保留在檔案中很吸引人。 但實際上,將其保留在原處只會讓您的 Bicep 檔案變得雜亂,讓其他人難以了解為什麼標記為註解的資源仍然存在。

另一個考量事項是,某個人可能會不小心取消註解定義,產生無法預測或潛在的不良結果。 當使用版本控制系統時,可以直接移除舊的資源定義。 若未來再次需要該定義,您可以從檔案歷程記錄中擷取。