Azure Bicep を使ってみる (2)

Microsoft Ignite (March 2-4, 2021) で Azure Bicep にちょっと興味を持ちました。
これまでやったことを忘れてしまいそうなので、前回に引き続きここに備忘録として置きます。

[前回](https://qiita.com/tetsuya-ooooo/items/9812d30d55b72044fd4d)は、Bicep 開発を行うための環境の準備と、Bicep ファイルからストレージアカウントをデプロイしてみました。
今回は、リソースの依存関係について Bicep ファイルではどのように表すのかということを残しておきます。


# リソースの依存関係

リソースをデプロイする時に、一部のリソースが他のリソースの前に存在していることを確認しなければならない場合があります。例えば、仮想マシンを作成するには、その前にネットワーク インターフェイス (、Unmanaged Disk の場合はストレージ アカウントも) が存在している必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/6dd8581f-1fbe-588b-92fe-8cd4ac7cfcc4.png)


## ARM テンプレートでは

ARM テンプレートでは、このリレーションシップ (あるリソースが他のリソースに依存している) を ```dependsOn``` 要素内に文字列の JSON 配列で**リソース名**、または**リソース ID** を列挙して定義します。

以下のテンプレートでは、リソースの依存関係を以下のように定義しています。

- **ネットワーク インターフェイス リソース**は、**仮想ネットワーク リソース**と**パブリック IP リソース**に依存している
- **仮想マシン リソース**は、**ネットワークインターフェイス リソース**に依存している


```json-doc:ネットワーク&#x20;インターフェイスの依存関係
/* ネットワーク インターフェイスの定義 */
{
    "type": "Microsoft.Network/networkInterfaces",
    "apiVersion": "2018-10-01",
    "name": "[parameters('networkInterfaceName')]",
    "location": "[parameters('location')]",
    "dependsOn": [
        /* 依存リソース */
        "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]",
        "[concat('Microsoft.Network/publicIpAddresses/', parameters('publicIpAddressName'))]"
    ],
    "properties": {
        /***** 中略 *****/
    }
}
```
```json-doc:仮想マシン&#x20;リソースの依存関係
/* 仮想マシンの定義 */
{
    "type": "Microsoft.Compute/virtualMachines",
    "apiVersion": "2021-03-01",
    "name": "[parameters('virtualMachineName')]",
    "location": "[parameters('location')]",
    "dependsOn": [
        /* 依存リソース */
        "[concat('Microsoft.Network/networkInterfaces/', parameters('networkInterfaceName'))]"
    ],
    "properties": {
        /***** 中略 *****/
    }
}
```


## Bicep ファイルでは

Bicep ファイルでは、このリレーションシップを**シップシンボリック名**を参照することで ```dependsOn``` プロパティが自動的に追加されます。

リソース ID はリソースのシンボリック名から簡単に参照することができます。例えば、ネットワーク インターフェイスのリソース ID は ```networkInterfaceName_resource.id``` というように参照でき、コンパイルされた ARM テンプレートでは [resourceId 関数](https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/templates/template-functions-resource?WT.mc_id=AZ-MVP-5003113&tabs=json#resourceid)に変換されます。

```python:ネットワークインターフェイスの依存関係
var vnetId = resourceId(resourceGroup().name, 'Microsoft.Network/virtualNetworks', virtualNetworkName)
var subnetRef = '${vnetId}/subnets/${subnetName}'

/* ネットワーク インターフェイス リソースの定義 */
resource networkInterfaceName_resource 'Microsoft.Network/networkInterfaces@2018-10-01' = {
  name: networkInterfaceName
  location: location
  properties: {
    ipConfigurations: [
      {
        name: 'ipconfig1'
        properties: {
          subnet: {
            /* ↓↓↓ 仮想ネットワーク リソース (サブネット) を参照 */
            id: subnetRef
          }
          privateIPAllocationMethod: 'Dynamic'
          publicIPAddress: {
            /* ↓↓↓ パブリック IP リソースを参照 */
            id: resourceId(resourceGroup().name, 'Microsoft.Network/publicIpAddresses', publicIpAddressName)
          }
        }
      }
    ]
    enableAcceleratedNetworking: enableAcceleratedNetworking
  }
  dependsOn: [
    virtualNetworkName_resource
    publicIpAddressName_resource
  ]
}
```
```python:仮想マシンの依存関係
/* 仮想マシン リソースの定義 */
resource virtualMachineName_resource 'Microsoft.Compute/virtualMachines@2021-03-01' = {
  name: virtualMachineName
  location: location
  properties: {
    /*** 中略 ***/
    networkProfile: {
      networkInterfaces: [
        {
          /* ↓↓↓ ネットワーク インターフェイス リソースを参照 */
          id: networkInterfaceName_resource.id
        }
      ]
    }
    /*** 中略 ***/
  }
}
```


# まとめ

スッキリした情報量なので、やりたいことがより分かりやすいですね :heart_eyes:


# 参考文献

https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/templates/define-resource-dependency?WT.mc_id=AZ-MVP-5003113

https://docs.microsoft.com/ja-jp/learn/paths/bicep-deploy/?WT.mc_id=AZ-MVP-5003113