Sintaxe e expressões nos modelos do ARM

A sintaxe básica do modelo do ARM (Azure Resource Manager) é JSON (JavaScript Object Notation). No entanto, você pode usar expressões para estender os valores JSON disponíveis no modelo. As expressões começam e terminam com colchetes: [ e ], respectivamente. O valor da expressão é avaliado quando o modelo é implantado. Uma expressão pode retornar uma cadeia de caracteres, um inteiro, um booliano, uma matriz ou um objeto.

A expressão de um modelo não pode exceder 24.576 caracteres.

Usar funções

O Azure Resource Manager oferece funções que você pode usar em um modelo. O seguinte exemplo mostra uma expressão que usa uma função no valor padrão de um parâmetro:

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

Dentro da expressão, a sintaxe resourceGroup() chama uma das funções que o Resource Manager oferece para uso em um modelo. Nesse caso, é a função resourceGroup. Assim como no JavaScript, as chamadas de função são formatadas como functionName(arg1,arg2,arg3). A sintaxe .location recupera uma propriedade do objeto exibido por essa função.

As funções do modelo e seus parâmetros não diferenciam maiúsculas de minúsculas. Por exemplo, o Resource Manager resolve variables('var1') e VARIABLES('VAR1') da mesma forma. Quando avaliada, a função preservará as maiúsculas e minúsculas, a menos que as mude expressamente (como toUpper ou toLower). Certos tipos de recursos podem ter requisitos de maiúsculas e minúsculas que não dependem da forma como as funções são avaliadas.

Para transmitir um valor de cadeia de caracteres como um parâmetro para uma função, use aspas simples.

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

A maioria das funções funciona da mesma forma, independentemente de serem implantadas em um grupo de recursos, assinatura, grupo de gerenciamento ou locatário. As seguintes funções têm restrições com base no escopo:

  • resourceGroup – só pode ser usada em implantações em um grupo de recursos.
  • resourceId – pode ser usada em qualquer escopo, mas os parâmetros válidos mudam com base no escopo.
  • subscription – só pode ser usada em implantações em um grupo de recursos ou uma assinatura.

Caracteres de escape

Para que uma cadeia de caracteres literal comece com um colchete esquerdo [ e termine com um colchete direito ], mas não seja interpretada como uma expressão, adicione um colchete extra para iniciar a cadeia de caracteres com [[. Por exemplo, a variável:

"demoVar1": "[[test value]"

É resolvida como [test value].

No entanto, se a cadeia de caracteres literal não terminar com um colchete, não remova o primeiro colchete. Por exemplo, a variável:

"demoVar2": "[test] value"

É resolvida como [test] value.

Para remover as aspas duplas de uma expressão, como para adicionar um objeto JSON no modelo, use a barra invertida.

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

Para aplicar escape nas aspas simples em uma saída de expressão do ARM, use duas aspas simples. A saída do modelo a seguir resulta em um valor JSON {"abc":"'quoted'"}.

{
  "$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''')]"
    }
  }
}

Na definição de recursos, faça duplo escape de valores em uma expressão. O scriptOutput do modelo a seguir é 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]"
    }
  }
}

Com a languageVersion 2.0, o escape duplo não é mais necessário. O exemplo anterior pode ser escrito como o seguinte JSON para obter o mesmo resultado, 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]"
    }
  }
}

Ao transmitir valores de parâmetro, o uso de caracteres de escape depende de onde o valor do parâmetro é especificado. Se você definir um valor padrão no modelo, precisará do colchete esquerdo extra.

{
  "$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')]"
    }
  }
}

Se você usar o valor padrão, o modelo exibirá [test value].

No entanto, se você transmitir um valor de parâmetro por meio da linha de comando, os caracteres serão interpretados literalmente. Implantar o modelo anterior com:

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

Retorna [[test value]. Em vez disso, use:

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

A mesma formatação se aplica ao transmitir valores de um arquivo de parâmetro. Os caracteres são interpretados literalmente. Quando usado com o modelo anterior, o seguinte arquivo de parâmetro exibe [test value]:

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

Valores nulos

Para definir uma propriedade como nula, é possível usar null ou [json('null')]. A função json exibe um objeto vazio quando você informa null como o parâmetro. Em ambos os casos, os modelos do Resource Manager agem como se a propriedade não estivesse presente.

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

Para remover totalmente um elemento, você pode usar a função filtro(). Por exemplo:

{
  "$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')))))]"
    }
  }
}

Próximas etapas