Развертывание подписок с помощью шаблонов ARM

Чтобы упростить управление ресурсами, можно использовать шаблон Azure Resource Manager (шаблон ARM) для развертывания ресурсов на уровне подписки Azure. Например, можно развернуть политики и управление доступом на основе ролей Azure (Azure RBAC) в подписке, чтобы применять их по всей подписке. Вы также можете создавать группы ресурсов в подписке и развертывать ресурсы в группах ресурсов в подписке.

Примечание

На уровне подписки можно развернуть до 800 различных групп ресурсов.

Чтобы развернуть шаблоны на уровне подписки, используйте Azure CLI, PowerShell, REST API или портал.

Совет

Мы рекомендуем использовать Bicep, так как он предоставляет те же возможности, что и шаблоны ARM, и имеет более простой синтаксис. Дополнительные сведения см. в документации по развертываниям подписок.

Поддерживаемые ресурсы

Не все типы ресурсов можно развернуть на уровне подписки. В этом разделе перечислены поддерживаемые типы ресурсов.

Для Azure Blueprints используйте следующие типы:

Для политик Azure используйте следующие типы:

Для управления доступом используйте:

Для вложенных шаблонов, которые развертываются в группах ресурсов, используйте следующие типы:

Для создания групп ресурсов используйте следующие типы:

Для управления подпиской используйте следующие типы:

Для мониторинга используйте:

В целях безопасности используйте:

Другие поддерживаемые типы:

схема

Схема, используемая для развертываний на уровне подписки, отличается от схемы развертываний группы ресурсов.

Для шаблонов используйте:

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  ...
}

Схема для файла параметров одинакова для всех областей развертывания. Для файлов параметров используйте:

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

Команды развертывания

Для развертывания в подписке используйте команды развертывания на уровне подписки.

Для Azure CLI используйте az deployment sub create. В следующем примере выполняется развертывание шаблона для создания группы ресурсов.

az deployment sub create \
  --name demoSubDeployment \
  --location centralus \
  --template-uri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/emptyrg.json" \
  --parameters rgName=demoResourceGroup rgLocation=centralus

Более подробные сведения о командах и параметрах развертывания для развертывания шаблонов ARM приведены в следующих статьях:

Расположение и имя развертывания

Для развертываний на уровне подписки необходимо указать расположение для развертывания. Расположение развертывания отделено от расположения развертываемых ресурсов. В расположении развертывания указывается место хранения данных развертывания. Для развертываний групп управления и клиентов также требуется указать расположение. При развертывании группы ресурсов расположение группы ресурсов используется для хранения данных развертывания.

Можно указать имя развертывания или использовать имя развертывания по умолчанию. Имя по умолчанию — это имя файла шаблона. Например, развернув шаблон с именем azuredeploy.json создается имя развертывания по умолчанию azuredeploy.

Для каждого имени развертывания расположение остается неизменным. Нельзя создать развертывание в одном расположении, если в другом уже есть развертывание с таким же именем. Например, если вы создаете развертывание подписки с именем deployment1 в centralus, вы не сможете позже создать другое развертывание с именем deployment1, но уже в расположении westus. Если появится код ошибки InvalidDeploymentLocation, используйте другое имя или то же расположение, что и для предыдущего развертывания с этим именем.

Области развертывания

При развертывании в подписку можно развернуть ресурсы в:

  • целевую подписку из операции;
  • любую подписку в клиенте;
  • группы ресурсов в той же подписке или других подписках;
  • клиенте для подписки.

Ресурс расширения можно ограничить целевым объектом, который отличается от целевого объекта развертывания.

Пользователь, развертывающий шаблон, должен иметь доступ к указанной области.

В этом разделе показано, как указать различные области. Такие различные области можно объединить в один шаблон.

Область целевой подписки

Чтобы развернуть ресурсы в целевой подписке, нужно добавить их в раздел ресурсов шаблона.

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    subscription-level-resources
  ],
  "outputs": {}
}

Примеры развертывания в подписке см. в разделах Создание групп ресурсов и Назначение определения политики.

Область другой подписки

Чтобы развернуть ресурсы в подписке, которая отличается от подписки из операции, добавьте вложенное развертывание. Задайте для свойства subscriptionId идентификатор подписки, в которую требуется выполнить развертывание. Задайте свойство location для вложенного развертывания.

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "nestedDeployment",
      "subscriptionId": "00000000-0000-0000-0000-000000000000",
      "location": "westus",
      "properties": {
        "mode": "Incremental",
        "template": {
          subscription-resources
        }
      }
    }
  ],
  "outputs": {}
}

