Sintaxe e expressões em modelos ARM

A sintaxe básica do modelo do Azure Resource Manager (modelo ARM) é JavaScript Object Notation (JSON). No entanto, você pode usar expressões para estender os valores JSON disponíveis no modelo. As expressões começam e terminam com parênteses retos: [ e ], respetivamente. O valor da expressão é avaliado quando o modelo é implementado. Uma expressão pode devolver: uma cadeia de carateres, um número inteiro, um valor booleano, uma matriz ou um objeto.

Uma expressão de modelo não pode exceder 24.576 caracteres.

Utilizar funções

O Azure Resource Manager fornece funções que você pode usar em um modelo. O exemplo a seguir 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 Gerenciador de Recursos fornece para uso em um modelo. Neste 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 retornado por essa função.

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

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

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

A maioria das funções funciona da mesma forma, quer sejam 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 usado em implantações para um grupo de recursos.
  • resourceId - pode ser usado em qualquer escopo, mas os parâmetros válidos mudam dependendo do escopo.
  • Assinatura - só pode ser usada em implantações para um grupo de recursos ou assinatura.

Carateres 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]"

Resolve para [test value].

No entanto, se a string literal não terminar com um colchete, não escape do primeiro colchete. Por exemplo, a variável:

"demoVar2": "[test] value"

Resolve para [test] value.

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

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

Para escapar de aspas simples em uma saída de expressão ARM, duplique as aspas simples. A saída do modelo a seguir resulta em valor {"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''')]"
    }
  }
}

Na definição de recurso, valores de escape duplo dentro de uma expressão. O scriptOutput modelo a partir do seguinte é 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 languageVersion 2.0, o escape duplo é mais necessário. O exemplo anterior pode ser escrito como o JSON a seguir 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 passar 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 retornará [test value].

No entanto, se você passar um valor de parâmetro através da linha de comando, os caracteres serão interpretados literalmente. Implantando o modelo anterior com:

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

Devoluções [[test value]. Em alternativa, utilize:

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

A mesma formatação se aplica ao passar 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 retorna [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, pode utilizar null ou [json('null')]. A função json retorna um objeto vazio quando você fornece null como parâmetro. Em ambos os casos, os modelos do Resource Manager tratam como se a propriedade não estivesse presente.

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

Para remover totalmente um elemento, você pode usar a função filter(). 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óximos passos