使用 ARM 模板和 Azure PowerShell 部署资源Deploy resources with ARM templates and Azure PowerShell

本文介绍如何配合使用 Azure PowerShell 与 Azure 资源管理器模板(ARM 模板),以将资源部署到 Azure。This article explains how to use Azure PowerShell with Azure Resource Manager templates (ARM templates) to deploy your resources to Azure. 如果不熟悉部署和管理 Azure 解决方案的概念,请参阅模版部署概述If you aren't familiar with the concepts of deploying and managing your Azure solutions, see template deployment overview.

先决条件Prerequisites

你需要使用模板进行部署。You need a template to deploy. 如果还没有模板,请从 Azure 快速入门模板存储库下载并保存一个示例模板If you don't already have one, download and save an example template from the Azure Quickstart templates repo. 本文中使用的本地文件名为 C:\MyTemplates\azuredeploy.json。The local file name used in this article is C:\MyTemplates\azuredeploy.json.

需安装 Azure PowerShell 并连接到 Azure:You need to install Azure PowerShell and connect to Azure:

部署范围Deployment scope

可将部署目标设定为资源组、订阅、管理组或租户。You can target your deployment to a resource group, subscription, management group, or tenant. 根据部署范围使用不同的命令。Depending on the scope of the deployment, you use different commands.

对于每一个范围,部署模板的用户必须具有创建资源所必需的权限。For every scope, the user deploying the template must have the required permissions to create resources.

部署名称Deployment name

部署 ARM 模板时,可以为部署指定名称。When deploying an ARM template, you can give the deployment a name. 此名称可以帮助你从部署历史记录中检索该部署。This name can help you retrieve the deployment from the deployment history. 如果没有为部署提供名称,将使用模板文件的名称。If you don't provide a name for the deployment, the name of the template file is used. 例如,如果部署一个名为 azuredeploy.json 的模板,但未指定部署名称,则该部署将命名为 azuredeployFor example, if you deploy a template named azuredeploy.json and don't specify a deployment name, the deployment is named azuredeploy.

每次运行部署时,一个包含部署名称的条目会添加到资源组的部署历史记录中。Every time you run a deployment, an entry is added to the resource group's deployment history with the deployment name. 如果运行另一个部署并为其指定了相同的名称,则会将先前的条目替换为当前部署。If you run another deployment and give it the same name, the earlier entry is replaced with the current deployment. 如果要在部署历史记录中保持唯一条目,请为每个部署指定唯一名称。If you want to maintain unique entries in the deployment history, give each deployment a unique name.

若要创建唯一名称,你可以分配一个随机数。To create a unique name, you can assign a random number.

$suffix = Get-Random -Maximum 1000
$deploymentName = "ExampleDeployment" + $suffix

或者,添加日期值。Or, add a date value.

$today=Get-Date -Format "MM-dd-yyyy"
$deploymentName="ExampleDeployment"+"$today"

如果使用相同的部署名称对同一资源组运行并发部署,则仅会完成最后一个部署。If you run concurrent deployments to the same resource group with the same deployment name, only the last deployment is completed. 尚未完成的具有相同名称的任何部署都将被最后一个部署所替换。Any deployments with the same name that haven't finished are replaced by the last deployment. 例如,如果你运行一个名为 newStorage 的部署,它部署了一个名为 storage1 的存储帐户;与此同时,你运行了另一个名为 newStorage 的部署,它部署了一个名为 storage2 的存储帐户,则你将仅部署一个存储帐户。For example, if you run a deployment named newStorage that deploys a storage account named storage1, and at the same time run another deployment named newStorage that deploys a storage account named storage2, you deploy only one storage account. 生成的存储帐户名为 storage2The resulting storage account is named storage2.

但是,如果你运行一个名为 newStorage 的部署,它部署了一个名为 storage1 的存储帐户;在该部署完成时你又立即运行了另一个名为 newStorage 的部署,它部署了一个名为 storage2 的存储帐户,则你将有两个存储帐户。However, if you run a deployment named newStorage that deploys a storage account named storage1, and immediately after it completes you run another deployment named newStorage that deploys a storage account named storage2, then you have two storage accounts. 一个名为 storage1,另一个名为 storage2One is named storage1, and the other is named storage2. 但是,部署历史记录中只有一个条目。But, you only have one entry in the deployment history.

