分享方式:


Bicep 模組

Bicep 可讓您將部署組織成模組。 模組是從另一個 Bicep 檔案部署的 Bicep 檔案(或 Azure Resource Manager JSON 範本)。 使用模組時,您可以透過封裝部署的複雜詳細資料,來改善 Bicep 檔案的可讀性。 您也可以輕鬆地對不同的部署重複使用模組。

若要與組織中的其他人共享模組,請建立 範本規格私人登錄。 範本規格和登錄中的模組僅可供具備正確權限的使用者使用。

提示

您通常可依喜好來選擇要採用模組登錄或範本規格。 當您在這兩者之間選擇時,需要考慮下列幾點:

  • 模組登錄僅受 Bicep 支援。 如果您尚未使用 Bicep,請使用範本規格。
  • Bicep 模組登錄中的內容只能從另一個 Bicep 檔案進行部署。 範本規格可以直接從 API、Azure PowerShell、Azure CLI 和 Azure 入口網站部署。 您甚至可以使用 UiFormDefinition (部分機器翻譯) 來自訂入口網站部署體驗。
  • Bicep 針對用下述函式內嵌其他專案成品 (包括非 Bicep 和非 ARM 範本檔案。例如,PowerShell 指令碼、CLI 指令碼和其他二進位檔) 的功能上有所限制:loadTextContent (部分機器翻譯) 和 loadFileAsBase64 (部分機器翻譯) 函式。 範本規格無法封裝這些成品。

Bicep 模組會使用巢狀範本轉換成單一 Azure Resource Manager 範本。 如需 Bicep 如何解析組態檔及 Bicep 如何合併使用者定義組態檔與預設組態檔的詳細資訊,請參閱 組態檔解析程式組態檔合併程式

訓練資源

如果您比較想要透過逐步指導來了解模組,請參閱使用模組建立可組合的 Bicep 檔案

定義模組

定義模組的基本語法為:

@<decorator>(<argument>)
module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}

因此,簡單的真實世界範例看起來像這樣:

module stgModule '../storageAccount.bicep' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

您也可以使用 ARM JSON 範本作為模組:

module stgModule '../storageAccount.json' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

使用符號名稱,在 Bicep 檔案的另一個部分中參考該模組。 例如,您可以使用符號名稱來取得模組的輸出。 符號名稱可能包含 a-z、A-Z、0-9 和底線 (_)。 名稱的開頭不能是數字。 模組的名稱不能與參數、變數或資源相同。

路徑可以是本機檔案或登錄中的檔案。 本機檔案可以是 Bicep 檔案或 ARM JSON 範本。 如需詳細資訊,請參閱模組路徑 (部分機器翻譯)。

name 是必要屬性。 其會成為所產生範本中巢狀部署資源的名稱。

如果將具有靜態名稱的模組同時部署到相同的範圍,那麼其中一個部署可能會干擾另一個部署的輸出。 例如,如果兩個 Bicep 檔案使用相同的模組與相同的靜態名稱 (examplemodule),且目標為相同的資源群組,那麼其中一個部署可能會顯示錯誤的輸出。 如果您擔心相同範圍裡會有並行部署,那麼請以唯一名稱來命名您的模組。

下列範例會將部署名稱串連至模組名稱。 如果您提供給部署的是唯一名稱,那麼模組名稱也會是唯一的。

module stgModule 'storageAccount.bicep' = {
  name: '${deployment().name}-storageDeploy'
  scope: resourceGroup('demoRG')
}

如果您需要指定與主要檔案範圍不同的範圍,請新增 scope 屬性。 如需詳細資訊,請參閱設定模組範圍 (部分機器翻譯)。

// deploy to different scope
module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  scope: <scope-object>
  params: {
    <parameter-names-and-values>
  }
}

若要有條件地部署模組,請新增 if 運算式。 使用方式類似於有條件地部署資源 (部分機器翻譯)。

// conditional deployment
module <symbolic-name> '<path-to-file>' = if (<condition-to-deploy>) {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}

若要部署模組一個以上的執行個體,請新增 for 運算式。 您可以使用 batchSize 裝飾項目來指定以序列方式或平行方式部署執行個體。 如需詳細資訊,請參閱 Bicep 中的反覆式迴圈 (部分機器翻譯)。

// iterative deployment
@batchSize(int) // optional decorator for serial deployment
module <symbolic-name> '<path-to-file>' = [for <item> in <collection>: {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}]

如同資源,模組會以平行方式部署,除非其相依於其他模組或資源。 一般來說,您不需要設定相依性,因為其為隱含決定。 如果您需要設定明確相依性,您可以將 dependsOn 新增至模組定義。 若要深入了解相依性,請參閱資源相依性 (部分機器翻譯)。

module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
  dependsOn: [
    <symbolic-names-to-deploy-before-this-item>
  ]
}

模組路徑

