Sintaxis y expresiones en las plantillas de ARM

La sintaxis básica de la plantilla de Azure Resource Manager (plantilla de ARM) es la notación de objetos JavaScript (JSON). Sin embargo, puede utilizar expresiones para ampliar los valores JSON disponibles en la plantilla. Las expresiones empiezan y terminan con corchetes: [ y ], respectivamente. El valor de la expresión se evalúa cuando se implementa la plantilla. Una expresión puede devolver una cadena, un entero, un booleano, una matriz o un objeto.

Las expresiones de plantilla no pueden superar los 24 576 caracteres.

Uso de las funciones

Azure Resource Manager cuenta con funciones que se pueden usar en una plantilla. En el ejemplo siguiente, se muestra una expresión que utiliza una función en el valor predeterminado de un parámetro:

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

En de la expresión, la sintaxis resourceGroup() llama a una de las funciones que Resource Manager proporciona para utilizarla dentro de una plantilla. En este caso, se trata de la función resourceGroup. Al igual que en JavaScript, las llamadas de función tienen el formato functionName(arg1,arg2,arg3). La sintaxis .location recupera una propiedad del objeto devuelto por esta función.

Las funciones de plantilla y sus parámetros no distinguen mayúsculas de minúsculas. Por ejemplo, Resource Manager resuelve variables('var1') y VARIABLES('VAR1') de la misma manera. Cuando se evalúa, a menos que la función modifique expresamente las mayúsculas y minúsculas (como toUpper o toLower), la función conserva lo que existe. Es posible que determinados tipos de recursos tengan requisitos de mayúsculas independientemente de cómo se evalúen las funciones.

Para pasar un valor de cadena como parámetro a una función, use comillas simples.

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

La mayoría de las funciones funcionan igual ya sea que se implementen en un grupo de recursos, una suscripción, un grupo de administración o un inquilino. Las siguientes funciones tienen restricciones en función del ámbito:

  • resourceGroup: solo puede utilizarse cuando la implementación se realiza en un grupo de recursos.
  • resourceId: puede utilizarse con cualquier ámbito, pero los valores correctos cambiarán en función de este.
  • subscription: solo puede utilizarse cuando la implementación se realiza en un grupo de recursos o una suscripción.

Carácter de escape

Para que una cadena literal empiece con un corchete izquierdo [ y termine con un corchete derecho ], pero no se interprete como una expresión, agregue otro corchete para que la cadena comience con [[. Por ejemplo, la variable:

"demoVar1": "[[test value]"

Se resuelve como [test value].

Sin embargo, si la cadena literal no termina con un corchete de cierre, no utilice un carácter de escape en el primer corchete. Por ejemplo, la variable:

"demoVar2": "[test] value"

Se resuelve como [test] value.

Para utilizar un carácter de escape en las comillas dobles en una expresión, como, por ejemplo, al agregar un objeto JSON a la plantilla, use la barra diagonal inversa.

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

Para escapar las comillas simples en una salida de expresión ARM, doble las comillas simples. El resultado de la siguiente plantilla da como resultado un 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''')]"
    }
  }
}

En la definición de recursos, los valores de escape doble dentro de una expresión. scriptOutput del objeto de la plantilla siguiente es 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]"
    }
  }
}

Con languageVersion 2.0, el escape doble es más largo necesario. El ejemplo anterior se puede escribir como el siguiente JSON para obtener el mismo 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]"
    }
  }
}

Al pasar valores de parámetro, el uso de caracteres de escape depende de si se especifica el valor de parámetro. Si especifica un valor predeterminado en la plantilla, necesita un corchete de apertura adicional.

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

Si usa el valor predeterminado, la plantilla devuelve [test value].

Sin embargo, si se pasa un valor de parámetro mediante la línea de comandos, los caracteres se interpretan literalmente. Al implementar la plantilla anterior con:

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

Devuelve [[test value]. En su lugar, use:

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

Se aplica el mismo formato al pasar valores de un archivo de parámetros. Los caracteres se interpretan literalmente. Cuando se usa con la plantilla anterior, el siguiente archivo de parámetros devuelve [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 NULL

Para establecer una propiedad en NULL, puede usar null o [json('null')]. La función json devuelve un objeto vacío cuando se proporciona null como parámetro. En ambos casos, las plantillas de Resource Manager lo tratan como si la propiedad no estuviera presente.

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

Para quitar totalmente un elemento, puede usar la función filter(). Por ejemplo:

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

Pasos siguientes