Implantações de grupo de gerenciamento com modelos do ARM

À medida que a sua organização amadurece, você pode implantar um modelo do ARM (Azure Resource Manager) para criar recursos em nível de grupo de gerenciamento. Por exemplo, talvez você precise definir e atribuir políticas ou o RBAC do Azure (controle de acesso baseado em função do Azure) para um grupo de gerenciamento. Com os modelos em nível de grupo de gerenciamento, você pode atribuir funções nesse mesmo nível e aplicar políticas declarativamente.

Dica

Recomendamos o Bicep porque ele oferece as mesmas funcionalidades que os modelos do ARM e a sintaxe é mais fácil de usar. Para saber mais, confira implantações do grupo de gerenciamento.

Recursos compatíveis

Nem todos os tipos de recursos podem ser implantados em nível de grupo de gerenciamento. Esta seção lista os tipos de recursos compatíveis.

Para o Azure Blueprints, use:

Para o Azure Policy, use:

Para controle de acesso, use:

Para modelos aninhados que são implantados em assinaturas ou grupos de recursos, use:

Para gerenciar recursos, use:

Os grupos de gerenciamento são recursos em nível de locatário. No entanto, é possível criá-los em uma implantação de grupo de gerenciamento definindo o escopo do novo grupo de gerenciamento para o locatário. Confira Grupo de gerenciamento.

Esquema

O esquema que você usa para implantações de grupo de gerenciamento é diferente do usado para implantações de grupo de recursos.

Para modelos, use:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#",
  ...
}

O esquema para um arquivo de parâmetro é o mesmo para todos os escopos de implantação. Para arquivos de parâmetros, use:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  ...
}

Comandos de implantação

Para implantar em um grupo de gerenciamento, use os comandos de implantação de grupo de gerenciamento.

Para a CLI do Azure, use az deployment mg create:

az deployment mg create \
  --name demoMGDeployment \
  --location WestUS \
  --management-group-id myMG \
  --template-uri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/management-level-deployment/azuredeploy.json"

Para obter informações mais detalhadas sobre os comandos de implantação e as opções para implantar modelos do ARM, confira:

Nome e local da implantação

Para implantações em nível de grupo de gerenciamento, você deve informar um local para a implantação. O local da implantação é separado do local dos recursos que você implanta. O local de implantação especifica onde armazenar os dados de implantação. As implantações de assinatura e locatário também exigem um local. Para implantações de grupo de recursos, o local do grupo de recursos é usado para armazenar os dados da implantação.

Você pode fornecer um nome da implantação ou usar o nome da implantação padrão. O nome padrão é o nome do arquivo de modelo. Por exemplo, implantar um modelo chamado azuredeploy.json cria um nome de implantação padrão de azuredeploy.

O local não pode ser alterado para cada nome de implantação. Você não pode criar uma implantação em um local quando há uma implantação existente com o mesmo nome em um local diferente. Por exemplo, se você criar uma implantação de grupo de gerenciamento com o nome deployment1 em centralus, não poderá criar outra implantação mais tarde com o nome deployment1 no local westus. Se você receber o código de erro InvalidDeploymentLocation, use um nome diferente ou o mesmo local que a implantação anterior para esse nome.

Escopos de implantação

Ao implantar em um grupo de gerenciamento, você pode implantar recursos:

  • no grupo de gerenciamento de destino com base na operação
  • em outro grupo de gerenciamento do locatário
  • nas assinaturas do grupo de gerenciamento
  • nos grupos de recursos do grupo de gerenciamento
  • no locatário do grupo de recursos

É possível definir o escopo de um recurso de extensão para um destino diferente do destino de implantação.

O usuário que implanta o modelo deve ter acesso ao escopo especificado.

Esta seção mostra como especificar escopos diferentes. Você pode combinar esses escopos diferentes em um só modelo.

Escopo do grupo de gerenciamento de destino

Os recursos definidos na seção de recursos do modelo são aplicados ao grupo de gerenciamento com base no comando de implantação.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    management-group-resources-default
  ],
  "outputs": {}
}

