Sintaxe e expressões em modelos do ARM

A sintaxe básica do modelo de Resource Manager do Azure (modelo arm) é JavaScript Object Notation (JSON). No entanto, pode utilizar expressões para expandir 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 carateres.

Utilizar funções

O Azure Resource Manager fornece funções que pode utilizar num modelo. O exemplo seguinte mostra uma expressão que utiliza uma função no valor predefinido de um parâmetro:

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

Na expressão, a sintaxe resourceGroup() chama uma das funções que Resource Manager fornece para utilização num modelo. Neste caso, é a função resourceGroup . Tal como no JavaScript, as chamadas de função são formatadas como functionName(arg1,arg2,arg3). A sintaxe .location obtém uma propriedade do objeto devolvido por essa função.

As funções de modelo e os respetivos parâmetros não são sensíveis a maiúsculas e minúsculas. Por exemplo, Resource Manager resolve variables('var1') e VARIABLES('VAR1') da mesma forma. Quando avaliada, a menos que a função modifigue expressamente o caso (como toUpper ou toLower), a função preserva o caso. Determinados tipos de recursos podem ter requisitos de maiúsculas e minúsculas separados da forma como as funções são avaliadas.

Para transmitir um valor de cadeia como um parâmetro para uma função, utilize aspas individuais.

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

A maioria das funções funciona da mesma forma, quer sejam implementadas num grupo de recursos, subscrição, grupo de gestão ou inquilino. As seguintes funções têm restrições com base no âmbito:

  • resourceGroup - só pode ser utilizado em implementações num grupo de recursos.
  • resourceId - pode ser utilizado em qualquer âmbito, mas os parâmetros válidos mudam consoante o âmbito.
  • subscrição – só pode ser utilizada em implementações para um grupo de recursos ou subscrição.

Carateres de escape

Para que uma cadeia literal comece com um parêntese [ esquerdo e termine com um parêntese ]direito , mas não a interprete como uma expressão, adicione um parêntese extra para iniciar a cadeia com [[. Por exemplo, a variável:

"demoVar1": "[[test value]"

Resolve para [test value].

No entanto, se a cadeia literal não terminar com um parêntese, não escape o primeiro parêntese. Por exemplo, a variável:

"demoVar2": "[test] value"

Resolve para [test] value.

Para escapar a aspas duplas numa expressão, como adicionar um objeto JSON no modelo, utilize a barra invertida.

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

Para escapar a aspas individuais numa saída de expressão do ARM, duplique as plicas. O resultado do seguinte modelo resulta no 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 recursos, faça duplo escape de valores numa expressão. O scriptOutput do seguinte modelo é 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, a escape dupla é mais necessária. 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âmetros, a utilização de carateres de escape depende de onde o valor do parâmetro é especificado. Se definir um valor predefinido no modelo, precisa do parêntese 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 utilizar o valor predefinido, o modelo devolve [test value].

No entanto, se transmitir um valor de parâmetro através da linha de comandos, os carateres são interpretados literalmente. Implementar o modelo anterior com:

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

Devolve [[test value]. Em alternativa, utilize:

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

A mesma formatação aplica-se ao transmitir valores a partir de um ficheiro de parâmetros. Os personagens são interpretados literalmente. Quando utilizado com o modelo anterior, o seguinte ficheiro de parâmetros devolve [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 devolve um objeto vazio quando fornece null como parâmetro. Em ambos os casos, Resource Manager modelos o tratam como se a propriedade não estivesse presente.

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

Para remover totalmente um elemento, pode utilizar 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')))))]"
    }
  }
}

Passos seguintes