为每个部署指定唯一的名称时,可以并发运行它们而不会发生冲突。When you specify a unique name for each deployment, you can run them concurrently without conflict. 如果你运行一个名为 newStorage1 的部署,它部署了一个名为 storage1 的存储帐户;与此同时,你又运行了另一个名为 newStorage2 的部署,它部署了一个名为 storage2 的存储帐户,则部署历史记录中将有两个存储帐户和两个条目。If you run a deployment named newStorage1 that deploys a storage account named storage1, and at the same time run another deployment named newStorage2 that deploys a storage account named storage2, then you have two storage accounts and two entries in the deployment history.

为避免与并发部署冲突并确保部署历史记录中的条目是唯一的,请为每个部署指定唯一的名称。To avoid conflicts with concurrent deployments and to ensure unique entries in the deployment history, give each deployment a unique name.

部署本地模板Deploy local template

可以部署本地计算机中的模板,也可以部署存储在外部的模板。You can deploy a template from your local machine or one that is stored externally. 本节介绍如何部署本地模板。This section describes deploying a local template.

如果要部署到不存在的资源组,请创建该资源组。If you're deploying to a resource group that doesn't exist, create the resource group. 资源组名称只能包含字母数字字符、句点、下划线、连字符和括号。The name of the resource group can only include alphanumeric characters, periods, underscores, hyphens, and parenthesis. 它最多可以包含 90 个字符。It can be up to 90 characters. 名称不能以句点结尾。The name can't end in a period.

Connect-AzAccount -Environment AzureChinaCloud
New-AzResourceGroup -Name ExampleGroup -Location "China North"

若要部署本地模板,请在部署命令中使用 -TemplateFile 参数。To deploy a local template, use the -TemplateFile parameter in the deployment command. 下面的示例还显示了如何设置来自该模板的参数值。The following example also shows how to set a parameter value that comes from the template.

New-AzResourceGroupDeployment `
  -Name ExampleDeployment `
  -ResourceGroupName ExampleGroup `
  -TemplateFile c:\MyTemplates\azuredeploy.json

部署可能需要几分钟时间才能完成。The deployment can take several minutes to complete.

部署远程模板Deploy remote template

你可能更愿意将 ARM 模板存储在外部位置,而不是存储在本地计算机上。Instead of storing ARM templates on your local machine, you may prefer to store them in an external location. 可以将模板存储在源控件存储库(例如 GitHub)中。You can store templates in a source control repository (such as GitHub). 另外,还可以将其存储在 Azure 存储帐户中,以便在组织中共享访问。Or, you can store them in an Azure storage account for shared access in your organization.

如果要部署到不存在的资源组,请创建该资源组。If you're deploying to a resource group that doesn't exist, create the resource group. 资源组名称只能包含字母数字字符、句点、下划线、连字符和括号。The name of the resource group can only include alphanumeric characters, periods, underscores, hyphens, and parenthesis. 它最多可以包含 90 个字符。It can be up to 90 characters. 名称不能以句点结尾。The name can't end in a period.

New-AzResourceGroup -Name ExampleGroup -Location "China North"

若要部署外部模板,请使用 -TemplateUri 参数。To deploy an external template, use the -TemplateUri parameter.

备注

当我们使用以 https://raw.githubusercontent.com/ 开头的指定模板文件 URI 部署资源时,控制台有时会生成错误,如 Unable to download deployment contentWhen we deploy resource with specified template file URI that starts with https://raw.githubusercontent.com/, the console will run in error like Unable to download deployment content sometime.

可以执行以下操作来解决相应问题。We can follow the actions below to resolve the corresponding issue.

  1. 复制模板 URI,通过更改前缀、中缀和模板文件名来转换 URI。Copy the template URI, convert the URI by changing the prefix, infix, and tempalte file name. 例如,源 URI 是 https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-cosmosdb-sql-autoscale/azuredeploy.jsonFor exsample: the origin URI is https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-cosmosdb-sql-autoscale/azuredeploy.json

    类别Category 原始值Original value 转换后的值Converted value 操作Action
    前缀Prefix https://raw.githubusercontent.com https://github.com 更新Update
    中辍Infix blob mastermain 之前添加分支名称Add before master or main branch name
    模板文件名Template file name azuredeploy.jsonazuredeploy.json 你的下载模板文件名your download tempalte file name updateupdate

    修改后,转换后的 URI 看起来将类似于 https://github.com/Azure/azure-quickstart-templates/blob/master/101-cosmosdb-sql-autoscale/azuredeploy.jsonAfter modified, the converted URI will show like https://github.com/Azure/azure-quickstart-templates/blob/master/101-cosmosdb-sql-autoscale/azuredeploy.json.

  2. 复制转换后的 URI,并在 Internet 浏览器中手动下载特定的模板内容。Copy the converted URI and download the specific template content in Internet browsers manully.

  3. 修改从 GitHub 存储库下载或引用的模板,以适应 Azure 中国云环境。Modify the templates you downloaded or referenced from the GitHub Repo in order to fit in the Azure China Cloud Environment. 例如,替换某些终结点(将“blob.core.windows.net”替换为“blob.core.chinacloudapi.cn”,将“cloudapp.azure.com”替换为“chinacloudapp.cn”);必要时更改某些不受支持的位置、VM 映像、VM 大小、SKU 以及资源提供程序的 API 版本。For example, replace some endpoints -- "blob.core.windows.net" by "blob.core.chinacloudapi.cn", "cloudapp.azure.com" by "chinacloudapp.cn"; change some unsupported Location,VM images, VM sizes, SKU, and resource-provider's API Version when necessary.

  4. TemplateUri 的参数替换为 TemplateFile,然后用下载的实际文件名更新指定的 URI,并再次运行该脚本。Replace the parameter of TemplateUri with TemplateFile, then update the specified URI with the downloaded actual file name and run the script again.

    语言类别Language category 参考链接Reference link 操作Action
    PowerShellPowerShell New-AzResourceGroupDeployment -TemplateUri 替换为 -TemplateFileReplace -TemplateUri with -TemplateFile
    如有必要,请按照前面的步骤下载 --TemplateParameterUri 内容并在 cmdlet 中替换为 --TemplateParameterFileFollow the previous steps to download the --TemplateParameterUri content and repalce with --TemplateParameterFile in cmdlet when necessary.
    Azure CLIAzure CLI az deployment group create --template-uri 替换为 --template-file Replace --template-uri with --template-file
New-AzResourceGroupDeployment `
  -Name remoteTemplateDeployment `
  -ResourceGroupName ExampleGroup `
  -TemplateUri https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-storage-account-create/azuredeploy.json

