使用 ARM 模板和 Python 部署资源
本文介绍了如何将 Python 与 Azure 资源管理器模板(ARM 模板)配合使用,以将资源部署到 Azure。 如果不熟悉部署和管理 Azure 解决方案的概念,请参阅模版部署概述。
要部署的模板。 如果还没有模板,请从 Azure 快速入门模板存储库下载并保存一个示例模板。
已安装 Python 3.8 或更高版本。 若要安装最新版本,请参阅 Python.org
在虚拟环境中安装了以下用于 Python 的 Azure 库包。 若要安装任何包,请使用
pip install {package-name}
- azure-identity
- azure-mgmt-resource
如果虚拟环境中已安装这些包的较旧版本,则可能需要使用
pip install --upgrade {package-name}
更新它们本文中的示例将使用基于 CLI 的身份验证 (
AzureCliCredential
)。 根据所用的环境,你可能需要先运行az login
来进行身份验证。
若要部署 Bicep 文件或 ARM 模板,需要对要部署的资源具有写入权限,并且需要对 Microsoft.Resources/deployments 资源类型的所有操作具有访问权限。 例如,若要部署虚拟机,需要 Microsoft.Compute/virtualMachines/write
和 Microsoft.Resources/deployments/*
权限。
有关角色和权限的列表,请参阅 Azure 内置角色。
可将部署目标设定为资源组、订阅、管理组或租户。 根据部署范围,可以使用不同的方法。
要部署到资源组,可使用 ResourceManagementClient.deployments.begin_create_or_update:
要部署到订阅,可使用 ResourceManagementClient.deployments.begin_create_or_update_at_subscription_scope:
有关订阅级部署的详细信息,请参阅在订阅级别创建资源组和资源。
要部署到管理组,可使用 ResourceManagementClient.deployments.begin_create_or_update_at_management_group_scope。
有关管理组级部署的详细信息,请参阅在管理组级别创建资源。
要部署到租户,可使用 ResourceManagementClient.deployments.begin_create_or_update_at_tenant_scope。
有关租户级别部署的详细信息,请参阅在租户级别创建资源。
对于每一个范围,部署模板的用户必须具有创建资源所必需的权限。
部署 ARM 模板时,可以为部署指定名称。 此名称可以帮助你从部署历史记录中检索该部署。 如果没有为部署提供名称,将使用模板文件的名称。 例如,如果部署一个名为 azuredeploy.json
的模板,但未指定部署名称,则该部署将命名为 azuredeploy
。
每次运行部署时,一个包含部署名称的条目会添加到资源组的部署历史记录中。 如果运行另一个部署并为其指定了相同的名称,则会将先前的条目替换为当前部署。 如果要在部署历史记录中保持唯一条目,请为每个部署指定唯一名称。
若要创建唯一名称,你可以分配一个随机数。
import random
suffix = random.randint(1, 1000)
deployment_name = f"ExampleDeployment{suffix}"
或者,添加日期值。
from datetime import datetime
today = datetime.now().strftime("%m-%d-%Y")
deployment_name = f"ExampleDeployment{today}"
如果使用相同的部署名称对同一资源组运行并发部署,则仅会完成最后一个部署。 尚未完成的具有相同名称的任何部署都将被最后一个部署所替换。 例如,如果你运行一个名为 newStorage
的部署,它部署了一个名为 storage1
的存储帐户;与此同时,你运行了另一个名为 newStorage
的部署,它部署了一个名为 storage2
的存储帐户,则你将仅部署一个存储帐户。 生成的存储帐户名为 storage2
。
但是,如果你运行一个名为 newStorage
的部署,它部署了一个名为 storage1
的存储帐户;在该部署完成时你又立即运行了另一个名为 newStorage
的部署,它部署了一个名为 storage2
的存储帐户,则你将有两个存储帐户。 一个名为 storage1
,另一个名为 storage2
。 但是,部署历史记录中只有一个条目。
为每个部署指定唯一的名称时,可以并发运行它们而不会发生冲突。 如果你运行一个名为 newStorage1
的部署,它部署了一个名为 storage1
的存储帐户;与此同时,你又运行了另一个名为 newStorage2
的部署,它部署了一个名为 storage2
的存储帐户,则部署历史记录中将有两个存储帐户和两个条目。
为避免与并发部署冲突并确保部署历史记录中的条目是唯一的,请为每个部署指定唯一的名称。
可以部署本地计算机中的模板,也可以部署存储在外部的模板。 本节介绍如何部署本地模板。
如果要部署到不存在的资源组,请创建该资源组。 资源组名称只能包含字母数字字符、句点、下划线、连字符和括号。 它最多可以包含 90 个字符。 名称不能以句点结尾。
import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient
credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
resource_client = ResourceManagementClient(credential, subscription_id)
rg_result = resource_client.resource_groups.create_or_update(
"exampleGroup",
{
"location": "Central US"
}
)
print(f"Provisioned resource group with ID: {rg_result.id}")
若要部署 ARM 模板,请使用 ResourceManagementClient.deployments.begin_create_or_update。 以下示例需要名为 storage.json
的本地模板。
import os
import json
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.resource.resources.models import DeploymentMode
credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
resource_client = ResourceManagementClient(credential, subscription_id)
with open("storage.json", "r") as template_file:
template_body = json.load(template_file)
rg_deployment_result = resource_client.deployments.begin_create_or_update(
"exampleGroup",
"exampleDeployment",
{
"properties": {
"template": template_body,
"parameters": {
"storagePrefix": {
"value": "demostore"
},
},
"mode": DeploymentMode.incremental
}
}
)
部署可能需要几分钟时间才能完成。
你可能更愿意将 ARM 模板存储在外部位置,而不是存储在本地计算机上。 可以将模板存储在源控件存储库(例如 GitHub)中。 另外,还可以将其存储在 Azure 存储帐户中,以便在组织中共享访问。
如果要部署到不存在的资源组,请创建该资源组。 资源组名称只能包含字母数字字符、句点、下划线、连字符和括号。 它最多可以包含 90 个字符。 名称不能以句点结尾。
import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient
credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
resource_client = ResourceManagementClient(credential, subscription_id)
rg_result = resource_client.resource_groups.create_or_update(
"exampleGroup",
{
"location": "Central US"
}
)
print(f"Provisioned resource group with ID: {rg_result.id}")
若要部署 ARM 模板,请使用 ResourceManagementClient.deployments.begin_create_or_update。 以下示例部署了一个远程模板。 该模板可创建存储帐户。
import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.resource.resources.models import DeploymentMode
credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
resource_client = ResourceManagementClient(credential, subscription_id)
resource_group_name = "exampleGroup"
location = "chinanorth"
template_uri = "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.storage/storage-account-create/azuredeploy.json"
rg_deployment_result = resource_client.deployments.begin_create_or_update(
resource_group_name,
"exampleDeployment",
{
"properties": {
"templateLink": {
"uri": template_uri
},
"parameters": {
"location": {
"value": location
}
},
"mode": DeploymentMode.incremental
}
}
)
前面的示例要求模板的 URI 可公开访问,它适用于大多数情况,因为模板应该不会包含敏感数据。 如果需要指定敏感数据(如管理员密码),请以安全参数的形式传递该值。 如果将模板保存在不允许匿名访问的存储帐户中,则需要提供 SAS 令牌。
import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.resource.resources.models import DeploymentMode
credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
sas_token = os.environ["SAS_TOKEN"]
resource_client = ResourceManagementClient(credential, subscription_id)
resource_group_name = "exampleGroup"
location = "chinanorth"
template_uri = f"https://stage20230425.blob.core.chinacloudapi.cn/templates/storage.json?{sas_token}"
rg_deployment_result = resource_client.deployments.begin_create_or_update(
resource_group_name,
"exampleDeployment",
{
"properties": {
"templateLink": {
"uri": template_uri
},
"parameters": {
"location": {
"value": location
}
},
"mode": DeploymentMode.incremental
}
}
)
有关详细信息,请参阅对链接模板使用相对路径。
你可以创建模板规格,而不是部署本地或远程模板。模板规格是 Azure 订阅中包含 ARM 模板的资源。 这使你可以轻松地与组织中的用户安全地共享模板。 可使用 Azure 基于角色的访问控制 (Azure RBAC) 来授予对模板规格的访问权限。
下面的示例演示如何创建和部署模板规格。
首先,通过提供 ARM 模板创建模板规格。
import os
import json
from azure.identity import AzureCliCredential
from azure.mgmt.resource.templatespecs import TemplateSpecsClient
from azure.mgmt.resource.templatespecs.models import TemplateSpecVersion, TemplateSpec
credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
template_specs_client = TemplateSpecsClient(credential, subscription_id)
template_spec = TemplateSpec(
location="chinanorth3",
description="Storage Spec"
)
template_specs_client.template_specs.create_or_update(
"templateSpecsRG",
"storageSpec",
template_spec
)
with open("storage.json", "r") as template_file:
template_body = json.load(template_file)
version = TemplateSpecVersion(
location="chinanorth3",
description="Storage Spec",
main_template=template_body
)
template_spec_result = template_specs_client.template_spec_versions.create_or_update(
"templateSpecsRG",
"storageSpec",
"1.0.0",
version
)
print(f"Provisioned template spec with ID: {template_spec_result.id}")
然后,获取模板规格的 ID 并部署它。
import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.resource.resources.models import DeploymentMode
from azure.mgmt.resource.templatespecs import TemplateSpecsClient
credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
resource_client = ResourceManagementClient(credential, subscription_id)
template_specs_client = TemplateSpecsClient(credential, subscription_id)
template_spec = template_specs_client.template_spec_versions.get(
"templateSpecsRg",
"storageSpec",
"1.0.0"
)
rg_deployment_result = resource_client.deployments.begin_create_or_update(
"exampleGroup",
"exampleDeployment",
{
"properties": {
"template_link": {
"id": template_spec.id
},
"mode": DeploymentMode.incremental
}
}
)
有关详细信息,请参阅 Azure 资源管理器模板规格。
在部署模板之前,可以预览模板将对环境做出的更改。 使用假设操作验证模板是否进行了预期的更改。 模拟操作还验证模板是否有错误。
- 若要在出错时回退到成功的部署,请参阅出错时回退到成功的部署。
- 若要指定如何处理存在于资源组中但未在模板中定义的资源,请参阅 Azure 资源管理器部署模式。
- 若要了解如何在模板中定义参数,请参阅了解 ARM 模板的结构和语法。
- 有关部署需要 SAS 令牌的模板的信息,请参阅使用 SAS 令牌部署专用 ARM 模板。