Azure Bicep で Infrastructure as Code 実現

![Qiita_1280x500.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287622/e2708399-a594-4cb4-6dd3-bc60230e93c7.png)

# 概要

Azureリソースをコードで管理する仕組みとしてAzure Resource Manager Template（以下、ARMテンプレート）があります。定義構文はJSON形式です。
昨年、Azure Bicep（以下、Bicep）が登場することにより、従来のJSON構文からBicep構文が加えられました。
BicepとはAzureリソースをデプロイする作業に特化して設計された言語、ドメイン固有言語(DSL)です。
JSON構文とBicep構文の比較は[Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/bicep/compare-template-syntax)に纏まっているのでご参考ください。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Let&#39;s get an Intro to Bicep 💪.<br><br>In today&#39;s <a href="https://twitter.com/hashtag/AzureFunBytes?src=hash&amp;ref_src=twsrc%5Etfw">#AzureFunBytes</a>, we learn how to create a basic template, deploy it to Azure, and look at how quickstart templates are converted in the Bicep Playground using Bicep CLI, the <a href="https://twitter.com/hashtag/VSCode?src=hash&amp;ref_src=twsrc%5Etfw">#VSCode</a> plug-in, and Azure CLI. 👀 <a href="https://t.co/BQOs4J68EU">https://t.co/BQOs4J68EU</a></p>&mdash; DevOps on Azure (@AzureDevOps) <a href="https://twitter.com/AzureDevOps/status/1403014089257914368?ref_src=twsrc%5Etfw">June 10, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# デモ

Bicep PlaygroundでJSON構文を比べながら試すことができます。

https://bicepdemo.z22.web.core.windows.net/

# 準備

Windows、MacOS、Linux環境で使えるように [Visual Studio Code](https://code.visualstudio.com/) と [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) をインストールします。
Visual Studio Codeをインストール後、[Bicep拡張機能](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-bicep) をインストールすると構文の検証、リソースの視覚化など便利な機能を使えるようになります。
Azure CLIはBicepを使うのにバージョンが`v2.20.0`以上であることをご確認ください。

# 学習

Bicepの学習は [Microsoft Learn](https://docs.microsoft.com/ja-jp/learn/paths/fundamentals-bicep/) をご参考ください。

# 形式

公式の [Bicep形式](https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/bicep/file#bicep-format) です。
注意しなければいけないのは、Bicepは`宣言型言語`なので定義されたリソースの要素に対して順序はデプロイの処理に影響しないことです。
リソースAとB順序に書いてもAが終わってからBがデプロイされる処理ではないことです。

`ターゲットスコープ`、`パラメーター`、`デコレーター`、`変数`、`リソース`、`モジュール`、`出力`の形式で構成されてますが、必要に応じて作成すれば良いと思います。

```js
// ターゲットスコープ
targetScope = '<scope>'

// パラメーターとデコレーター
@<decorator>(<argument>)
param <parameter-name> <parameter-data-type> = <default-value>

// 変数
var <variable-name> = <variable-value>

// リソース
resource <resource-symbolic-name> '<resource-type>@<api-version>' = {
  <resource-properties>
}

// モジュール
module <module-symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}

// 出力
output <output-name> <output-data-type> = <output-value>
```

# 実装例

試しにストレージアカウントを作成するためのBicepファイルを作成してみます。

```js:storage.bicep
// パラメーターとデコレーター
@minLength(3)
@maxLength(11)
param storagePrefix string
param storageSKU string = 'Standard_LRS'
param location string = resourceGroup().location

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

// リソース
resource storage 'Microsoft.Storage/storageAccounts@2021-06-01' = {
  name: uniqueStorageName
  location: location
  sku: {
    name: storageSKU
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

// 出力
output storageEndpoint object = storage.properties.primaryEndpoints
```

Visual Studio Codeから作成するとリソース可視化まで確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287622/ebc32f00-d39c-8c1b-9f68-4b77cb91f046.png)

## 関数

`resourceGroup()`または`uniqueString()`はBicepで使える関数となります。
使い方など詳細な内容を [Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/bicep/bicep-functions) をご参考ください。

## APIバージョン

`Microsoft.Storage/storageAccounts@2021-06-01`のようにARMテンプレートをデプロイするとAzureではAzure Resource Manager APIを呼び出しますが、同じリソース(例、ストレージアカウント)でもリソースを機能追加などでスキーマが更新されるため、APIバージョンで管理しています。
APIバージョンが変わるとプロパティが変わったりするので、詳細な内容は [Microsoft Docs](https://docs.microsoft.com/en-us/azure/templates/) でご確認ください。
ちなみに、もう少し詳細な内容を知りたい方は [ARMスキーマリポジトリ](https://github.com/Azure/azure-resource-manager-schemas/tree/main/schemas) と [Azure REST APIスペックリポジトリ](https://github.com/Azure/azure-rest-api-specs) をご参考ください。

# 配置(デプロイ)

Bicepファイルを作成できたら、Azure CLIでデプロイします。

```shell:Azureにログイン
# Azure CLIバージョンを確認してアップグレードします。
> az --version
azure-cli    2.32.0
...
> az upgrade

# Azureにログインします。
> az login

# サブスクリプションの一覧を表示します。
> az account list --output table --all
Name              CloudName    SubscriptionId                        State    IsDefault
----------------  -----------  ------------------------------------  -------  -----------
Hello Internal    AzureCloud   xxxxxxxx-1111-2222-3333-xxxxxxxxxxxx  Enabled  False

# サブスクリプションを選択します。
> az account set --subscription "Hello Internal"
```

```shell:リソースグループ作成
# 東日本でリソースグループを作成します。
> az group create --name rg-hello-dev --location japaneast
```

Bicepファイルは Azure CLIで実行します。
実行結果内容から出力で定義した内容が加えられて出力されることを確認できます。

```shell:ストレージアカウント作成
# Bicepファイルからストレージアカウントのデプロイします。
> az deployment group create --resource-group rg-hello-dev --template-file storage.bicep --parameters storageName=blog
{
  ...
  "properties": {
    ...
    "outputs": {
      "storageEndpoint": {
        "type": "Object",
        "value": {
          "blob": "https://bloghash123456789.blob.core.windows.net/",
          "dfs": "https://bloghash123456789.dfs.core.windows.net/",
          "file": "https://bloghash123456789.file.core.windows.net/",
          "queue": "https://bloghash123456789.queue.core.windows.net/",
          "table": "https://bloghash123456789.table.core.windows.net/",
          "web": "https://bloghash123456789.z11.web.core.windows.net/"
        }
      }
    },
    ...
  },
  ...
}
```

Azureポータルからでもデプロイ結果に対して確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287622/356063bd-5ff3-17a4-833e-9f7657f04f1f.png)