🗂

Bicepで使える構文と使い所をまとめてみる(1)

2023/05/14に公開

bicepで使える構文と使い所を整理してみようと思います。ものによっては、もっとスマートな書き方があるでしょうが、そう感じるようになったらそれはそれで良いのではないでしょうか。

https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/bicep/file


Jsonファイルで外部化したパラメータを読み出す

  1. loadTextContext()でファイル読み込み
  2. 読み込んだ文字列をjson()でparse
    ※ 使ったことないが、loadJsonContent()と書いてもよいかもしれません。bicep始めた頃にはまだ無かった関数なので、、、
  3. データ項目はstringとして扱われる
  4. 数値にしたい場合は、int()でparseする
  • 以下は、PostgreSQL Flexible Serverのパラメータ指定をJsonファイルで外部ファイル定義とした例
    • paramで指定してもよいが、今回は例として、jsonファイルから読み出し
      実際には、ipアドレスリストなどを外部ファイル化する使い方が多い(例は後ほど)
    • int()の例としてpsqlのparameterをjsonから読み出し
var _psql_define = json(loadTextContent('../env/psql.json')).psql
// var _psql_define = loadJsonContent('./env/psql.json').psql

var _sku_name = _psql_define.sku.name
var _sku_tier = _psql_define.sku.tier

var _psql_version = _psql_define.version
var _storage_size = int(_psql_define.storageSizeGB)


  • jsonファイル定義例
{
  "psql": {
    "version": "14",
    "sku": {
      "name": "Standard_B1ms",
      "tier": "Burstable"
    },
    "storageSizeGB": "32",
  }
}

https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/bicep/bicep-functions-files


for文

  1. for文を使ってデプロイ処理をループすることが可能
  2. デプロイ処理に限らず変数の処理でもfor文を利用可能
  • 以下は、リソースグループ名をリスト化してfor文で作成する例
    • デプロイスコープをsubscriptionにしているので、locationを指定
    • 多くのテンプレートでは、locationを明示的に指定するのは、リソースグループのデプロイ時だけになると思う
      リソースグループのデプロイ時だけ、指定するようになるよう作成することをおすすめ
targetScope = 'subscription'
param location string = 'japaneast'

var _rgs = [
  'rg-app-01'
  'rg-db-01'
  'rg-net-01'
]

resource rg 'Microsoft.Resources/resourceGroups@2022-09-01' = [for name in _rgs: {
  name: name
  location: location
}]

https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/bicep/loops


ResourceGroup関数とlocation

  1. resourceGroup()の引数なしはデプロイで指定したリソースグループの情報を取得
  2. リソースグループのlocationは、resourceGroup()の変数として格納されている
  3. デプロイするリソースのlocationをリソースグループと同じlocationことでlocationをハードコードする事がなくなりテンプレートを再利用しやすくなる
  • 以下は、Managed Idのデプロイ例
param location string = resourceGroup().location
param id_name string

resource id 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31'= {
  name: id_name
  location: location
}

https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/bicep/bicep-functions-scope#resourcegroup


三項演算子とempty関数

  1. bicepでは条件判定に三項演算子を使用する
    if文は別の用途で使用
  2. 値、配列の空文字、空配列、null判定はempty()を使用する
  • 以下は、ActivityLogの診断設定のデプロイテンプレートの例
    • エクスポート先(Storage Account, LogAnalytics workspace)をempty()を使い、resourceIdが指定されたかどうかを判断し、指定されていなければ、nullを設定、指定されていれば指定した値を設定する
    • ActivityLogの場合は、scopesubscription()を設定
targetScope = 'subscription'

param log_id string = ''
param st_id string

param logs array = [
// 省略
]

resource diag 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
  name: 'diag-log'
  scope: subscription()
  properties: {
    workspaceId: empty(log_id) ? null : log_id
    storageAccountId: empty(st_id) ? null : st_id
    logs: logs
  }
}

https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/bicep/operators

https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/bicep/bicep-functions-array#empty


