Bicep によるAzure のインフラ構築入門

概要

こんにちは、サイオステクノロジーの安藤 浩です。

Bicepは、Azureリソースを宣言的にデプロイするためのドメイン固有言語(DSL)であり、ARMテンプレートの記述を簡素化することを目的としています。ARM テンプレートは、JSON または Bicep の使用という 2 つの異なる方法で記述できますが、JSONの場合は複雑な記法が必要になります。

私自身ARM テンプレート は書いたことないですが、ARM テンプレート自体複雑な印象で記述が困難なように思います。

JSON と Bicep の比較はBicep プレイグラウンドで確認することができます。

以下のAzure のLearning があるのでそちらを参照するとBicep に関して学習できます。

Bicep に関する Learn モジュール

前提条件

以下をインストールします。

構成要素

今は例として以下の構成要素でBicep によるAzure のインフラ構築をしてみます。

  • Azure Function
  • Blob Storage
  • Application Insights
  • LogAnalytics Workspace
  • App Service Plan

ソースコード

ソースコードは以下にあります。

https://github.com/Hiroshi-Ando-sti/introduction-bicep

実装方法

まずは、 main.bicep を用意し、以下を記載します。

targetScope = 'resourceGroup'

param location string = resourceGroup().location
@description('The environment designator for the deployment. Replaces {env} in namingConvention.')
@allowed([
  'dev' //Develop
  'stg' //Staging
  'prd' //Production
])
param enviromentName string = 'dev'
var enviromentResourceNameWithoutHyphen = replace(enviromentName, '-', '')

@allowed(['northeurope', 'southeastasia', 'eastasia', 'eastus2', 'southcentralus', 'australiaeast', 'eastus', 'westus2', 'uksouth', 'eastus2euap', 'westus3', 'swedencentral'])
param hostingPlanLocation string = 'eastus2'

@description('The workload name. Replaces {workloadName} in namingConvention.')
param workloadName string = 'pj'

param deploymentStorageContainerName string = 'app-pkg-func'

@description('secretName')
param secretName1 string

@secure()
@description('secretValue')
param secretValue1 string


var suffixResourceName = '-${workloadName}'
var suffixResourceNameWithoutHyphen = replace(suffixResourceName, '-', '')
var uniqueStr = uniqueString(resourceGroup().id, enviromentName, workloadName, suffixResourceNameWithoutHyphen)

param convertedEpoch int = dateTimeToEpoch(dateTimeAdd(utcNow(), 'P1Y'))

var abbrs = json(loadTextContent('abbreviations.json'))

var tags = {
  workload: workloadName
  environment: enviromentName
}

記述方法

主要なBicep の記述方法について説明します。

param(パラメータ)

paramは、実行時に値をBicepテンプレートに渡すためのパラメータを定義するために使用されます。これにより、テンプレートの再利用が可能になり、値のハードコーディングを避けられます。

例:

@allowed([
  'dev' //Develop
  'stg' //Staging
  'prd' //Production
])
param enviromentName string = 'dev'

ここでは、enviromentNameという名前のstring型のパラメータが定義されており、デフォルト値: dev が設定されています。

  • stringintboolarrayobject などの型を指定できます。
  • デフォルト値: パラメータにデフォルト値を設定することも可能です。

description

descriptionは、パラメータや変数の説明を提供するために使用されます。

allowed

allowedは、パラメータの許可された値を制限するために使用されます。これにより、指定値以外の不正な値を設定することを防ぐことができます。

var(変数)

varは、テンプレート内で中間的な値や計算結果を保持するための変数を定義するために使用されます。

例:

var uniqueStr = uniqueString(resourceGroup().id, enviromentName, workloadName, suffixResourceNameWithoutHyphen)

この例では、uniqueStr という変数に、リソースグループのID, enviromentName などに基づいて生成された一意の文字列が設定されています。

  • : 変数は、式や文字列の連結、計算などを保持できます。
  • スコープ: 変数はテンプレート内でのみ使用可能で、外部には公開されません。

secure(セキュアパラメータ)

Bicepでは、パスワードやAPIキーのような機密情報を取り扱う場合、セキュアなパラメータを定義できます。ログや出力には表示されず、デプロイメント中に値が安全に処理されます。

例:

@secure()
@description('secretValue')
param secretValue1 string

module(モジュール)

module は、他のBicepテンプレートを参照して再利用するために使用されます。テンプレートを分割して、管理しやすくなります。例えば、Azure Function や AppService などのリソースに対するStorage Accountを作成する際に再利用可能なモジュールを作成できます。

例:

./main.bicep

var storageAccountName = '${abbrs.storageStorageAccounts}${enviromentResourceNameWithoutHyphen}${uniqueStr}'
module storage 'modules/storage/storage.bicep' = {
  name: 'storage'
  params: {
    storageAccountName: storageAccountName
    location: location
    tags: tags
    storageAccountType: 'Standard_LRS'
    containerNames: [deploymentStorageContainerName]
  }
}

./modules/storage/storage.bicep