Escopo de outro grupo de gerenciamento

Para visar a outro grupo de gerenciamento, adicione uma implantação aninhada e especifique a propriedade scope. Defina a propriedade scope como um valor no formato Microsoft.Management/managementGroups/<mg-name>.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "mgName": {
      "type": "string"
    }
  },
  "variables": {
    "mgId": "[format('Microsoft.Management/managementGroups/{0}', parameters('mgName'))]"
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2022-09-01",
      "name": "nestedDeployment",
      "scope": "[variables('mgId')]",
      "location": "eastus",
      "properties": {
        "mode": "Incremental",
        "template": {
          management-group-resources-non-default
        }
      }
    }
  ],
  "outputs": {}
}

Escopo de assinatura

Também é possível visar a assinaturas de um grupo de gerenciamento. O usuário que implanta o modelo deve ter acesso ao escopo especificado.

Para visar a uma assinatura do grupo de gerenciamento, use uma implantação aninhada e a propriedade subscriptionId.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2022-09-01",
      "name": "nestedSub",
      "location": "westus2",
      "subscriptionId": "00000000-0000-0000-0000-000000000000",
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              subscription-resources
            }
          ]
        }
      }
    }
  ]
}

Escopo de grupo de recursos

Você também pode visar a grupos de recursos do grupo de gerenciamento. O usuário que implanta o modelo deve ter acesso ao escopo especificado.

Para visar a um grupo de recursos do grupo de gerenciamento, use uma implantação aninhada. Definir as propriedades subscriptionId e resourceGroup. Não defina um local para a implantação aninhada porque ela é implantada no local do grupo de recursos.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2022-09-01",
      "name": "nestedRGDeploy",
      "subscriptionId": "00000000-0000-0000-0000-000000000000",
      "resourceGroup": "demoResourceGroup",
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              resource-group-resources
            }
          ]
        }
      }
    }
  ]
}

Para usar uma implantação de grupo de gerenciamento a fim de criar um grupo de recursos em uma assinatura e implantar uma conta de armazenamento para esse grupo de recursos, confira Implantar na assinatura e no grupo de recursos.

Escopo de locatário

Para criar recursos no locatário, defina scope como /. O usuário que está implantando o modelo deve ter o acesso necessário para implantar no locatário.

Para usar uma implantação aninhada, defina scope e location.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2022-09-01",
      "name": "nestedDeployment",
      "location": "centralus",
      "scope": "/",
      "properties": {
        "mode": "Incremental",
        "template": {
          tenant-resources
        }
      }
    }
  ],
  "outputs": {}
}

Ou é possível definir o escopo como / para alguns tipos de recursos, como grupos de gerenciamento. A próxima seção descreve a criação de um novo grupo de gerenciamento.

Grupo de gerenciamento

Para criar um grupo de gerenciamento em uma implantação de grupo de gerenciamento, você deve definir o escopo desse grupo como /.

O exemplo a seguir cria um novo grupo de gerenciamento no grupo de gerenciamento raiz.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "mgName": {
      "type": "string",
      "defaultValue": "[concat('mg-', uniqueString(newGuid()))]"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Management/managementGroups",
      "apiVersion": "2021-04-01",
      "name": "[parameters('mgName')]",
      "scope": "/",
      "location": "eastus",
      "properties": {}
    }
  ],
  "outputs": {
    "output": {
      "type": "string",
      "value": "[parameters('mgName')]"
    }
  }
}

O próximo exemplo cria um novo grupo de gerenciamento no grupo de gerenciamento especificado como pai. Observe que o escopo está definido como /.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "mgName": {
      "type": "string",
      "defaultValue": "[concat('mg-', uniqueString(newGuid()))]"
    },
    "parentMG": {
      "type": "string"
    }
  },
  "resources": [
    {
      "name": "[parameters('mgName')]",
      "type": "Microsoft.Management/managementGroups",
      "apiVersion": "2021-04-01",
      "scope": "/",
      "location": "eastus",
      "properties": {
        "details": {
          "parent": {
            "id": "[tenantResourceId('Microsoft.Management/managementGroups', parameters('parentMG'))]"
          }
        }
      }
    }
  ],
  "outputs": {
    "output": {
      "type": "string",
      "value": "[parameters('mgName')]"
    }
  }
}

