IaC 新時代! Azure Bicep を触ってみる!

IaC 新時代! Azure Bicep を触ってみる!

IaC (Infrastructure as Code) してますか?

クラウド使ってるなら当然してますよね。え、してない? そう、プラットフォームが変わろうと中々難しいものなんです。今回は IaC をより進めやすくなる Azure の新しい取り組みを紹介します。

Azure における IaC

ARM テンプレート

Azure をはじめクラウドプラットフォームサービスでは各種サービスをプログラマブルに扱えるよう、サービス展開を API や JSON データで扱えるようなインタフェースを用意しています。Azure を例に取ると ARM テンプレートと呼ばれるものが一例です。JSON で Azure の各サービスに必要なパラメータを記述していきます。(ちなみに仮想ネットワークを示したものです)

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "suffix": {
      "type": "string",
      "defaultValue": "001"
    },
    "addressPrefix": {
      "type": "string",
      "defaultValue": "10.0.0.0/15"
    }
  },
  "functions": [],
  "variables": {
    "vnetName": "[format('vnet-{0}', parameters('suffix'))]"
  },
  "resources": [
    {
      "type": "Microsoft.Network/virtualNetworks",
      "apiVersion": "2020-06-01",
      "name": "[variables('vnetName')]",
      "location": "[resourceGroup().location]",
      "properties": {
        "addressSpace": {
          "addressPrefixes": [
            "[parameters('addressPrefix')]"
          ]
        },
        "enableVmProtection": false,
        "enableDdosProtection": false,
        "subnets": [
          {
            "name": "subnet001",
            "properties": {
              "addressPrefix": "10.0.0.0/24"
            }
          },
          {
            "name": "subnet002",
            "properties": {
              "addressPrefix": "10.0.1.0/24"
            }
          }
        ]
      }
    }
  ]
}

単なる自動化であればスクリプトでも同じ効果だと思いますが、一般に IaC の利点は次のようなことが挙げられます。

  • コードベース
  • 自動化
  • 冪等性

コードベースなので GitHub などのサービスで変更履歴を管理しやすいです。当然プログラマブルなので自動化にもつなげやすいです。ヒューマンエラーも減ります。

大きな特徴としては冪等性が挙げられます。つまりはいつやっても同じ結果になるということです。スクリプトだと既に存在しているリソースを作成しようとしてエラーになったり、それを回避して例外処理したりするとどんどん複雑になります。自動化してるのならいつでも同じ結果になるよう楽をしたいものです。

Azure Bicep

楽をできるのはわかりましたが、流石に JSON は人間が読むために最適化されているとは言えません。今までは ARM テンプレートで JSON 形式のデータを直接記述するしかありませんでした。

技術者の利便性を向上させるために開発されたのが Bicep Project です。

Bicep は Azure リソースを展開するために開発された新しい言語です。まず大きな特徴として、Bicep は Azure 専用の言語 (DSL: ドメイン固有言語) だということです。Python や C 言語のように記述できますが、一般的な計算処理やシステム開発を目的とはしていません。

Azure Bicep は新しい Azure での IaC ツールですが、今のところは ARM テンプレートがリタイアする計画はありません。また、基本的に Bicep と ARM テンプレート (JSON 形式データ) は透過的な変換が可能なので相互に補完できます。あくまでも Azure における新しい IaC の表現方法の一つだということです。

ちなみに直訳で bicep = 上腕二頭筋らしいです。

Bicep インストール

Bicep のインストールは Azure CLI、もしくは各種プラットフォーム上で可能です。Azure CLI ないであればクロスプラットフォームで対応しているので今回は Azure CLI の手順を紹介します。

Azure CLI をインストールした環境で次のコマンドを実行します。

az bicep install

インストール済みの環境でアップグレードするには次のコマンドを実行します。

az bicep upgrade

特定のバージョンを指定してインストールする場合は次のコマンドを実行します。--version は好きなバージョンを指定します。

az bicep install --version v0.2.212

インストール済みのバージョンは次のコマンドで確認できます。


Bicep 拡張機能

Visual Studio Code を使っているなら拡張機能が使えます。”Bicep” と検索して拡張機能をインストールします。これで Bicep 言語のインテリジェントが効くようになります。

Bicep 触ってみる

まずは簡単に Bicep で扱うファイルを見てみます。次の内容を sample.bicep という名前で保存します。ストレージアカウントを一つ作るコードです。{provider-unique-name} には好きな文字列を入力して名前が被らないようにしてください。

resource stg 'Microsoft.Storage/storageAccounts@2019-06-01' = {
  name: '{provide-unique-name}'
  location: 'eastus'
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

少し解説すると、resource というのが型のような宣言文であり、ここではリソースを宣言しています。続く stg は 言語内での名前でインスタンス名みたいなものです。その後ろには Azure サービスの種類と API バージョンを指定する文字列が続きます。(VS Vode ならインテリジェントがついて見やすいです)

一番外側の {} 内には ARM テンプレートと同じように記述するパラメータが入ります。タブ補完が効くのでだいぶ記述しやすいです。カンマやカッコなどの余分な情報がないのも可読性が高いです。

ARM テンプレートのリファレンスにも Bicep の記述方式が合わせて記載されるようになっています。

Microsoft.Storage/storageAccounts 2019-06-01 – ARM template reference | Microsoft Docs

ファイルを保存し、テスト用にリソースグループを作ってデプロイしてみます。

az login
az account set --subscription [SubscriptionID/SubscriptionName]
az group create \
  --name myResourceGroup \
  --location "Central US"

// bicep ファイルのパスを指定
bicepFile="{provide-the-path-to-the-bicep-file}"
az deployment group create \
  --name firstbicep \
  --resource-group myResourceGroup \
  --template-file $bicepFile

展開が成功するとストレージが作成されます。

Bicep の構文を少しだけ解説

Bicep では次のような構文が利用できます。

@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 = resourceGroup().location

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

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

output storageEndpoint object = stg.properties.primaryEndpoints

パラメータ

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

ARM テンプレートと同じようにパラメータを定義できます。パラメータには型や最大長など同じ制限を付与できます。

変数

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

入力を必須としない変数を定義できます。一つのパラメータから複数の変数を生成するなどして他の場所で使いまわせます。

関数

ARM テンプレートと同様に resourceGroup() といった関数を利用できます。リソースグループに応じたロケーションの設定などは非常に楽になりそうです。

出力

output storageEndpoint object = stg.properties.primaryEndpoints

出力結果を表示できます。展開後に決定する値の確認やレビューに利用できます。

Bicep と JSON の変換

有志のサイトで Bicep を JSON に変換、もしくは読み込んだ JSON を Bicep に変換するサイトがあります。サンプルも提供されているので一度見てみるとイメージがつきやすくなります。

Bicep Playground 0.3.13-g311f540d3c (windows.net)

Bicep と JSON を比較した内容は次の記事にまとまっています。

Azure Resource Manager テンプレートの構文を JSON と Bicep で比較する – Azure Resource Manager | Microsoft Docs

Bicep 感想

プログラミング言語ライクになっているので可読性が非常に上がっています。GitHub などに夜管理も楽になるでしょう。書いてみてわかりましたが、制御構文 (カンマやカッコ) が気にならなくなるので書き上げが速いです。

一方でまだ全ての ARM テンプレート互換に対応はしていません。copy() などはまだ対応していないと思います。バージョン 0.3 なのでそこはこれからの成長に期待です。