Область для группы ресурсов

Чтобы развернуть ресурсы в группе ресурсов в подписке, нужно добавить вложенное развертывание и включить свойство resourceGroup. В следующем примере вложенное развертывание предназначено для группы ресурсов с именем demoResourceGroup.

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "nestedDeployment",
      "resourceGroup": "demoResourceGroup",
      "properties": {
        "mode": "Incremental",
        "template": {
          resource-group-resources
        }
      }
    }
  ],
  "outputs": {}
}

Пример развертывания в группе ресурсов см. в разделе Создание ресурсов и группы ресурсов.

Область для клиента

Чтобы создать ресурсы в клиенте, присвойте свойству scope значение /. Пользователь, развертывающий шаблон, должен иметь необходимый доступ для развертывания в клиенте.

Чтобы использовать вложенное развертывание, задайте scope и location.

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "nestedDeployment",
      "location": "centralus",
      "scope": "/",
      "properties": {
        "mode": "Incremental",
        "template": {
          tenant-resources
        }
      }
    }
  ],
  "outputs": {}
}

Или можно задать область / для некоторых типов ресурсов, например для групп управления.

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.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')]"
    }
  }
}

Дополнительные сведения находятся в Обзоре группы управления.

Группы ресурсов

Создание группы ресурсов

Чтобы создать группу ресурсов в шаблоне ARM, определите имя и расположение ресурса Microsoft.Resources/resourceGroups для группы ресурсов.

В следующем примере создается пустая группа ресурсов.

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "rgName": {
      "type": "string"
    },
    "rgLocation": {
      "type": "string"
    }
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Resources/resourceGroups",
      "apiVersion": "2022-09-01",
      "name": "[parameters('rgName')]",
      "location": "[parameters('rgLocation')]",
      "properties": {}
    }
  ],
  "outputs": {}
}

Используйте элемент copy с группами ресурсов, чтобы создать несколько групп ресурсов.

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "rgNamePrefix": {
      "type": "string"
    },
    "rgLocation": {
      "type": "string"
    },
    "instanceCount": {
      "type": "int"
    }
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Resources/resourceGroups",
      "apiVersion": "2022-09-01",
      "location": "[parameters('rgLocation')]",
      "name": "[concat(parameters('rgNamePrefix'), copyIndex())]",
      "copy": {
        "name": "rgCopy",
        "count": "[parameters('instanceCount')]"
      },
      "properties": {}
    }
  ],
  "outputs": {}
}

Сведения об итерации ресурсов см. в статьях Итерация ресурсов в шаблонах ARM и Учебник. Создание нескольких экземпляров ресурсов с помощью шаблонов ARM.

Создание ресурсов и группы ресурсов

Чтобы создать группу ресурсов и развернуть в нее ресурсы, используйте вложенный шаблон. Вложенный шаблон определяет ресурсы для развертывания в группе ресурсов. Установите вложенный шаблон как зависимый от группы ресурсов, чтобы группа существовала до развертывания ресурсов. Можно выполнить развертывание до 800 групп ресурсов.

В следующем примере создается группа ресурсов и в нее развертывается учетная запись хранения.

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "rgName": {
      "type": "string"
    },
    "rgLocation": {
      "type": "string"
    },
    "storagePrefix": {
      "type": "string",
      "maxLength": 11
    }
  },
  "variables": {
    "storageName": "[format('{0}{1}', parameters('storagePrefix'), uniqueString(subscription().id, parameters('rgName')))]"
  },
  "resources": [
    {
      "type": "Microsoft.Resources/resourceGroups",
      "apiVersion": "2022-09-01",
      "name": "[parameters('rgName')]",
      "location": "[parameters('rgLocation')]",
      "properties": {}
    },
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2022-09-01",
      "name": "storageDeployment",
      "resourceGroup": "[parameters('rgName')]",
      "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": "2022-09-01",
              "name": "[variables('storageName')]",
              "location": "[parameters('rgLocation')]",
              "sku": {
                "name": "Standard_LRS"
              },
              "kind": "StorageV2"
            }
          ]
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.Resources/resourceGroups/', parameters('rgName'))]"
      ]
    }
  ]
}

Политика Azure