模組的檔案可以是本機檔案或外部檔案。 外部檔案可以位於範本規格或 Bicep 模組登錄中。

本機檔案

如果模組是本機檔案,請提供該檔案的相對路徑。 Bicep 中的所有路徑都必須使用斜線 (/) 目錄分隔符號來指定,以確保跨平台的一致匯編。 不支援 Windows 反斜線 (\) 字元。 路徑可以包含空格。

例如,若要在主要檔案目錄的上一層中部署檔案,請使用:

module stgModule '../storageAccount.bicep' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

登錄中的檔案

公用模組模組登錄

注意

非 AVM (Azure 已驗證的模組) 模組會從公用模組登錄淘汰。

Azure 已驗證的模組 已預先建置、預先測試,以及預先驗證的模組,以在 Azure 上部署資源。 這些模組是由Microsoft員工所建立及擁有,旨在簡化和加速常見 Azure 資源和設定的部署程式,同時符合最佳做法:例如架構完善的架構。

流覽至 Azure 已驗證的模組 Bicep 索引以查看可用的模組清單,選取下列螢幕快照中的醒目提示數位,以直接進入該篩選檢視。

Azure 已驗證模組 (AVM) 的螢幕快照。

模組清單會顯示最新版本。 選擇版本號碼以檢視可用的版本清單:

Azure 已驗證模組(AVM) 版本的螢幕快照。

若要連結至公用模組,請使用下列語法指定模組路徑:

module <symbolic-name> 'br/public:<file-path>:<tag>' = {}
  • br/public 是公用模組的別名。 您可以在 Bicep 組態檔自定義此別名。
  • file path 可以包含以 / 字元分隔的區段。
  • tag 可用於指定模組的版本。

例如:

module storage 'br/public:avm/res/storage/storage-account:0.9.0' = {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}

注意

br/public 是公用模組的別名。 它也可以撰寫為:

module <symbolic-name> 'br:mcr.microsoft.com/bicep/<file-path>:<tag>' = {}

私人模組登錄

如果您已將模組發佈到登錄 (部分機器翻譯),您可以連結至該模組。 提供 Azure 容器登錄的名稱和模組的路徑。 使用下列語法指定模組路徑:

