Синтаксис и выражения в шаблонах ARM

Базовый синтаксис шаблона Azure Resource Manager (шаблон ARM) является нотацией объектов JavaScript (JSON). Тем не менее выражения можно использовать для расширения значений JSON, доступных в шаблоне. Выражения начинаются и заканчиваются квадратными скобками: [ и ] соответственно. Значение выражения вычисляется при развертывании шаблона. Выражение может возвращать строку, целое число, логическое значение, массив или объект.

Выражение шаблона не может превышать 24 576 знаков.

Использование функций

Azure Resource Manager предоставляет функции, которые можно использовать в шаблоне. В следующем примере показано выражение, использующее функцию в значении по умолчанию для параметра:

"parameters": {
  "location": {
    "type": "string",
    "defaultValue": "[resourceGroup().location]"
  }
},

Внутри выражения синтаксис resourceGroup() вызывает одну из функций, которые Resource Manager предоставляет для использования внутри шаблона. В этом случае это функция resourceGroup. Как и в языке JavaScript, вызовы функций форматируются так: functionName(arg1,arg2,arg3). Синтаксис .location получает одно свойство из объекта, возвращаемого данной функцией.

Функции шаблонов и их параметры зависят от регистра. Например, Resource Manager разрешает переменные variables('var1') и VARIABLES('VAR1') как одну и ту же переменную. При вычислении функция сохраняет регистр, если его изменение не является ее явным предназначением (как у функций toUpper и toLower). Для некоторых типов ресурсов требования к регистру могут не зависеть от того, как происходит вычисление функций.

Чтобы передать строковое значение в качестве параметра функции, используйте одинарные кавычки.

"name": "[concat('storage', uniqueString(resourceGroup().id))]"

Большинство функций работают одинаково независимо от того, развернуты ли они в группе ресурсов, подписке, группе управления или клиенте. Следующие функции предусматривают ограничения в зависимости от области действия:

  • resourceGroup — может использоваться только при развертываниях в группу ресурсов.
  • resourceId — можно использовать в любой области, но допустимые параметры изменяются в зависимости от области.
  • subscription — может использоваться только при развертываниях в группу ресурсов или подписку.

Escape-символы

Чтобы строковый литерал начинался с левой скобки [ и заканчивался правой скобкой ], но не интерпретировался как выражение, добавьте еще одну скобку, чтобы строка начиналась со знака [[. Например, следующая переменная:

"demoVar1": "[[test value]"

Разрешается в [test value].

Однако если строковый литерал не заканчивается скобкой, не нужно экранировать первую скобку. Например, следующая переменная:

"demoVar2": "[test] value"

Разрешается в [test] value.

Для экранирования двойных кавычек в выражении, например при добавлении объекта JSON в шаблон, используйте обратную косую черту.

"tags": {
    "CostCenter": "{\"Dept\":\"Finance\",\"Environment\":\"Production\"}"
},

Чтобы экранировать одинарные кавычки в выходных данных выражения ARM, удвоите одинарные кавычки. Выходные данные следующего шаблона приводят к значению {"abc":"'quoted'"}JSON .

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "resources": [],
  "outputs": {
    "foo": {
      "type": "object",
      "value": "[createObject('abc', '''quoted''')]"
    }
  }
}

В определении ресурса — двойной экранирование значений в выражении. Из scriptOutput следующего шаблона имеет значение de'f.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "forceUpdateTag": {
      "type": "string",
      "defaultValue": "[newGuid()]"
    }
  },
  "variables": {
    "deploymentScriptSharedProperties": {
      "forceUpdateTag": "[parameters('forceUpdateTag')]",
      "azPowerShellVersion": "10.1",
      "retentionInterval": "P1D"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deploymentScripts",
      "apiVersion": "2020-10-01",
      "name": "escapingTest",
      "location": "[resourceGroup().location]",
      "kind": "AzurePowerShell",
      "properties": "[union(variables('deploymentScriptSharedProperties'), createObject('scriptContent', '$DeploymentScriptOutputs = @{}; $DeploymentScriptOutputs.escaped = \"de''''f\";'))]"
    }
  ],
  "outputs": {
    "scriptOutput": {
      "type": "string",
      "value": "[reference('escapingTest').outputs.escaped]"
    }
  }
}

При использовании languageVersion 2.0 двойной экранирование требуется дольше. Предыдущий пример можно записать в виде следующего json, чтобы получить тот же результат, de'f.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "languageVersion": "2.0",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "forceUpdateTag": {
      "type": "string",
      "defaultValue": "[newGuid()]"
    }
  },
  "variables": {
    "deploymentScriptSharedProperties": {
      "forceUpdateTag": "[parameters('forceUpdateTag')]",
      "azPowerShellVersion": "10.1",
      "retentionInterval": "P1D"
    }
  },
  "resources": {
    "escapingTest": {
      "type": "Microsoft.Resources/deploymentScripts",
      "apiVersion": "2020-10-01",
      "name": "escapingTest",
      "location": "[resourceGroup().location]",
      "kind": "AzurePowerShell",
      "properties": "[union(variables('deploymentScriptSharedProperties'), createObject('scriptContent', '$DeploymentScriptOutputs = @{}; $DeploymentScriptOutputs.escaped = \"de''f\";'))]"
    }
  },
  "outputs": {
    "scriptOutput": {
      "type": "string",
      "value": "[reference('escapingTest').outputs.escaped]"
    }
  }
}

При передаче значений параметров использование escape-символов зависит от того, где указано значение параметра. Если в шаблоне задано значение по умолчанию, тогда требуется еще одна закрывающая скобка.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "demoParam1": {
      "type": "string",
      "defaultValue": "[[test value]"
    }
  },
  "resources": [],
  "outputs": {
    "exampleOutput": {
      "type": "string",
      "value": "[parameters('demoParam1')]"
    }
  }
}

Если вы используете значение по умолчанию, шаблон возвращает значение [test value].

Однако если передать значение параметра через командную строку, символы будут интерпретироваться буквально. Развертывание предыдущего шаблона с помощью:

New-AzResourceGroupDeployment -ResourceGroupName demoGroup -TemplateFile azuredeploy.json -demoParam1 "[[test value]"

Возвращает [[test value]. Вместо него используйте следующий вариант:

New-AzResourceGroupDeployment -ResourceGroupName demoGroup -TemplateFile azuredeploy.json -demoParam1 "[test value]"

То же самое форматирование применяется при передаче значений из файла параметров. Символы интерпретируются буквально. При использовании с предыдущим шаблоном следующий файл параметров предоставляет значение [test value]:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "demoParam1": {
      "value": "[test value]"
    }
  }
}

Значения NULL

Чтобы задать для свойства значение NULL, можно использовать null или [json('null')]. Функция JSON возвращает пустой объект при предоставлении значения null в качестве параметра. В обоих случаях в шаблонах Resource Manager это свойство рассматривается так, будто бы оно отсутствует.

"stringValue": null,
"objectValue": "[json('null')]"

Чтобы полностью удалить элемент, можно использовать функцию filter(). Пример:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "deployCaboodle": {
      "type": "bool",
      "defaultValue": false
    }
  },
  "variables": {
    "op": [
      {
        "name": "ODB"
      },
      {
        "name": "ODBRPT"
      },
      {
        "name": "Caboodle"
      }
    ]
  },
  "resources": [],
  "outputs": {
    "backendAddressPools": {
      "type": "array",
      "value": "[if(parameters('deployCaboodle'), variables('op'), filter(variables('op'), lambda('on', not(equals(lambdaVariables('on').name, 'Caboodle')))))]"
    }
  }
}

Дальнейшие действия