Assinaturas

Para usar um modelo do ARM para criar uma assinatura do Azure em um grupo de gerenciamento, confira:

Para implantar um modelo que move uma assinatura existente do Azure para um novo grupo de gerenciamento, confira Mover assinaturas no modelo do ARM

Azure Policy

As definições de políticas personalizadas que são implantadas no grupo de gerenciamento são extensões do grupo de gerenciamento. Para obter a ID de uma definição de política personalizada, use a função extensionResourceId(). As definições de políticas internas são recursos em nível de locatário. Para obter a ID de uma definição de política interna, use a função tenantResourceId().

O exemplo a seguir mostra como definir uma política em nível de grupo de gerenciamento e atribuí-la.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "targetMG": {
      "type": "string",
      "metadata": {
        "description": "Target Management Group"
      }
    },
    "allowedLocations": {
      "type": "array",
      "defaultValue": [
        "australiaeast",
        "australiasoutheast",
        "australiacentral"
      ],
      "metadata": {
        "description": "An array of the allowed locations, all other locations will be denied by the created policy."
      }
    }
  },
  "variables": {
    "mgScope": "[tenantResourceId('Microsoft.Management/managementGroups', parameters('targetMG'))]",
    "policyDefinition": "LocationRestriction"
  },
  "resources": [
    {
      "type": "Microsoft.Authorization/policyDefinitions",
      "name": "[variables('policyDefinition')]",
      "apiVersion": "2020-09-01",
      "properties": {
        "policyType": "Custom",
        "mode": "All",
        "parameters": {
        },
        "policyRule": {
          "if": {
            "not": {
              "field": "location",
              "in": "[parameters('allowedLocations')]"
            }
          },
          "then": {
            "effect": "deny"
          }
        }
      }
    },
    {
      "type": "Microsoft.Authorization/policyAssignments",
      "name": "location-lock",
      "apiVersion": "2020-09-01",
      "dependsOn": [
        "[variables('policyDefinition')]"
      ],
      "properties": {
        "scope": "[variables('mgScope')]",
        "policyDefinitionId": "[extensionResourceId(variables('mgScope'), 'Microsoft.Authorization/policyDefinitions', variables('policyDefinition'))]"
      }
    }
  ]
}

Implantar na assinatura e no grupo de recursos

Em uma implantação em nível de grupo de gerenciamento, você pode visar a uma assinatura do grupo de gerenciamento. O exemplo a seguir cria um grupo de recursos em uma assinatura e implanta uma conta de armazenamento para esse grupo de recursos.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "nestedsubId": {
      "type": "string"
    },
    "nestedRG": {
      "type": "string"
    },
    "storageAccountName": {
      "type": "string"
    },
    "nestedLocation": {
      "type": "string"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "nestedSub",
      "location": "[parameters('nestedLocation')]",
      "subscriptionId": "[parameters('nestedSubId')]",
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "parameters": {
          },
          "variables": {
          },
          "resources": [
            {
              "type": "Microsoft.Resources/resourceGroups",
              "apiVersion": "2021-04-01",
              "name": "[parameters('nestedRG')]",
              "location": "[parameters('nestedLocation')]"
            }
          ]
        }
      }
    },
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "nestedRG",
      "subscriptionId": "[parameters('nestedSubId')]",
      "resourceGroup": "[parameters('nestedRG')]",
      "dependsOn": [
        "nestedSub"
      ],
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              "type": "Microsoft.Storage/storageAccounts",
              "apiVersion": "2021-04-01",
              "name": "[parameters('storageAccountName')]",
              "location": "[parameters('nestedLocation')]",
              "kind": "StorageV2",
              "sku": {
                "name": "Standard_LRS"
              }
            }
          ]
        }
      }
    }
  ]
}

Próximas etapas