ARM Template の書き方 その1 基本構文

  • AzureResourceManager
  • テンプレートの構文

    はじめに

    以前に ARM Template の Deploy をという記事を書きました。まずは使ってみようということでストレージアカウントだけ ARM テンプレートを使ってデプロイしています。

    今回は、これから ARM テンプレートを使って行くに当たっての基本となる文法を押さえておこうかと思い書いています。

    ARM テンプレートの構文は Microsoft のドキュメントで詳しく書かれています。

    上記URLの内容も分かりやすいと思いますが、私なりの解説も入れていきたいと思います。

    テンプレートの構造

    テンプレートの構造は以下のようになっています。緑色が必須パラメータです。

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
      "contentVersion": "",
      "apiProfile": "",
      "parameters": {  },
      "variables": {  },
      "functions": [  ],
      "resources": [  ],
      "outputs": {  }
    }

    $schema ※必須

    テンプレートファイルを送信する先の API の URL を指定します。

    たとえば、PoweShell を使ってテンプレートをデプロイする場合は、各 schema に対して別々のコマンドを実行しなければいけません。

    # リソースグループデプロイ # https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json# New-AzResourceGroupDeployment -ResourceGroupName "resource-group-name" -TemplateFile "path-to-template" # サブスクリプションデプロイ # https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json# New-AzSubscriptionDeployment -Location "location" -TemplateFile "path-to-template" # 管理グループデプロイ # https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json# New-AzManagementGroupDeployment -Location "location" -TemplateFile "path-to-template" # テナントデプロイ # https://schema.management.azure.com/schemas/2019-08-01/tenantDeploymentTemplate.json# New-AzTenantDeployment -Location "location" -TemplateFile "path-to-template"

    どのレイヤーで実行するテンプレートかを設計しておく必要があります。用途に応じた schema を選択すべきです。

    contentVersion ※必須

    任意の値を指定できます。バージョン番号を入力するところだそうです。これによりテンプレートのバージョン管理が捗ります。

    そして、指定することが必須です。

    apiProfile

    こちらにAPIプロファイルの一覧があります。このプロファイルの中で各リソースの API バージョンが指定されています。

    下記のサンプルテンプレートを例にすると、API バージョンは "2016-01-01" となります。テンプレートの中で apiVersion を指定すると apiProfile の値は無視されます。

    {
        "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
        "contentVersion": "1.0.0.0",
        "apiProfile": "2018–03-01-hybrid",
        "parameters": {
            "location": {
                "type": "string",
                "metadata": {
                    "description": "Location the resources will be deployed to."
                },
                "defaultValue": "[resourceGroup().location]"
            }
        },
        "variables": {},
        "resources": [
            {
                "type": "Microsoft.Storage/storageAccounts",
                "apiVersion": "2016-01-01",
                "name": "mystorageaccount",
                "location": "[parameters('location')]",
                "properties": {
                    "accountType": "Standard_LRS"
                }
            },
            {
                "type": "Microsoft.Compute/availabilitySets",
                "name": "myavailabilityset",
                "location": "[parameters('location')]",
                "properties": {
                    "platformFaultDomainCount": 2,
                    "platformUpdateDomainCount": 2
                }
            }
        ],
        "outputs": {}
    }

    逆に、テンプレートファイルの中で API バージョンを管理せずに apiProfile で API バージョンを管理するといった運用も考えられます。

    複数のリージョンでグローバルなサービスを展開しているような企業では、API バージョンを統一するためにこのプロファイルを利用しても良いかもしれません。

    ただし、この値の指定は必須ではありません。

    parameters

    パラメータは必須の項目ではないですが、テンプレートを運用する上で必ず使用します。

    例えば、VirtualMachine を作成するときに、ユーザー名やパスワード、接続元のIPなどの値は、まとめて別の場所で管理したいものです。そういった時に、このパラメータだけをファイルで外出しすることができます。

    New-AzResourceGroupDeployment -Name ExampleDeployment -ResourceGroupName ExampleResourceGroup ` -TemplateFile c:\MyTemplates\azuredeploy.json ` -TemplateParameterFile c:\MyTemplates\storage.parameters.json

    このようにデプロイコマンド実行時にパラメータファイルを渡すことができます。

    variables

    この値も必須ではありませんが、運用上は必ず使用します。

    例えば、Storage Account などのグローバルサービスは一意なネーミングを要求されます。また、企業毎にリソースのネーミングルールは決められています。

    そう言った場合、Storage Account に付けるネーミングは Company-dev-id1234567 といった具合に、決められた法則に従って設定することがほとんどです。

    下記の例では、リソースグループID と 'CompanyName' を組み合わせて一意の名称を振っています。

    {
        "variables": {
          "storageName": "[concat(toLower(parameters('CompanyName')), uniqueString(resourceGroup().id))]"
        }
    }

    特定の VirtualMachine のディスク名には、Virtualmachine の名称と番号を先頭に付けるというネーミングもあると思います。そう言った時に variables で動的に定義することができます。

    functions

    ユーザー定義ファンクションのサンプルは「User-defined functions in ARM template」に掲載されています。

    とりあえず、初心者の私が手をつけるのにはまだ早そうですね。これを使うのはかなり上級テクニックだと思われます。どういう用途ができるかだけを把握しておくだけで良いと思われます。

    resources ※必須

    各リソースの定義を入力する部分です。テンプレートファイルのメインとなる部分です。この中の書き方の詳細については、それぞれのリソースを作成する時に解説していきたいと思います。

    outputs

    この機能もよく使います。テンプレートの内容が増えてくると、リソース種別毎にファイルを分割して管理するようになります。そうすると、テンプレート間で IPAddress や リソースID 等の値をやり取りする必要が出てくるのですが、そういった時にこの Output を使って値のやりとりを行います。

    または、デプロイ後にしか知ることのできない値を出力させるようにすることで、コンソールを参照したり、コマンドで確認する手間を省くこともできます。

    ただし、outputs は必須ではありません。

    データ型

    データ型の一覧

    テンプレートを書くに当たって一番押さえておかなければならないのが、このデータ型です。

    • string
    • int
    • bool
    • array
    • object

    それぞれのデータ型の文法

    記述方法は覚えておかないと、パラメータは object で指定すること、みたいに書かれていた時に、どうやって値を入れればいいか分かりません。データ型の文法は覚えておきましょう。

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "stringParameter": {
          "type": "string",
          "defaultValue": "option 1"
        },
        "intParameter": {
          "type": "int",
          "defaultValue": 1
        },
        "boolParameter": {
            "type": "bool",
            "defaultValue": true
        },
        "objectParameter": {
          "type": "object",
          "defaultValue": {
            "one": "a",
            "two": "b"
          }
        },
        "arrayParameter": {
          "type": "array",
          "defaultValue": [ 1, 2, 3 ]
        }
      },
      "resources": [],
      "outputs": {}
    }

    Comments

    インラインコメントの記述方法は「//」と「/* ... */」です。

    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2018-10-01",
      "name": "[variables('vmName')]", // to customize name, change it in variables
      "location": "[parameters('location')]", //defaults to resource group location
      "dependsOn": [ /* storage account and network interface must be deployed first */
        "[resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
        "[resourceId('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
      ],
    }

    Metadata

    メタデータオブジェクトは、テンプレート内のほとんどどこにでも追加できます。企業毎のルールに従って可読性を高めるために入れるようにしましょう。

    テンプレートの先頭に

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "metadata": {
        "comments": "This template was developed for demonstration purposes.",
        "author": "Example Name"
      },
    }

    パラメータの中に

    {
      "parameters": {
        "adminUsername": {
          "type": "string",
          "metadata": {
            "description": "User name for the Virtual Machine."
          }
        },
      }
    }

    リソースの中に

    {
      "resources": [
        {
          "type": "Microsoft.Storage/storageAccounts",
          "apiVersion": "2018-07-01",
          "name": "[concat('storage', uniqueString(resourceGroup().id))]",
          "comments": "Storage account used to store VM disks",
          "location": "[parameters('location')]",
          "metadata": {
            "comments": "These tags are needed for policy compliance."
          },
          "tags": {
            "Dept": "[parameters('deptName')]",
            "Environment": "[parameters('environment')]"
          },
          "sku": {
            "name": "Standard_LRS"
          },
          "kind": "Storage",
          "properties": {}
        }
      ]
    }

    今回は以上です。これから、実際に色々なリソースを Template を使いながら作成していきたいと思います。

  • AzureResourceManager