module <symbolic-name> 'br:<registry-name>.azurecr.io/<file-path>:<tag>' = {
  • br 是 Bicep 登錄的結構描述名稱。
  • file path 在 Azure Container Registry 中稱為 repositoryfile path 可以包含以 / 字元分隔的區段。
  • tag 可用於指定模組的版本。

例如:

module stgModule 'br:exampleregistry.azurecr.io/bicep/modules/storage:v1' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

參考登錄中的模組時,Visual Studio Code 中的 Bicep 延伸模組會自動呼叫 bicep restore (部分機器翻譯),以將外部模組複製到本機快取。 需要幾分鐘的時間來還原外部模組。 如果模組的 IntelliSense 無法立即運作,請等候還原完成。

登錄中模組的完整路徑可能很長。 您可以在 bicepconfig.json 檔案中設定別名 (部分機器翻譯),而不是在每次您想要使用模組時提供完整路徑。 別名可讓您更輕鬆地參考模組。 例如,您可以使用別名來將路徑縮短為:

module stgModule 'br/ContosoModules:storage:v1' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

已預先定義公用模組登錄的別名:

module storage 'br/public:avm/res/storage/storage-account:0.9.0' = {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}

您可以在 bicepconfig.json 檔案中覆寫公用別名。

範本規格中的檔案

建立範本規格 (部分機器翻譯) 之後,您可以在模組中連結至該範本規格。 以下列格式指定範本規格:

module <symbolic-name> 'ts:<sub-id>/<rg-name>/<template-spec-name>:<version>' = {

不過,您可以為包含範本規格的資源群組建立別名 (部分機器翻譯),以簡化您的 Bicep 檔案。 當您使用別名時,語法會變成:

module <symbolic-name> 'ts/<alias>:<template-spec-name>:<version>' = {

下列模組會部署範本規格來建立儲存體帳戶。 範本規格的訂用帳戶和資源群組已在名為 ContosoSpecs 的別名中定義。

module stgModule 'ts/ContosoSpecs:storageSpec:2.0' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

使用裝飾專案

裝飾專案是以 格式 @expression 撰寫,並放在模組宣告上方。 下表顯示模組的可用裝飾專案。

裝飾項目 Argument 描述
batchSize none 設定實例以循序部署。
description 字串 提供模組的描述。

裝飾項目在 sys 命名空間中。 如果您需要區別裝飾項目與具有相同名稱的另一個項目,請在裝飾項目前面加上 sys。 例如,如果您的 Bicep 檔案包含名稱為 description 的參數,則在使用描述裝飾項目時,您必須加入 sys 命名空間。

BatchSize

您只能套用 @batchSize() 至使用 for 表示式的資源或模組定義。

根據預設,模組會以平行方式部署。 新增 @batchSize(int) 裝飾項目時,請依序部署實例。

@batchSize(3)
module storage 'br/public:avm/res/storage/storage-account:0.11.1' = [for storageName in storageAccounts: {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}]

如需詳細資訊,請參閱分批部署

描述

若要新增說明,請將描述新增至模組宣告。 例如:

@description('Create storage accounts referencing an AVM.')
module storage 'br/public:avm/res/storage/storage-account:0.9.0' = {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}

Markdown 格式的文字可用於描述文字。

參數

您在模組定義中提供的參數會符合 Bicep 檔案中的參數。

下列 Bicep 範例有三個參數:storagePrefix、storageSKU 和 location。 storageSKU 參數有預設值,因此在部署期間,您不需要為該參數提供值。

@minLength(3)
@maxLength(11)
param storagePrefix string

@allowed([
  'Standard_LRS'
  'Standard_GRS'
  'Standard_RAGRS'
  'Standard_ZRS'
  'Premium_LRS'
  'Premium_ZRS'
  'Standard_GZRS'
  'Standard_RAGZRS'
])
param storageSKU string = 'Standard_LRS'

param location string

var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}'

resource stg 'Microsoft.Storage/storageAccounts@2023-04-01' = {
  name: uniqueStorageName
  location: location
  sku: {
    name: storageSKU
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

output storageEndpoint object = stg.properties.primaryEndpoints

若要使用上述範例作為模組,請提供那些參數的值。

targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

resource demoRG 'Microsoft.Resources/resourceGroups@2024-03-01' existing = {
  name: 'demogroup1'
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: demoRG
  params: {
    storagePrefix: namePrefix
    location: demoRG.location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

設定模組範圍

宣告模組時,您可以設定與包含 Bicep 檔案的範圍不同的模組範圍。 使用 scope 屬性來設定模組的範圍。 如果未提供 scope 屬性,則會在父代的目標範圍中部署模組。

下列 Bicep 檔案會在該資源群組中建立資源群組和儲存體帳戶。 該檔案會部署至訂用帳戶,但模組的範圍會設為新資源群組。

// set the target scope for this file
targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

param location string = deployment().location

var resourceGroupName = '${namePrefix}rg'

resource newRG 'Microsoft.Resources/resourceGroups@2024-03-01' = {
  name: resourceGroupName
  location: location
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: newRG
  params: {
    storagePrefix: namePrefix
    location: location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

下一個範例會將儲存體帳戶部署至兩個不同的資源群組。 這兩個資源群組都必須已存在。

targetScope = 'subscription'

resource firstRG 'Microsoft.Resources/resourceGroups@2024-03-01' existing = {
  name: 'demogroup1'
}

resource secondRG 'Microsoft.Resources/resourceGroups@2024-03-01' existing = {
  name: 'demogroup2'
}

module storage1 '../create-storage-account/main.bicep' = {
  name: 'westusdeploy'
  scope: firstRG
  params: {
    storagePrefix: 'stg1'
    location: 'westus'
  }
}

module storage2 '../create-storage-account/main.bicep' = {
  name: 'eastusdeploy'
  scope: secondRG
  params: {
    storagePrefix: 'stg2'
    location: 'eastus'
  }
}

將 scope 屬性設定為有效的範圍物件。 如果您的 Bicep 檔案會部署資源群組、訂用帳戶或管理群組,您可以將模組的範圍設為該資源的符號名稱。 或者,您可以使用範圍函式來取得有效的範圍。

這些函式是:

下列範例會使用 managementGroup 函式來設定範圍。

param managementGroupName string

module mgDeploy 'main.bicep' = {
  name: 'deployToMG'
  scope: managementGroup(managementGroupName)
}

輸出

您可以從模組取得值,並在主要 Bicep 檔案中加以使用。 若要從模組取得輸出值,請使用模組物件上的 outputs 屬性。

第一個範例會建立儲存體帳戶,並傳回主要端點。

@minLength(3)
@maxLength(11)
param storagePrefix string

@allowed([
  'Standard_LRS'
  'Standard_GRS'
  'Standard_RAGRS'
  'Standard_ZRS'
  'Premium_LRS'
  'Premium_ZRS'
  'Standard_GZRS'
  'Standard_RAGZRS'
])
param storageSKU string = 'Standard_LRS'

param location string

var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}'

resource stg 'Microsoft.Storage/storageAccounts@2023-04-01' = {
  name: uniqueStorageName
  location: location
  sku: {
    name: storageSKU
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

output storageEndpoint object = stg.properties.primaryEndpoints

當成模組使用時,您可以取得該輸出值。

targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

resource demoRG 'Microsoft.Resources/resourceGroups@2024-03-01' existing = {
  name: 'demogroup1'
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: demoRG
  params: {
    storagePrefix: namePrefix
    location: demoRG.location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

下一步