Bicep モジュール

Bicep を使用すると、デプロイをモジュールにまとめることができます。 モジュールとは、別の Bicep ファイル (または ARM JSON テンプレート) からデプロイされる Bicep ファイルです。 モジュールを使用して、デプロイの複雑な詳細をカプセル化することで、Bicep ファイルの読みやすさが向上します。 また、モジュールを異なるデプロイに簡単に再利用することもできます。

組織内の他のユーザーとモジュールを共有するには、テンプレート スペックパブリック レジストリ、またはプライベート レジストリを作成します。 レジストリ内のテンプレート スペックとモジュールは、正しいアクセス許可を持つユーザーのみが使用できます。

ヒント

モジュール レジストリとテンプレート スペックの選択は、ほとんど好みの問題です。 2 つから選択するときに考慮すべき点がいくつかあります。

  • モジュール レジストリは、Bicep でのみサポートされています。 Bicep をまだ使用していない場合は、テンプレート スペックを使用します。
  • Bicep モジュール レジストリの内容は、別の Bicep ファイルからのみデプロイできます。 テンプレート スペックは、API、Azure PowerShell、Azure CLI、および Azure portal から直接デプロイできます。 UiFormDefinition を使用して、ポータルのデプロイ エクスペリエンスをカスタマイズすることさえできます。
  • Bicep には、loadTextContent および loadFileAsBase64 関数を使用して他のプロジェクト成果物 (非 Bicep ファイルや非 ARM テンプレート ファイルなど。たとえば、PowerShell スクリプト、CLI スクリプト、その他のバイナリ) を埋め込むための機能がいくつかあります。 テンプレート スペックでは、これらのアーティファクトをパッケージ化することはできません。

Bicep モジュールは、入れ子になったテンプレートを持つ単一の Azure Resource Manager テンプレートに変換されます。 Bicep が構成ファイルを解決する方法と、Bicep がユーザー定義の構成ファイルを既定の構成ファイルとマージする方法の詳細については、「構成ファイルの解決プロセス」と「構成ファイルのマージ プロセス」を参照してください。

トレーニング リソース

段階的なガイダンスを通じてモジュールの詳細を学習する場合は、「モジュールを使用して構成可能な Bicep ファイルを作成する」を参照してください。

定義の構文

モジュールを定義するための基本的な構文は次のとおりです。

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 プロパティは必須です。 生成されるテンプレートでは、それは入れ子になったデプロイ リソースの名前になります。

静的な名前のモジュールが同じスコープに同時にデプロイされる場合、一方のデプロイがもう一方のデプロイからの出力に干渉する可能性があります。 たとえば、2 つの 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 の円記号 () 文字はサポートされていません。 パスにはスペースを含めることができます。

たとえば、ディレクトリ内でメイン ファイルより 1 つ上のレベルにあるファイルをデプロイするには、以下を使用します。

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

レジストリ内のファイル

パブリック モジュール レジストリ

パブリック モジュール レジストリは、Microsoft コンテナー レジストリ (MCR) にホストされます。 ソース コードとモジュールは GitHub に格納されます。 使用可能なモジュールとそのバージョンを表示するには、Bicep レジストリの「Module Index」 (モジュール インデックス) を参照してください。

The screenshot of public module registry.

バージョンを選択すると、利用可能なバージョンが表示されます。 [Source code] を選択してモジュールのソース コードを表示したり、Readme ファイルを開いたりすることもできます。

現在、公開されているモジュールはごくわずかです。 さらに多くのモジュールが追加される予定です。 レジストリに貢献したい場合は、貢献ガイドを参照してください。

パブリック レジストリ モジュールにリンクするには、次の構文でモジュール パスを指定します。

module <symbolic-name> 'br/public:<file-path>:<tag>' = {}
  • br/public は、パブリック モジュール レジストリのエイリアスです。 このエイリアスは、構成で事前に定義されています。
  • / 文字で区切ることで、複数のセグメントをファイル パスに含めることができます。
  • タグは、モジュールのバージョンを指定するために使用します。

次に例を示します。

module hw 'br/public:samples/hello-world:1.0.2' = {
  name: 'helloWorld'
  params: {
    name: 'John Dole'
  }
}

注意

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 レジストリのスキーマ名です。
  • ファイル パスは、Azure Container Registry では repository と呼ばれます。 / 文字で区切ることで、複数のセグメントをファイル パスに含めることができます。
  • タグは、モジュールのバージョンを指定するために使用します。

次に例を示します。

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 hw 'br/public:samples/hello-world:1.0.2' = {
  name: 'helloWorld'
  params: {
    name: 'John Dole'
  }
}

パブリック エイリアスは、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'
  }
}

パラメーター

モジュールの定義で指定するパラメーターは、Bicep ファイル内のパラメーターと一致します。

次の Bicep の例には、storagePrefix、storageSKU、location という 3 つのパラメーターが含まれます。 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@2021-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@2021-04-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@2021-04-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

次の例では、2 つの異なるリソース グループにストレージ アカウントがデプロイされます。 どちらのリソース グループも既に存在している必要があります。

targetScope = 'subscription'

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

resource secondRG 'Microsoft.Resources/resourceGroups@2021-04-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@2021-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@2021-04-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

次のステップ