Назначение определения политики

В следующем примере подписке присваивается имеющееся определение политики. Предоставьте параметры в качестве объекта, если определение политики принимает их. Используйте пустой объект по умолчанию, если определение политики не принимает параметры.

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "policyDefinitionID": {
      "type": "string"
    },
    "policyName": {
      "type": "string"
    },
    "policyParameters": {
      "type": "object",
      "defaultValue": {}
    }
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Authorization/policyAssignments",
      "apiVersion": "2020-03-01",
      "name": "[parameters('policyName')]",
      "properties": {
        "scope": "[subscription().id]",
        "policyDefinitionId": "[parameters('policyDefinitionID')]",
        "parameters": "[parameters('policyParameters')]"
      }
    }
  ]
}

Развернуть этот шаблон с помощью Azure CLI можно так:

# Built-in policy definition that accepts parameters
definition=$(az policy definition list --query "[?displayName=='Allowed locations'].id" --output tsv)

az deployment sub create \
  --name demoDeployment \
  --location centralus \
  --template-uri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/policyassign.json" \
  --parameters policyDefinitionID=$definition policyName=setLocation policyParameters="{'listOfAllowedLocations': {'value': ['westus']} }"

Развернуть этот шаблон с помощью PowerShell можно так:

$definition = Get-AzPolicyDefinition | Where-Object { $_.Properties.DisplayName -eq 'Allowed locations' }

$locations = @("westus", "westus2")
$policyParams =@{listOfAllowedLocations = @{ value = $locations}}

New-AzSubscriptionDeployment `
  -Name policyassign `
  -Location centralus `
  -TemplateUri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/policyassign.json" `
  -policyDefinitionID $definition.PolicyDefinitionId `
  -policyName setLocation `
  -policyParameters $policyParams

Создание и назначение определения политики

Вы можете определить и назначить определение политики в том же шаблоне.

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Authorization/policyDefinitions",
      "apiVersion": "2020-03-01",
      "name": "locationpolicy",
      "properties": {
        "policyType": "Custom",
        "parameters": {},
        "policyRule": {
          "if": {
            "field": "location",
            "equals": "northeurope"
          },
          "then": {
            "effect": "deny"
          }
        }
      }
    },
    {
      "type": "Microsoft.Authorization/policyAssignments",
      "apiVersion": "2020-03-01",
      "name": "location-lock",
      "dependsOn": [
        "locationpolicy"
      ],
      "properties": {
        "scope": "[subscription().id]",
        "policyDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/policyDefinitions', 'locationpolicy')]"
      }
    }
  ]
}

Чтобы создать определение политики и назначить ее в подписке, используйте следующую команду CLI.

az deployment sub create \
  --name demoDeployment \
  --location centralus \
  --template-uri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/policydefineandassign.json"

Развернуть этот шаблон с помощью PowerShell можно так:

New-AzSubscriptionDeployment `
  -Name definePolicy `
  -Location centralus `
  -TemplateUri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/policydefineandassign.json"

Azure Blueprints

Создание определения схемы

Можно создать определение схемы из шаблона.

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "blueprintName": {
      "defaultValue": "sample-blueprint",
      "type": "String",
      "metadata": {
        "description": "The name of the blueprint definition."
      }
    }
  },
  "resources": [
    {
      "type": "Microsoft.Blueprint/blueprints",
      "apiVersion": "2018-11-01-preview",
      "name": "[parameters('blueprintName')]",
      "properties": {
        "targetScope": "subscription",
        "description": "Blueprint with a policy assignment artifact.",
        "resourceGroups": {
          "sampleRg": {
            "description": "Resource group to add the assignment to."
          }
        },
        "parameters": {
          "listOfResourceTypesNotAllowed": {
            "type": "array",
            "metadata": {
              "displayName": "Resource types to pass to the policy assignment artifact."
            },
            "defaultValue": [
              "Citrix.Cloud/accounts"
            ]
          }
        }
      }
    },
    {
      "type": "Microsoft.Blueprint/blueprints/artifacts",
      "apiVersion": "2018-11-01-preview",
      "name": "[concat(parameters('blueprintName'), '/policyArtifact')]",
      "kind": "policyAssignment",
      "dependsOn": [
        "[parameters('blueprintName')]"
      ],
      "properties": {
        "displayName": "Blocked Resource Types policy definition",
        "description": "Block certain resource types",
        "policyDefinitionId": "[tenantResourceId('Microsoft.Authorization/policyDefinitions', '6c112d4e-5bc7-47ae-a041-ea2d9dccd749')]",
        "resourceGroup": "sampleRg",
        "parameters": {
          "listOfResourceTypesNotAllowed": {
            "value": "[[parameters('listOfResourceTypesNotAllowed')]"
          }
        }
      }
    }
  ]
}

Чтобы создать определение схемы в подписке, используйте следующую команду CLI.

az deployment sub create \
  --name demoDeployment \
  --location centralus \
  --template-uri "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/subscription-deployments/blueprints-new-blueprint/azuredeploy.json"

Развернуть этот шаблон с помощью PowerShell можно так:

New-AzSubscriptionDeployment `
  -Name demoDeployment `
  -Location centralus `
  -TemplateUri "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/subscription-deployments/blueprints-new-blueprint/azuredeploy.json"

