Bicep ファイルの構造を計画する

完了

Bicep を使用すると、コードを構築する方法を柔軟に決定できます。 このユニットでは、Bicep コードを構築する方法と、一貫したスタイルと明確でわかりやすい Bicep コードの重要性について説明します。

Bicep コードで従う必要がある順序

Bicep テンプレートには、テンプレート全体のパラメーター、変数、リソース、モジュール、出力、および targetScope を含む多くの要素を含めることができます。 Bicep には強制的に適用される要素の順序はありません。 ただし、テンプレートを明確さとわかりやすさを確保するために要素の順序を考慮することが重要です。

コードを並べ替えるには、主に 2 つの方法があります。

  • 要素の種類別に要素をグループ化する
  • リソース別に要素をグループ化する

あなたとチームは、どれか 1 つに同意し、それを一貫して使用する必要があります。

要素の種類別に要素をグループ化する

同じ型のすべての要素をグループ化できます。 すべてのパラメーターは 1 か所 (通常はファイルの先頭) に配置されます。 その次に変数があり、リソースとモジュールが続き、出力が末尾に表示されます。 たとえば、Azure SQL データベースとストレージ アカウントをデプロイする Bicep ファイルがあるとします。

要素を種類別にグループ化すると、次のように表示されます。

要素の種類別にグループ化された要素を示す図。パラメーター、変数、リソース、出力がグループ化されています。

ヒント

この規則に従う場合、targetScope をファイルの先頭に置くことを検討してください。

この順序付けは、コードとしてのインフラストラクチャの他の言語 (たとえば、Azure Resource Manager テンプレートの言語) に慣れている場合に適しています。 また、これによって特定の種類の要素をどこで探せばよいかが明確になるので、テンプレートが理解しやすくもなります。 しかし、より長いテンプレートでは、要素間を移動してジャンプするのが困難な場合があります。

これらのカテゴリ内の要素を順序付けする方法を決定する必要があります。 関連するパラメーターをグループ化すると便利です。 たとえば、ストレージ アカウントに関するすべてのパラメーターは同じ種類であり、その内部では、ストレージ アカウントの SKU パラメーターが同じ種類です。

同様に、関連するリソースをグループ化できます。 そうすることで、テンプレートを使用する人物は、すばやくテンプレート内を移動し、テンプレートの重要な部分を理解できるようになります。

場合によっては、複数のセカンダリ サポート リソースを持つプライマリ リソースをデプロイするテンプレートを作成することがあります。 たとえば、Azure App Service でホストされている Web サイトをデプロイするテンプレートを作成する場合があります。 プライマリ リソースは App Service アプリです。 同じテンプレート内のセカンダリ リソースには、App Service プラン、ストレージ アカウント、Application Insights インスタンスなどがあります。 このようなテンプレートがある場合は、テンプレートを開く人物がテンプレートの目的をすばやく特定し、重要なリソースを見つけることができるように、テンプレートのリソース セクションの先頭にプライマリ リソースを配置することをお勧めします。

リソース別に要素をグループ化する

代わりに、デプロイしているリソースの種類に基づいて要素をグループ化することもできます。 引き続き前の例で、Azure SQL データベース リソースに関連するすべてのパラメーター、変数、リソース、出力をグループ化できます。 その後に、ストレージ アカウントのパラメーター、変数、リソース、出力を追加できます。次のようになります。

リソース別にグループ化された要素を示す図。ストレージ アカウントの要素がグループ化され、その後に Azure SQL データベースの要素がグループ化されています。

リソース別にグループ化すると、特定のリソースに必要なすべての要素が 1 か所にまとめられるため、テンプレートが読みやすくなります。 しかし、これによって、たとえばすべてのパラメーターを確認したい場合など、特定の要素の種類がどのように宣言されているかをすばやく確認するのが困難になります。

また、構成マップ使用時の environmentType パラメーターなど、複数のリソースに共通するパラメーターと変数を処理する方法も検討する必要があります。 一般的なパラメーターと変数は、通常は Bicep ファイルの先頭にまとめて配置する必要があります。

ヒント

関連するリソースのグループのために "モジュール" を作成し、より簡単なテンプレートを使用してモジュールを結合する方が合理的かどうかを検討してください。 Bicep モジュールについては、Bicep ラーニング パスの全体を通して詳しく説明します。

構造の作成での空白の活用方法

空白行または "空白" は、テンプレートに視覚的な構造を付加するのに役立ちます。 空白を慎重に使用することで、Bicep コードのセクションを論理的にグループ化できます。これは、リソース間の関係を明確にするのに役立ちます。 これを行うには、希望するグループ化のスタイルに関係なく、メジャー セクション間に空白行を追加することを検討してください。

類似したリソースを定義する方法

Bicep では、ループを使用して、1 つの定義から類似した複数のリソースをデプロイできます。 for キーワードを使用してリソースのループを定義することで、Bicep コードをよりクリーンにし、リソース定義の不要な重複を減らします。 将来、リソースの定義を変更する必要がある場合は、1 つの場所を更新するだけです。 既定では、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 データベースは 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 ファイルが煩雑になるだけであり、コメントアウトされたリソースがまだ存在する理由を他のユーザーが理解することは難しくなります。

もう 1 つの考慮事項は、予測できない結果や悪影響を及ぼすおそれのある定義をだれかが誤ってコメント解除する可能性があることです。 バージョン管理システムを使用すると、古いリソース定義を簡単に削除できます。 後で定義が再び必要になった場合は、ファイル履歴から取得できます。