@description('Storage Account type')
@allowed([
  'Premium_LRS'
  'Premium_ZRS'
  'Standard_GRS'
  'Standard_GZRS'
  'Standard_LRS'
  'Standard_RAGRS'
  'Standard_RAGZRS'
  'Standard_ZRS'
])
param storageAccountType string = 'Standard_LRS'

@description('The storage account location.')
param location string = resourceGroup().location

param tags object = {}

@description('The name of the storage account')
param storageAccountName string

param containerNames array

resource sa 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: storageAccountName
  location: location
  tags: tags
  sku: {
    name: storageAccountType
  }
  kind: 'StorageV2'
  properties: {}
}

resource blobServices 'Microsoft.Storage/storageAccounts/blobServices@2023-01-01' = {
  parent: sa
  name: 'default'
}

resource containers 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-01-01' = [for containerName in containerNames: {
  parent: blobServices
  name: containerName
}]


output storageAccountName string = storageAccountName
output storageAccountId string = sa.id

この例では、module を利用し、 ./modules/storage/storage.bicep をインポートして再利用しています。

  • モジュール化: 複雑なインフラを整理し、リソースをモジュールにグループ化するのに役立ちます。
  • 再利用: モジュールは、異なるデプロイメントで再利用可能です。

resource(リソース)

resource は、Azureリソースを定義するために使用されます。リソースの種類、プロパティ、依存関係など、リソースの詳細を定義します。

リソースの定義は、Microsoft.Storage/storageAccounts@2023-01-01 という形式で指定します。リソースの種類とAPIバージョンを指定しています。

詳しくは、リソースの Bicep を使った宣言 を参照ください。

Storage Accountの場合は、以下を参照して詳細なプロパティなどを指定します。

https://learn.microsoft.com/ja-jp/azure/templates/microsoft.storage/storageaccounts

output(出力)

output は、デプロイメントが完了した後に値を返すために使用されます。リソースIDや接続文字列のような情報をデプロイ後に返す場合に便利です。

上記の例では、作成されたストレージアカウントのリソースIDを返します。

  • データの返却: 出力された値は、後続のデプロイメントや追加のアクションで使用できます。
  • 複数の出力: 1つのBicepファイルに複数の output ステートメントを含めることができます。

その他

Best practice の記載があるのでこちらを参考にしてBest Practice を実践しましょう。

パラメーター ファイルを使用して値を指定する

Bicep では、パラメーター ファイルを使用して、Bicep テンプレートに渡す値を指定することができます。 パラメーター ファイルは、JSON 形式のファイルで、Bicep テンプレートのパラメータ(param)に渡す値を定義します。

main.parameters.dev.json を main.bicep と同階層に作成します。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "value": "eastus2"
    },
    "enviromentName": {
      "value": "dev"
    },
    "hostingPlanLocation": {
      "value": "eastus2"
    },
    "workloadName": {
      "value": "pj-bicep"
    },
    "deploymentStorageContainerName": {
      "value": "app-pkg-func"
    },
    "secretName1": {
      "value": "secretName1"
    },
    "secretValue1": {
      "value": "secretValue1"
    }
  }
}

新規作成

リソースグループ作成

リソースグループを作成します。

az group create --name rg-dev-pj-bicep --location japaneast

デプロイ

上記で作成したリソースグループへリソースをデプロイします。

az deployment group create \
  --name rg-dev-pj-bicep-deploy \
  --resource-group rg-dev-pj-bicep \
  --mode Complete \
  --confirm-with-what-if \
  --template-file main.bicep \
  --parameters ./main.parameters.dev.json

ここでは mode にComplete と指定して、完全モードでDeployしています。 完全モードは、 Bicep コードに 定義されているリソースのみをデプロイするモードです。Bicep コードに存在しない既存のリソースが存在する場合は、削除されます。

もう一方、インクリメントモードがあり、Bicep コードに存在しない既存のリソースが存在してもリソースの影響は受けません。

更新

リソースの作成が完了したら、もう一度同じコマンドを実行すると変更箇所の差分が確認できます。

az deployment group create \
  --name rg-dev-pj-bicep-deploy \
  --resource-group rg-dev-pj-bicep \
  --mode Complete \
  --confirm-with-what-if \
  --template-file main.bicep \
  --parameters ./main.parameters.dev.json

実行すると以下のように変更箇所を教えてくれます。

確認方法

コマンドの結果でも確認できますが、リソースグループの「概要」の「要点」の箇所のデプロイのところを確認することも可能です。

リンクを押下すると以下のようになります。

リンクの function, appInsights, storage などは main.bicep の module で指定した name に対応します。より詳細は各リンクを押下すると確認できます。

参考URL

Bicep とは

Bicep のドキュメント

Bicep の基礎

Bicep に関するベスト プラクティス

サンプルコード

まとめ

Bicep を利用して、簡単に Azure のインフラ構築をしてみました。割と簡単な記述でリソース作成ができるので、ぜひ使ってはいかがでしょうか。

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です