Управление доступом

Дополнительные сведения о назначении ролей Azure см. в статье Назначение ролей Azure с помощью шаблонов Azure Resource Managers.

В следующем примере создается группа ресурсов, к ней применяется блокировка, а затем участнику назначается роль.

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.5.6.12127",
      "templateHash": "16815708176905569328"
    }
  },
  "parameters": {
    "rgName": {
      "type": "string",
      "metadata": {
        "description": "Name of the resourceGroup to create"
      }
    },
    "rgLocation": {
      "type": "string",
      "metadata": {
        "description": "Location for the resourceGroup"
      }
    },
    "principalId": {
      "type": "string",
      "metadata": {
        "description": "principalId of the user that will be given contributor access to the resourceGroup"
      }
    },
    "roleDefinitionId": {
      "type": "string",
      "defaultValue": "b24988ac-6180-42a0-ab88-20f7382dd24c",
      "metadata": {
        "description": "roleDefinition to apply to the resourceGroup - default is contributor"
      }
    },
    "roleAssignmentName": {
      "type": "string",
      "defaultValue": "[guid(parameters('principalId'), parameters('roleDefinitionId'), parameters('rgName'))]",
      "metadata": {
        "description": "Unique name for the roleAssignment in the format of a guid"
      }
    }
  },
  "resources": [
    {
      "type": "Microsoft.Resources/resourceGroups",
      "apiVersion": "2019-10-01",
      "name": "[parameters('rgName')]",
      "location": "[parameters('rgLocation')]",
      "tags": {
        "Note": "subscription level deployment"
      },
      "properties": {}
    },
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2020-10-01",
      "name": "applyLock",
      "resourceGroup": "[parameters('rgName')]",
      "properties": {
        "expressionEvaluationOptions": {
          "scope": "inner"
        },
        "mode": "Incremental",
        "parameters": {
          "principalId": {
            "value": "[parameters('principalId')]"
          },
          "roleDefinitionId": {
            "value": "[parameters('roleDefinitionId')]"
          },
          "roleAssignmentName": {
            "value": "[parameters('roleAssignmentName')]"
          }
        },
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "metadata": {
            "_generator": {
              "name": "bicep",
              "version": "0.5.6.12127",
              "templateHash": "6034226420560042393"
            }
          },
          "parameters": {
            "principalId": {
              "type": "string",
              "metadata": {
                "description": "principalId of the user that will be given contributor access to the resourceGroup"
              }
            },
            "roleDefinitionId": {
              "type": "string",
              "metadata": {
                "description": "roleDefinition to apply to the resourceGroup - default is contributor"
              }
            },
            "roleAssignmentName": {
              "type": "string",
              "metadata": {
                "description": "Unique name for the roleAssignment in the format of a guid"
              }
            }
          },
          "resources": [
            {
              "type": "Microsoft.Authorization/locks",
              "apiVersion": "2016-09-01",
              "name": "DontDelete",
              "properties": {
                "level": "CanNotDelete",
                "notes": "Prevent deletion of the resourceGroup"
              }
            },
            {
              "type": "Microsoft.Authorization/roleAssignments",
              "apiVersion": "2020-04-01-preview",
              "name": "[guid(parameters('roleAssignmentName'))]",
              "properties": {
                "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionId'))]",
                "principalId": "[parameters('principalId')]"
              }
            }
          ]
        }
      },
      "dependsOn": [
        "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('rgName'))]"
      ]
    }
  ]
}

Дальнейшие действия