resourceId関数

  1. resourceId()でリソースIDを取得する
  2. 前述の通り、for文はデプロイ以外に変数処理でも使用可能
  3. 文字列の結合はformat()を使っても良いし、${}を使ってもどちらでも可能。読みやすい書き方をすればよいでしょう
  • 以下は、key vaultのデプロイテンプレートの例
    • networkAcls(ネットワークルール)で設定するvirtualNetworkRules(サービスエンドポイント)のsubnetIdのid,ignoreMissingVnetServiceEndpointを持ったオブジェクのトリストをfor文で作成
    • ipRulesは外部ファイルから読み出し、ipアドレスをvalueで持ったオブジェクトリストをfor文で作成
    • tenantIdの指定もtenant()を使用してハードコードを避け、テンプレートファイルを再利用しやすくする
param location string = resourceGroup().location
param kv_name string

var _ips = json(loadTextContent('./env/ip-list.json'))
var _allow_ip_rules = [for ip in _ips.ip_list['allow-ip-rule']: {
  value: ip
}]

var _snets = [
  {
    vnet_rg_name: 'rg-net-01'
    vnet_name: 'vnet-01'
    name: 'snet-01'
  }
  {
    vnet_rg_name: 'rg-net-02'
    vnet_name: 'vnet-02'
    name: 'snet-01'
  }
]

var _vnet_se = [for snet in _snets: {
  id: format('{0}/subnets/{1}', resourceId(snet.vnet_rg_name, 'Microsoft.Network/virtualNetworks', snet.vnet_name), snet.name)
  ignoreMissingVnetServiceEndpoint: false
}]

resource kv 'Microsoft.KeyVault/vaults@2023-02-01' = {
  name: kv_name
  location: location
  properties: {
    createMode: 'default'
    enableRbacAuthorization: true
    enablePurgeProtection: true
    softDeleteRetentionInDays: 3
    networkAcls: {
      defaultAction: 'Deny'
      bypass: 'AzureServices'
      ipRules: _allow_ip_rules
      virtualNetworkRules: _vnet_se
    }
    sku: {
      family: 'A'
      name: 'standard'
    }
    enabledForTemplateDeployment: true
    tenantId: tenant().tenantId
  }
}

https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/bicep/bicep-functions-resource#resourceid


  • jsonファイルでのipリスト定義例
{
  "ip_list": {
    "allow-ip-rule": [
      "a.d.u.x",
      "b.e.v.y",
      "c.f.w.z"
    ]
  }
}


Date関数

  1. 現在時刻や日時はutcNow()を使用して取得する
  2. 日付・時間の計算はdateTimeAdd()を使用する
  • 以下は、module構文を使ってデプロイするテンプレートの例
    • module構文でのデプロイ名に日時を付加する場合に指定するutcNow()を使用
param now string = utcNow('yyyyMMdd-HHmmss')
targetScope = 'subscription'

param st_name string
param st_rg_name string

module diag_activity './modules/diag-activity.bicep' = {
  name: 'diag-log-activity-${now}'
  scope: subscription()
  params: {
    st_id: st.id
  }
}

module diag_aad './modules/diag-aad.bicep' = {
  name: 'diag-log-aad-${now}'
  scope: subscription()
  params: {
    st_id: st.id
  }
}

resource st 'Microsoft.Storage/storageAccounts@2021-09-01' existing = {
  name: st_name
  scope: resourceGroup(st_rg_name)
}


  • 以下は、Automation Accountでスケジュール登録を作成するテンプレートの例から抜粋
    • 日付をutcNow()を使って文字列として取得
    • dateTimeAdd()を使って開始時刻の文字列を作成
param today string = utcNow('yyyy-MM-dd')
param start_schedule_time string
param stop_schedule_time string

var _start_schedule_time = dateTimeAdd('${today}T${start_schedule_time}', 'P1D')
var _stop_schedule_time = dateTimeAdd('${today}T${stop_schedule_time}', 'P1D')
// correction: 'Asia/Tokyo'
var _start_local_time = dateTimeAdd(_start_schedule_time, '-PT9H')
var _stop_local_time = dateTimeAdd(_stop_schedule_time, '-PT9H')

https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/bicep/bicep-functions-date


  • 参考: Automation Accountでスケジュール登録するテンプレートの例

https://zenn.dev/lente/articles/azure-fw-start-stop#runbookのスケジュール登録



以上、ここまで。

Discussion