前面的示例要求模板的 URI 可公开访问,它适用于大多数情况,因为模板应该不会包含敏感数据。The preceding example requires a publicly accessible URI for the template, which works for most scenarios because your template shouldn't include sensitive data. 如果需要指定敏感数据(如管理员密码),请以安全参数的形式传递该值。If you need to specify sensitive data (like an admin password), pass that value as a secure parameter. 但是,如果想要管理对模板的访问权限,请考虑使用模板规格However, if you want to manage access to the template, consider using template specs.

要使用存储在存储帐户中的相对路径部署远程链接模板,请使用 QueryString 指定 SAS 令牌:To deploy remote linked templates with relative path that are stored in a storage account, use QueryString to specify the SAS token:

New-AzResourceGroupDeployment `
  -Name linkedTemplateWithRelativePath `
  -ResourceGroupName "myResourceGroup" `
  -TemplateUri "https://stage20210126.blob.core.chinacloudapi.cn/template-staging/mainTemplate.json" `
  -QueryString $sasToken

有关详细信息,请参阅对链接模板使用相对路径For more information, see Use relative path for linked templates.

部署模板规格Deploy template spec

你可以创建模板规格,而不是部署本地或远程模板。模板规格是 Azure 订阅中包含 ARM 模板的资源。Instead of deploying a local or remote template, you can create a template spec. The template spec is a resource in your Azure subscription that contains an ARM template. 这使你可以轻松地与组织中的用户安全地共享模板。It makes it easy to securely share the template with users in your organization. 可使用 Azure 基于角色的访问控制 (Azure RBAC) 来授予对模板规格的访问权限。此功能目前以预览版提供。You use Azure role-based access control (Azure RBAC) to grant access to the template spec. This feature is currently in preview.

下面的示例演示如何创建和部署模板规格。The following examples show how to create and deploy a template spec.

首先,通过提供 ARM 模板创建模板规格。First, create the template spec by providing the ARM template.

