Funciones de plantilla de Resource Manager en ámbitos de implementación

Con las plantillas de Azure Resource Manager, puede realizar implementaciones en grupos de recursos, suscripciones, grupos de administración o inquilinos. Por lo general, las funciones de plantilla de Resource Manager funcionan igual en todos los ámbitos. En este artículo se describen las diferencias que existen en algunas funciones según el ámbito.

Funciones admitidas

Al realizar la implementación en distintos ámbitos, hay algunos aspectos importantes que se deben tener en cuenta:

  • La función resourceGroup() se admite con implementaciones de grupos de recursos.

  • La función subscription() se admite con implementaciones de grupos de recursos y suscripciones.

  • Las funciones reference() y list() se admiten con todos los ámbitos.

  • Use resourceId() para obtener el identificador de un recurso implementado en el grupo de recursos.

    "subnet": {
      "id": "[resourceId(parameters('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnet1Name'))]"
    }
    
  • Use la función subscriptionResourceId() para obtener el identificador de un recurso implementado en la suscripción.

    Por ejemplo, para obtener el identificador de recurso de una definición de directiva que se implementa en una suscripción, use:

    "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]"
    
  • Use la función extensionResourceId() con los recursos que se implementan como extensiones del grupo de administración. Las definiciones de directivas personalizadas que se implementan en un grupo de administración son extensiones del grupo de administración.

    Para obtener el identificador de recurso de una definición de directiva personalizada en el nivel de grupo de administración, use:

    "policyDefinitionId": "[extensionResourceId(variables('mgScope'), 'Microsoft.Authorization/policyDefinitions', parameters('policyDefinitionID'))]"
    
  • Use la función tenantResourceId() para obtener el identificador de un recurso implementado en el inquilino. Las definiciones de directivas integradas son recursos del nivel de inquilino. Al asignar una directiva integrada en el nivel de grupo de administración, use la función tenantResourceId.

    Para obtener el identificador de recurso de una definición de directiva integrada, utilice:

    "policyDefinitionId": "[tenantResourceId('Microsoft.Authorization/policyDefinitions', parameters('policyDefinitionID'))]"
    

Resolución de funciones en ámbitos

Al implementar en más de un ámbito, las funciones resourceGroup() y subscription() se resuelven de manera diferente en función de cómo se especifique la plantilla. Cuando se vincula a una plantilla externa, las funciones siempre se resuelven en el ámbito de esa plantilla. Al anidar una plantilla dentro de una plantilla primaria, use la propiedad expressionEvaluationOptions para especificar si las funciones se resuelven en el grupo de recursos y en la suscripción de la plantilla primaria o en la plantilla anidada. Establezca la propiedad en inner para resolver el ámbito de la plantilla anidada. Establezca la propiedad en outer para resolver el ámbito de la plantilla primaria.

En la tabla siguiente se muestra si las funciones se resuelven en el grupo de recursos y la suscripción primarios o insertados.

Tipo de plantilla Ámbito Solución
anidada exterior (valor predeterminado) Grupo de recursos primario
anidada interna Grupo de subrecursos
Vinculado N/D Grupo de subrecursos

En la plantilla de ejemplo se muestra:

  • plantilla anidada con ámbito predeterminado (exterior)
  • plantilla anidada con ámbito interno
  • plantilla vinculada
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2022-09-01",
      "name": "defaultScopeTemplate",
      "resourceGroup": "inlineGroup",
      "properties": {
        "mode": "Incremental",
        "parameters": {},
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [],
          "outputs": {
            "resourceGroupOutput": {
              "type": "string",
              "value": "[resourceGroup().name]"
            }
          }
        }
      }
    },
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2022-09-01",
      "name": "innerScopeTemplate",
      "resourceGroup": "inlineGroup",
      "properties": {
        "expressionEvaluationOptions": {
          "scope": "inner"
        },
        "mode": "Incremental",
        "parameters": {},
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [],
          "outputs": {
            "resourceGroupOutput": {
              "type": "string",
              "value": "[resourceGroup().name]"
            }
          }
        }
      }
    },
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2022-09-01",
      "name": "linkedTemplate",
      "resourceGroup": "linkedGroup",
      "properties": {
        "mode": "Incremental",
        "parameters": {},
        "templateLink": {
          "contentVersion": "1.0.0.0",
          "uri": "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/resourcegroupname.json"
        }
      }
    }
  ],
  "outputs": {
    "parentRG": {
      "type": "string",
      "value": "[format('Parent resource group is {0}', resourceGroup().name)]"
    },
    "defaultScopeRG": {
      "type": "string",
      "value": "[format('Default scope resource group is {0}', reference('defaultScopeTemplate').outputs.resourceGroupOutput.value)]"
    },
    "innerScopeRG": {
      "type": "string",
      "value": "[format('Inner scope resource group is {0}', reference('innerScopeTemplate').outputs.resourceGroupOutput.value)]"
    },
    "linkedRG": {
      "type": "string",
      "value": "[format('Linked resource group is {0}', reference('linkedTemplate').outputs.resourceGroupOutput.value)]"
    }
  }
}

Para probar la plantilla anterior y ver los resultados, use PowerShell o la CLI de Azure.

New-AzResourceGroup -Name parentGroup -Location southcentralus
New-AzResourceGroup -Name inlineGroup -Location southcentralus
New-AzResourceGroup -Name linkedGroup -Location southcentralus

New-AzResourceGroupDeployment `
  -ResourceGroupName parentGroup `
  -TemplateUri https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/crossresourcegroupproperties.json

El resultado del ejemplo anterior es:

 Name             Type                       Value
 ===============  =========================  ==========
 parentRG         String                     Parent resource group is parentGroup
 defaultScopeRG   String                     Default scope resource group is parentGroup
 innerScopeRG     String                     Inner scope resource group is inlineGroup
 linkedRG         String                     Linked resource group is linkedgroup

Pasos siguientes