创建资源组并部署资源
Create Resource Group and Deploy Resource
根据Microsoft Documentation,现在可以创建资源组并将资源部署到新创建的资源组。不过有一个小问题,在一开始,我们有这个免责声明 -
Subscription level deployment is different from resource group deployment in the following aspects:
Schema and commands
The schema and commands you use for subscription-level deployments are different than resource group deployments.
For the schema, use https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#
这引发了一个主要问题,azuredeploy.json 不再被识别为部署模板,因为它没有使用资源部署架构(https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json# ).
因此,另一种选择是将资源组创建为 嵌套模板 并放置 dependsOn 对于将要创建的子资源,这现在允许我 Deploy/Validate 文件。但是,这有一个新问题。即使 dependsOn 指示创建资源组,它仍然无法识别这一点并返回错误 - 找不到资源组,因此无法部署资源。我尝试使用链接模板(我知道这没有任何区别,但仍然如此)
有人成功做到了吗?
- 同时创建资源组和部署资源。
- 克服尝试使用 DependsOn 但仍未获得正确部署或验证的障碍?
添加我的代码。
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "North Europe"
},
"FirstResourceGroupName": {
"type": "string",
"defaultValue": "myFirstRG"
},
"FirstBlobStorageName": {
"type": "string",
"defaultValue": "North Europe"
}
},
"variables": {
},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2018-05-01",
"name": "ResourceGroupDeployment",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.1",
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"apiVersion": "2018-05-01",
"location": "[parameters('location')]",
"name": "[parameters('FirstResourceGroupName')]",
"properties": {}
}
],
"outputs" : {}
}
}
},
{
//ResourceDeployment
"type": "Microsoft.Resources/deployments",
"name": "StorageDeployment",
"apiVersion": "2017-05-10",
"dependsOn": [
"[concat('Microsoft.Resources/deployments/', 'ResourceGroupDeployment')]"
//"ResourceGroupDeployment"
],
"resourceGroup": "[parameters('FirstResourceGroupName')]",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2017-10-01",
"name": "[parameters('FirstBlobStorageName')]",
"location": "[parameters('location')]",
"kind": "StorageV2",
"sku": {
"name": "Standard_LRS"
}
}
],
"outputs": {}
}
}
}
],
"outputs": {}
}
取自官方文档的示例:
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.1",
"parameters": {
"rgName": {
"type": "string"
},
"rgLocation": {
"type": "string"
},
"storagePrefix": {
"type": "string",
"maxLength": 11
}
},
"variables": {
"storageName": "[concat(parameters('storagePrefix'), uniqueString(subscription().id, parameters('rgName')))]"
},
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"apiVersion": "2018-05-01",
"location": "[parameters('rgLocation')]",
"name": "[parameters('rgName')]",
"properties": {}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2018-05-01",
"name": "storageDeployment",
"resourceGroup": "[parameters('rgName')]",
"dependsOn": [
"[resourceId('Microsoft.Resources/resourceGroups/', parameters('rgName'))]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2017-10-01",
"name": "[variables('storageName')]",
"location": "[parameters('rgLocation')]",
"kind": "StorageV2",
"sku": {
"name": "Standard_LRS"
}
}
]
}
}
}
]
}
正是您所需要的。
当您不使用 Visual Studio 或 Portal 进行部署时,MS 提出的解决方案很好。我的主要问题是模板的验证再次不适用于订阅级部署,因为它使用的模式未被识别为 ARM。
它可能通过任何其他方式如@4c74356b41建议的那样工作,即cli\sdks\restapi,但我没有走那条路。
我的另一个解决方案是通过在 Azure DevOps 管道上添加一个步骤来 运行 一个 powershell 脚本。这是我最接近完成这项工作的一次,但再次验证以检查我的部署是否会成功,仍然悬而未决。我不希望我的发布管道因为模板无效而失败。
这是我收集到的信息,验证失败的原因(即使部署了 RG 并使用 dependsOn)是因为资源组不会被创建,直到您部署模板。模板部署不会发生,除非它通过验证,因为资源组不存在。所以我们陷入了一个循环。这两个选项要么在验证之前在门户网站上手动创建它们(这违背了自动化的要点),要么在验证它们之前使用简单的 powershell 步骤。后者是我所经历的。我知道这是非正统的,但有效……并且还验证了我的模板。
注意 - 解决方案与原始问题不同,因为我使用了多个资源组创建。根据 MS 文档,您最多可以通过这种方式部署 5 个 RG。
首先,创建一个资源组文件,用于保存您要创建的资源组。它只是一个简单的 JSON 文件,例如
{
"rgNames":
{
"rg1": { "rg": "resource-group-main" },
"rg2": { "rg": "resource-group-backup" }
}
}
使用您添加到此文件的相同值作为参数,因此您可以使用它们将资源部署到。
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"ResourceGroups": {
"type": "object",
//If you are changing this value !!!! Please make sure you are also updating the same in the ResourceGroups.ARM.json !!!!
"allowedValues": [
{
"rgNames":
{
"rg1": { "rg": "resource-group-main" },
"rg2": { "rg": "resource-group-backup" }
}
}
]
}
}
其次,更改PS 脚本以包含循环遍历需要部署的资源组列表的代码。
# Set '$RGTemplateFile' parameter to be the name of the file you added to your project
$rgFile = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, $RGTemplateFile))
$rgString = Get-Content -Raw -Path $rgFile | ConvertFrom-Json
# helper to turn PSCustomObject into a list of key/value pairs
function Get-ObjectMembers {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True, ValueFromPipeline=$True)]
[PSCustomObject]$obj
)
$obj | Get-Member -MemberType NoteProperty | ForEach-Object {
$key = $_.Name
[PSCustomObject]@{Key = $key; Value = $obj."$key"}
}
}
$rgValues = $jsonParam | Get-ObjectMembers | foreach {
$_.Value | Get-ObjectMembers | foreach {
[PSCustomObject]@{
RGName = $_.value.rgNames | select -First 1
}
}
}
foreach ($values in $rgValues)
{
New-AzureRmResourceGroup -Name $values.RGName -Location $ResourceGroupLocation -Verbose -Force
}
在执行验证之前添加上面的代码 -
if ($ValidateOnly) {
$ErrorMessages = Format-ValidationOutput (Test-AzureRmResourceGroupDeployment -ResourceGroupName $ResourceGroupName `
-TemplateFile $TemplateFile `
-TemplateParameterFile $TemplateParametersFile `
@OptionalParameters)
:
最后,更改部署模板文件(azuredeploy.json)以执行嵌套模板部署或链接模板以在您声明的 RG 上部署资源。 (我用过Linked,因为它看起来更整洁)
"variables": {
"rg1Name": "[parameters('ResourceGroups')['rgNames']['rg1'].rg]",
"rg2Name": "[parameters('ResourceGroups')['rgNames']['rg2'].rg]",
"blob1Name": "[parameters('blob1')]",
"blob2Name": "[parameters('blob2')]",
"arm1": "[concat(parameters('_artifactsLocation'), 'rg1/rg1.ARM.json', parameters('_artifactsLocationSasToken'))]",
"arm2": "[concat(parameters('_artifactsLocation'), 'rg2/rg2.ARM.json', parameters('_artifactsLocationSasToken'))]"
},
"resources": [
{
//RG1 Resources Deployment
"type": "Microsoft.Resources/deployments",
"name": "RG1Resources",
"apiVersion": "2017-05-10",
"resourceGroup": "[variables('rg1Name')]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('arm1')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"blob1Name": {
"value": "[variables('blob1Name')]"
}
}
}
},
{
//RG2 Resources Deployment
"type": "Microsoft.Resources/deployments",
"name": "RG2Resources",
"apiVersion": "2017-05-10",
"resourceGroup": "[variables('rg2Name')]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('arm2')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"blobName": {
"value": "[variables('blob2Name')]"
}
}
}
}
],
"outputs": {}
}
您的 rg1.ARM.json 和 rg2.ARM.json 文件看起来很像,显然一个文件可以拥有多个资源。
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"blobName": {
"type": "string"
}
},
"variables": {
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[parameters('blobName')]",
"kind": "StorageV2",
"apiVersion": "2018-07-01",
"location": "[resourceGroup().location]",
"sku": {
"name": "Standard_LRS"
},
"properties": {}
}
],
"outputs": {
}
}
设置完成后,您将能够验证文件,因为 PS 脚本会在文件通过验证之前为您创建 RG。
根据Microsoft Documentation,现在可以创建资源组并将资源部署到新创建的资源组。不过有一个小问题,在一开始,我们有这个免责声明 -
Subscription level deployment is different from resource group deployment in the following aspects:
Schema and commands
The schema and commands you use for subscription-level deployments are different than resource group deployments.
For the schema, use https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#
这引发了一个主要问题,azuredeploy.json 不再被识别为部署模板,因为它没有使用资源部署架构(https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json# ).
因此,另一种选择是将资源组创建为 嵌套模板 并放置 dependsOn 对于将要创建的子资源,这现在允许我 Deploy/Validate 文件。但是,这有一个新问题。即使 dependsOn 指示创建资源组,它仍然无法识别这一点并返回错误 - 找不到资源组,因此无法部署资源。我尝试使用链接模板(我知道这没有任何区别,但仍然如此)
有人成功做到了吗?
- 同时创建资源组和部署资源。
- 克服尝试使用 DependsOn 但仍未获得正确部署或验证的障碍?
添加我的代码。
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "North Europe"
},
"FirstResourceGroupName": {
"type": "string",
"defaultValue": "myFirstRG"
},
"FirstBlobStorageName": {
"type": "string",
"defaultValue": "North Europe"
}
},
"variables": {
},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2018-05-01",
"name": "ResourceGroupDeployment",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.1",
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"apiVersion": "2018-05-01",
"location": "[parameters('location')]",
"name": "[parameters('FirstResourceGroupName')]",
"properties": {}
}
],
"outputs" : {}
}
}
},
{
//ResourceDeployment
"type": "Microsoft.Resources/deployments",
"name": "StorageDeployment",
"apiVersion": "2017-05-10",
"dependsOn": [
"[concat('Microsoft.Resources/deployments/', 'ResourceGroupDeployment')]"
//"ResourceGroupDeployment"
],
"resourceGroup": "[parameters('FirstResourceGroupName')]",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2017-10-01",
"name": "[parameters('FirstBlobStorageName')]",
"location": "[parameters('location')]",
"kind": "StorageV2",
"sku": {
"name": "Standard_LRS"
}
}
],
"outputs": {}
}
}
}
],
"outputs": {}
}
取自官方文档的示例:
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.1",
"parameters": {
"rgName": {
"type": "string"
},
"rgLocation": {
"type": "string"
},
"storagePrefix": {
"type": "string",
"maxLength": 11
}
},
"variables": {
"storageName": "[concat(parameters('storagePrefix'), uniqueString(subscription().id, parameters('rgName')))]"
},
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"apiVersion": "2018-05-01",
"location": "[parameters('rgLocation')]",
"name": "[parameters('rgName')]",
"properties": {}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2018-05-01",
"name": "storageDeployment",
"resourceGroup": "[parameters('rgName')]",
"dependsOn": [
"[resourceId('Microsoft.Resources/resourceGroups/', parameters('rgName'))]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2017-10-01",
"name": "[variables('storageName')]",
"location": "[parameters('rgLocation')]",
"kind": "StorageV2",
"sku": {
"name": "Standard_LRS"
}
}
]
}
}
}
]
}
正是您所需要的。
当您不使用 Visual Studio 或 Portal 进行部署时,MS 提出的解决方案很好。我的主要问题是模板的验证再次不适用于订阅级部署,因为它使用的模式未被识别为 ARM。
它可能通过任何其他方式如@4c74356b41建议的那样工作,即cli\sdks\restapi,但我没有走那条路。
我的另一个解决方案是通过在 Azure DevOps 管道上添加一个步骤来 运行 一个 powershell 脚本。这是我最接近完成这项工作的一次,但再次验证以检查我的部署是否会成功,仍然悬而未决。我不希望我的发布管道因为模板无效而失败。
这是我收集到的信息,验证失败的原因(即使部署了 RG 并使用 dependsOn)是因为资源组不会被创建,直到您部署模板。模板部署不会发生,除非它通过验证,因为资源组不存在。所以我们陷入了一个循环。这两个选项要么在验证之前在门户网站上手动创建它们(这违背了自动化的要点),要么在验证它们之前使用简单的 powershell 步骤。后者是我所经历的。我知道这是非正统的,但有效……并且还验证了我的模板。
注意 - 解决方案与原始问题不同,因为我使用了多个资源组创建。根据 MS 文档,您最多可以通过这种方式部署 5 个 RG。
首先,创建一个资源组文件,用于保存您要创建的资源组。它只是一个简单的 JSON 文件,例如
{
"rgNames":
{
"rg1": { "rg": "resource-group-main" },
"rg2": { "rg": "resource-group-backup" }
}
}
使用您添加到此文件的相同值作为参数,因此您可以使用它们将资源部署到。
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"ResourceGroups": {
"type": "object",
//If you are changing this value !!!! Please make sure you are also updating the same in the ResourceGroups.ARM.json !!!!
"allowedValues": [
{
"rgNames":
{
"rg1": { "rg": "resource-group-main" },
"rg2": { "rg": "resource-group-backup" }
}
}
]
}
}
其次,更改PS 脚本以包含循环遍历需要部署的资源组列表的代码。
# Set '$RGTemplateFile' parameter to be the name of the file you added to your project
$rgFile = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, $RGTemplateFile))
$rgString = Get-Content -Raw -Path $rgFile | ConvertFrom-Json
# helper to turn PSCustomObject into a list of key/value pairs
function Get-ObjectMembers {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True, ValueFromPipeline=$True)]
[PSCustomObject]$obj
)
$obj | Get-Member -MemberType NoteProperty | ForEach-Object {
$key = $_.Name
[PSCustomObject]@{Key = $key; Value = $obj."$key"}
}
}
$rgValues = $jsonParam | Get-ObjectMembers | foreach {
$_.Value | Get-ObjectMembers | foreach {
[PSCustomObject]@{
RGName = $_.value.rgNames | select -First 1
}
}
}
foreach ($values in $rgValues)
{
New-AzureRmResourceGroup -Name $values.RGName -Location $ResourceGroupLocation -Verbose -Force
}
在执行验证之前添加上面的代码 -
if ($ValidateOnly) {
$ErrorMessages = Format-ValidationOutput (Test-AzureRmResourceGroupDeployment -ResourceGroupName $ResourceGroupName `
-TemplateFile $TemplateFile `
-TemplateParameterFile $TemplateParametersFile `
@OptionalParameters)
:
最后,更改部署模板文件(azuredeploy.json)以执行嵌套模板部署或链接模板以在您声明的 RG 上部署资源。 (我用过Linked,因为它看起来更整洁)
"variables": {
"rg1Name": "[parameters('ResourceGroups')['rgNames']['rg1'].rg]",
"rg2Name": "[parameters('ResourceGroups')['rgNames']['rg2'].rg]",
"blob1Name": "[parameters('blob1')]",
"blob2Name": "[parameters('blob2')]",
"arm1": "[concat(parameters('_artifactsLocation'), 'rg1/rg1.ARM.json', parameters('_artifactsLocationSasToken'))]",
"arm2": "[concat(parameters('_artifactsLocation'), 'rg2/rg2.ARM.json', parameters('_artifactsLocationSasToken'))]"
},
"resources": [
{
//RG1 Resources Deployment
"type": "Microsoft.Resources/deployments",
"name": "RG1Resources",
"apiVersion": "2017-05-10",
"resourceGroup": "[variables('rg1Name')]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('arm1')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"blob1Name": {
"value": "[variables('blob1Name')]"
}
}
}
},
{
//RG2 Resources Deployment
"type": "Microsoft.Resources/deployments",
"name": "RG2Resources",
"apiVersion": "2017-05-10",
"resourceGroup": "[variables('rg2Name')]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('arm2')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"blobName": {
"value": "[variables('blob2Name')]"
}
}
}
}
],
"outputs": {}
}
您的 rg1.ARM.json 和 rg2.ARM.json 文件看起来很像,显然一个文件可以拥有多个资源。
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"blobName": {
"type": "string"
}
},
"variables": {
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[parameters('blobName')]",
"kind": "StorageV2",
"apiVersion": "2018-07-01",
"location": "[resourceGroup().location]",
"sku": {
"name": "Standard_LRS"
},
"properties": {}
}
],
"outputs": {
}
}
设置完成后,您将能够验证文件,因为 PS 脚本会在文件通过验证之前为您创建 RG。