New-AzTemplateSpec `
  -Name storageSpec `
  -Version 1.0 `
  -ResourceGroupName templateSpecsRg `
  -Location chinanorth2 `
  -TemplateJsonFile ./mainTemplate.json

然后,获取模板规格的 ID 并部署它。Then, get the ID for template spec and deploy it.

$id = (Get-AzTemplateSpec -Name storageSpec -ResourceGroupName templateSpecsRg -Version 1.0).Version.Id

New-AzResourceGroupDeployment `
  -ResourceGroupName demoRG `
  -TemplateSpecId $id

有关详细信息,请参阅 Azure 资源管理器模板规格(预览版)For more information, see Azure Resource Manager template specs (Preview).

预览更改Preview changes

在部署模板之前,可以预览模板将对环境做出的更改。Before deploying your template, you can preview the changes the template will make to your environment. 使用假设操作验证模板是否进行了预期的更改。Use the what-if operation to verify that the template makes the changes that you expect. 模拟操作还验证模板是否有错误。What-if also validates the template for errors.

粘贴参数值Pass parameter values

若要传递参数值,可以使用内联参数或参数文件。To pass parameter values, you can use either inline parameters or a parameter file.

内联参数。Inline parameters

若要传递内联参数,请使用 New-AzResourceGroupDeployment 命令提供参数的名称。To pass inline parameters, provide the names of the parameter with the New-AzResourceGroupDeployment command. 例如,若要将字符串和数组传递给模板,请使用:For example, to pass a string and array to a template, use:

$arrayParam = "value1", "value2"
New-AzResourceGroupDeployment -ResourceGroupName testgroup `
  -TemplateFile c:\MyTemplates\demotemplate.json `
  -exampleString "inline string" `
  -exampleArray $arrayParam

还可以获取文件的内容并将该内容作为内联参数提供。You can also get the contents of file and provide that content as an inline parameter.

$arrayParam = "value1", "value2"
New-AzResourceGroupDeployment -ResourceGroupName testgroup `
  -TemplateFile c:\MyTemplates\demotemplate.json `
  -exampleString $(Get-Content -Path c:\MyTemplates\stringcontent.txt -Raw) `
  -exampleArray $arrayParam

当需要提供配置值时,从文件中获取参数值非常有用。Getting a parameter value from a file is helpful when you need to provide configuration values. 例如,可以为 Linux 虚拟机提供 cloud-init 值For example, you can provide cloud-init values for a Linux virtual machine.

如果需要传入对象数组,请在 PowerShell 中创建哈希表并将其添加到数组中。If you need to pass in an array of objects, create hash tables in PowerShell and add them to an array. 在部署过程中将该数组作为参数传递。Pass that array as a parameter during deployment.

$hash1 = @{ Name = "firstSubnet"; AddressPrefix = "10.0.0.0/24"}
$hash2 = @{ Name = "secondSubnet"; AddressPrefix = "10.0.1.0/24"}
$subnetArray = $hash1, $hash2
New-AzResourceGroupDeployment -ResourceGroupName testgroup `
  -TemplateFile c:\MyTemplates\demotemplate.json `
  -exampleArray $subnetArray

参数文件Parameter files

你可能会发现,与在脚本中以内联值的形式传递参数相比,使用包含参数值的 JSON 文件更为容易。Rather than passing parameters as inline values in your script, you may find it easier to use a JSON file that contains the parameter values. 参数文件可以是本地文件,也可以是具有可访问 URI 的外部文件。The parameter file can be a local file or an external file with an accessible URI.

有关参数文件的详细信息,请参阅创建资源管理器参数文件For more information about the parameter file, see Create Resource Manager parameter file.

若要传递本地参数文件,请使用 TemplateParameterFile 参数:To pass a local parameter file, use the TemplateParameterFile parameter:

New-AzResourceGroupDeployment -Name ExampleDeployment -ResourceGroupName ExampleResourceGroup `
  -TemplateFile c:\MyTemplates\azuredeploy.json `
  -TemplateParameterFile c:\MyTemplates\storage.parameters.json

若要传递外部参数文件,请使用 TemplateParameterUri 参数:To pass an external parameter file, use the TemplateParameterUri parameter:

New-AzResourceGroupDeployment -Name ExampleDeployment -ResourceGroupName ExampleResourceGroup `
  -TemplateUri https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-storage-account-create/azuredeploy.json `
  -TemplateParameterUri https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-storage-account-create/azuredeploy.parameters.json

后续步骤Next steps