练习 - 向部署脚本添加参数
现在你已使用部署脚本将一些手动工作迁移到 Azure 资源管理器 (ARM) 模板中,组织中的另一个合作伙伴应用程序团队已向你请求帮助。
该团队的流程有类似的要求,但他们需要将多个文件部署到其存储帐户。 该团队有一个 PowerShell 脚本可将文件列表作为参数上传,类似于已在模板中使用的脚本。
在本练习中,你将以之前的模板作为起点,并更新 PowerShell 脚本以使用合作伙伴团队提供的模板。 然后,将添加一种方法,使部署模板的人员能够指定要部署的配置文件(一个或多个)。
在此过程中,你将:
- 更新部署脚本。
- 添加环境变量和模板参数,并将其传递给部署脚本。
- 将输出添加到部署脚本。
- 添加参数文件。
- 部署模板,并验证结果。
创建共享模板
可以从在上一练习中创建的模板入手。
打开 Visual Studio Code 并创建名为 azuredeploy.json 的新文件。
将以下起始模板复制到 azuredeploy.json 中。
{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.1", "apiProfile": "", "parameters": {}, "variables": { "storageAccountName": "[concat('storage', uniqueString(resourceGroup().id))]", "storageBlobContainerName": "config", "userAssignedIdentityName": "configDeployer", "roleAssignmentName": "[guid(concat(resourceGroup().id, 'contributor'))]", "contributorRoleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", "deploymentScriptName": "CopyConfigScript" }, "functions": [], "resources": [ { "name": "[variables('storageAccountName')]", "type": "Microsoft.Storage/storageAccounts", "apiVersion": "2023-01-01", "tags": { "displayName": "[variables('storageAccountName')]" }, "location": "[resourceGroup().location]", "kind": "StorageV2", "sku": { "name": "Standard_LRS", "tier": "Standard" }, "properties": { "allowBlobPublicAccess": true, "encryption": { "services": { "blob": { "enabled": true } }, "keySource": "Microsoft.Storage" }, "supportsHttpsTrafficOnly": true } }, { "type": "Microsoft.Storage/storageAccounts/blobServices", "apiVersion": "2019-04-01", "name": "[concat(variables('storageAccountName'), '/default')]", "dependsOn": [ "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]" ] }, { "type": "Microsoft.Storage/storageAccounts/blobServices/containers", "apiVersion": "2019-04-01", "name": "[concat(variables('storageAccountName'),'/default/',variables('storageBlobContainerName'))]", "dependsOn": [ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('storageAccountName'), 'default')]", "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]" ], "properties": { "publicAccess": "Blob" } }, { "type": "Microsoft.ManagedIdentity/userAssignedIdentities", "apiVersion": "2018-11-30", "name": "[variables('userAssignedIdentityName')]", "location": "[resourceGroup().location]" }, { "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2020-04-01-preview", "name": "[variables('roleAssignmentName')]", "dependsOn": [ "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('userAssignedIdentityName'))]" ], "properties": { "roleDefinitionId": "[variables('contributorRoleDefinitionId')]", "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('userAssignedIdentityName')), '2015-08-31-preview').principalId]", "scope": "[resourceGroup().id]", "principalType": "ServicePrincipal" } }, { "type": "Microsoft.Resources/deploymentScripts", "apiVersion": "2020-10-01", "name": "[variables('deploymentScriptName')]", "location": "[resourceGroup().location]", "kind": "AzurePowerShell", "dependsOn": [ "[resourceId('Microsoft.Authorization/roleAssignments', variables('roleAssignmentName'))]", "[resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', variables('storageAccountName'), 'default', variables('storageBlobContainerName'))]" ], "identity": { "type": "UserAssigned", "userAssignedIdentities": { "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',variables('userAssignedIdentityName'))]": {} } }, "properties": { "azPowerShellVersion": "3.0", "scriptContent": " Invoke-RestMethod -Uri 'https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/mslearn-arm-deploymentscripts-sample/appsettings.json' -OutFile 'appsettings.json' $storageAccount = Get-AzStorageAccount -ResourceGroupName 'learndeploymentscript_exercise_1' | Where-Object { $_.StorageAccountName -like 'storage*' } $blob = Set-AzStorageBlobContent -File 'appsettings.json' -Container 'config' -Blob 'appsettings.json' -Context $StorageAccount.Context $DeploymentScriptOutputs = @{} $DeploymentScriptOutputs['Uri'] = $blob.ICloudBlob.Uri $DeploymentScriptOutputs['StorageUri'] = $blob.ICloudBlob.StorageUri ", "retentionInterval": "P1D" } } ], "outputs": { "fileUri": { "type": "string", "value": "[reference(variables('deploymentScriptName')).outputs.Uri]" } } }
保存模板。
打开 Visual Studio Code,并创建名为 main.bicep 的新文件。
将以下起始模板复制到 main.bicep 中。
var storageAccountName = 'storage${uniqueString(resourceGroup().id)}' var storageBlobContainerName = 'config' var userAssignedIdentityName = 'configDeployer' var roleAssignmentName = guid(resourceGroup().id, 'contributor') var contributorRoleDefinitionId = resourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') var deploymentScriptName = 'CopyConfigScript' resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = { name: storageAccountName tags: { displayName: storageAccountName } location: resourceGroup().location kind: 'StorageV2' sku: { name: 'Standard_LRS' tier: 'Standard' } properties: { allowBlobPublicAccess: true encryption: { services: { blob: { enabled: true } } keySource: 'Microsoft.Storage' } supportsHttpsTrafficOnly: true } resource blobService 'blobServices' existing = { name: 'default' } } resource blobContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2019-04-01' = { parent: storageAccount::blobService name: storageBlobContainerName properties: { publicAccess: 'Blob' } } resource userAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { name: userAssignedIdentityName location: resourceGroup().location } resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = { name: roleAssignmentName properties: { roleDefinitionId: contributorRoleDefinitionId principalId: userAssignedIdentity.properties.principalId principalType: 'ServicePrincipal' } } resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { name: deploymentScriptName location: resourceGroup().location kind: 'AzurePowerShell' identity: { type: 'UserAssigned' userAssignedIdentities: { '${userAssignedIdentity.id}': {} } } properties: { azPowerShellVersion: '3.0' scriptContent: ''' Invoke-RestMethod -Uri 'https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/mslearn-arm-deploymentscripts-sample/appsettings.json' -OutFile 'appsettings.json' $storageAccount = Get-AzStorageAccount -ResourceGroupName 'learndeploymentscript_exercise_1' | Where-Object { $_.StorageAccountName -like 'storage*' } $blob = Set-AzStorageBlobContent -File 'appsettings.json' -Container 'config' -Blob 'appsettings.json' -Context $storageAccount.Context $DeploymentScriptOutputs = @{} $DeploymentScriptOutputs['Uri'] = $blob.ICloudBlob.Uri $DeploymentScriptOutputs['StorageUri'] = $blob.ICloudBlob.StorageUri ''' retentionInterval: 'P1D' } dependsOn: [ roleAssignment blobContainer ] } output fileUri string = deploymentScript.properties.outputs.Uri
保存模板。
更新 PowerShell 脚本
由于另一个团队已经完成了创建 PowerShell 脚本(用于复制多个文件)的艰难任务,因此你决定在模板中使用该脚本。
对 properties
部分中的 scriptContent
进行编辑,使其包含合作伙伴团队提供的脚本。
param([string]$File)
$fileList = $File -replace '(\[|\])' -split ',' | ForEach-Object { $_.trim() }
$storageAccount = Get-AzStorageAccount -ResourceGroupName $env:ResourceGroupName -Name $env:StorageAccountName -Verbose
$count = 0
$DeploymentScriptOutputs = @{}
foreach ($fileName in $fileList) {
Write-Host \"Copying $fileName to $env:StorageContainerName in $env:StorageAccountName.\"
Invoke-RestMethod -Uri \"https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/mslearn-arm-deploymentscripts-sample/$fileName\" -OutFile $fileName
$blob = Set-AzStorageBlobContent -File $fileName -Container $env:StorageContainerName -Blob $fileName -Context $storageAccount.Context
$DeploymentScriptOutputs[$fileName] = @{}
$DeploymentScriptOutputs[$fileName]['Uri'] = $blob.ICloudBlob.Uri
$DeploymentScriptOutputs[$fileName]['StorageUri'] =$blob.ICloudBlob.StorageUri
$count++
}
Write-Host \"Finished copying $count files.\"
param([string]$File)
$fileList = $File -replace '(\[|\])' -split ',' | ForEach-Object { $_.trim() }
$storageAccount = Get-AzStorageAccount -ResourceGroupName $env:ResourceGroupName -Name $env:StorageAccountName -Verbose
$count = 0
$DeploymentScriptOutputs = @{}
foreach ($fileName in $fileList) {
Write-Host "Copying $fileName to $env:StorageContainerName in $env:StorageAccountName."
Invoke-RestMethod -Uri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/mslearn-arm-deploymentscripts-sample/$fileName" -OutFile $fileName
$blob = Set-AzStorageBlobContent -File $fileName -Container $env:StorageContainerName -Blob $fileName -Context $storageAccount.Context
$DeploymentScriptOutputs[$fileName] = @{}
$DeploymentScriptOutputs[$fileName]['Uri'] = $blob.ICloudBlob.Uri
$DeploymentScriptOutputs[$fileName]['StorageUri'] = $blob.ICloudBlob.StorageUri
$count++
}
Write-Host "Finished copying $count files."
添加环境变量
所采用的脚本需要某些环境变量。 可以直接在模板中指定它们,但使用模板函数获取一些值将更加灵活。
将
environmentVariables
属性添加到部署脚本的properties
部分。"environmentVariables": [ ],
添加
ResourceGroupName
的环境变量。"environmentVariables": [ { "name": "ResourceGroupName", "value": "[resourceGroup().name]" } ],
添加
StorageAccountName
的环境变量。"environmentVariables": [ { "name": "ResourceGroupName", "value": "[resourceGroup().name]" }, { "name": "StorageAccountName", "value": "[variables('storageAccountName')]" } ],
添加
StorageContainerName
的环境变量。"environmentVariables": [ { "name": "ResourceGroupName", "value": "[resourceGroup().name]" }, { "name": "StorageAccountName", "value": "[variables('storageAccountName')]" }, { "name": "StorageContainerName", "value": "[variables('storageBlobContainerName')]" } ],
提示
使用模板函数访问常用值,例如 [resourceGroup().name]
和 [variables()]
。
所采用的脚本需要某些环境变量。 可以直接在模板中指定它们,但使用 Bicep 变量获取一些值将更加灵活。
将
environmentVariables
属性添加到部署脚本的properties
部分。environmentVariables: [ ]
添加
ResourceGroupName
的环境变量。environmentVariables: [ { name: 'ResourceGroupName' value: resourceGroup().name } ]
添加
StorageAccountName
的环境变量。environmentVariables: [ { name: 'ResourceGroupName' value: resourceGroup().name } { name: 'StorageAccountName' value: storageAccountName } ]
添加
StorageContainerName
的环境变量。environmentVariables: [ { name: 'ResourceGroupName' value: resourceGroup().name } { name: 'StorageAccountName' value: storageAccountName } { name: 'StorageContainerName' value: storageBlobContainerName } ]
添加模板参数
为了让这两个团队可以更轻松地使用模板,可将向模板添加一个参数,使每个团队都可以指定要复制的文件。
将参数添加到模板以采用文件名数组。
"parameters": {
"filesToCopy": {
"type": "array",
"metadata": {
"description": "List of files to copy to application storage account."
}
}
},
这样,就可以提供默认值,让团队能够继续使用模板,而无需更改部署过程。 虽然不是必需的,但输入新的默认值可以帮助你理解更易于团队采用新版模板的模式(如果其行为和之前一样),还能获得新功能作为回报。 换句话说,此步骤展示了在通过更改来支持将来的工作的同时,如何维护现有行为。
将参数添加到模板以采用文件名数组。
@description('List of files to copy to application storage account.')
param filesToCopy array
这样,就可以提供默认值,让团队能够继续使用模板,而无需更改部署过程。 虽然不是必需的,但输入新的默认值可以帮助你理解更易于团队采用新版模板的模式(如果其行为和之前一样),还能获得新功能作为回报。 换句话说,此步骤展示了在通过更改来支持将来的工作的同时,如何维护现有行为。
添加参数以传入要复制的文件
接下来,你可以获取刚定义的参数,并将其传递给部署脚本。 传递命令行参数可能很棘手,因为字符串是在多个级别进行评估的。 正确转义引号并为作业选择正确的引号对于取得成功至关重要。
提示
使用模板函数访问 [string()]
等常用函数,将某种类型的值转换为字符串。
将
arguments
属性添加到部署脚本。 PowerShell 脚本采用名为File
的参数,该参数是应来自filesToCopy
模板参数的文件名的字符串。 请确保整个参数用引号括起,以便正确传递。注意
此
arguments
属性无效。 如果在 Visual Studio Code 中使用 Azure 资源管理器扩展,则可能会标记此行。 你将在后续步骤中解决此问题。"arguments": "[concat( '-File '', string(parameters('filesToCopy')), ''' )]",
提示
在 JSON 中对内容使用引号可能很难,尤其是在传入命令行参数时。 可以使用模板变量来表示难以转义的字符。
添加一个模板变量来表示单引号字符。
"variables": { "singleQuote": "'", "storageAccountName": "[concat('storage', uniqueString(resourceGroup().id))]", "storageBlobContainerName": "config", "userAssignedIdentityName": "configDeployer", "roleAssignmentName": "[guid(concat(resourceGroup().id, 'contributor'))]", "contributorRoleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", "deploymentScriptName": "CopyConfigScript" },
将
arguments
属性中的单引号替换为刚定义的变量。"arguments": "[concat( '-File ', variables('singleQuote'), string(parameters('filesToCopy')), variables('singleQuote'))]",
接下来,你可以获取刚定义的参数,并将其传递给部署脚本。 传递命令行参数可能很棘手,因为字符串是在多个级别进行评估的。 正确转义引号并为作业选择正确的引号对于取得成功至关重要。
将 arguments
属性添加到部署脚本。 PowerShell 脚本采用名为 File
的参数,该参数是应来自 filesToCopy
模板参数的文件名的字符串。
arguments: '-File \'${string(filesToCopy)}\''
请注意,这将使用多个 Bicep 功能:
- 字符串内插,用于合并字符串。
- 我们使用
\
转义字符在字符串中包含单引号字符 ('
),因为单引号通常是 Bicep 中的保留字符。 - 我们使用
string()
函数将filesToCopy
数组转换为字符串。
更新模板输出
因为你要更改部署脚本以部署一个或多个文件,所以需要更新模板输出以提供所有必需的信息。
更新模板中的
outputs
以返回整个对象(每个文件都将有一个 URI)。$DeploymentScriptOutputs = @{} foreach ($fileName in $fileList) { Write-Host \"Copying $fileName to $env:StorageContainerName in $env:StorageAccountName.\" Invoke-RestMethod -Uri \"https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/mslearn-arm-deploymentscripts-sample/$fileName\" -OutFile $fileName $blob = Set-AzStorageBlobContent -File $fileName -Container $env:StorageContainerName -Blob $fileName -Context $storageAccount.Context $DeploymentScriptOutputs[$fileName] = @{} $DeploymentScriptOutputs[$fileName]['Uri'] = $blob.ICloudBlob.Uri $DeploymentScriptOutputs[$fileName]['StorageUri'] =$blob.ICloudBlob.StorageUri $count++ }
使用存储帐户名称(具有随机标识符)添加另一个输出。 稍后你将使用它来验证部署脚本是否执行了预期的操作。
$DeploymentScriptOutputs = @{} foreach ($fileName in $fileList) { Write-Host \"Copying $fileName to $env:StorageContainerName in $env:StorageAccountName.\" Invoke-RestMethod -Uri \"https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/mslearn-arm-deploymentscripts-sample/$fileName\" -OutFile $fileName $blob = Set-AzStorageBlobContent -File $fileName -Container $env:StorageContainerName -Blob $fileName -Context $storageAccount.Context $DeploymentScriptOutputs[$fileName] = @{} $DeploymentScriptOutputs[$fileName]['Uri'] = $blob.ICloudBlob.Uri $DeploymentScriptOutputs[$fileName]['StorageUri'] =$blob.ICloudBlob.StorageUri $count++ }
更新模板中的输出以返回整个对象(每个文件都将有一个 URI)。
output fileUri object = deploymentScript.properties.outputs
使用存储帐户名称(具有随机标识符)添加另一个输出。 稍后你将使用它来验证部署脚本是否执行了预期的操作。
output storageAccountName string = storageAccountName
验证模板
模板的外观应类似于:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.1",
"apiProfile": "",
"parameters": {
"filesToCopy": {
"type": "array",
"defaultValue": [ "appsettings.json" ],
"metadata": {
"description": "List of files to copy to application storage account."
}
}
},
"variables": {
"singleQuote": "'",
"storageAccountName": "[concat('storage', uniqueString(resourceGroup().id))]",
"storageBlobContainerName": "config",
"userAssignedIdentityName": "configDeployer",
"roleAssignmentName": "[guid(concat(resourceGroup().id, 'contributor'))]",
"contributorRoleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
"deploymentScriptName": "CopyConfigScript"
},
"functions": [],
"resources": [
{
"name": "[variables('storageAccountName')]",
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2023-01-01",
"tags": {
"displayName": "[variables('storageAccountName')]"
},
"location": "[resourceGroup().location]",
"kind": "StorageV2",
"sku": {
"name": "Standard_LRS",
"tier": "Standard"
},
"properties": {
"allowBlobPublicAccess": true,
"encryption": {
"services": {
"blob": {
"enabled": true
}
},
"keySource": "Microsoft.Storage"
},
"supportsHttpsTrafficOnly": true
}
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices",
"apiVersion": "2019-04-01",
"name": "[concat(variables('storageAccountName'), '/default')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
]
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2019-04-01",
"name": "[concat(variables('storageAccountName'),'/default/',variables('storageBlobContainerName'))]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('storageAccountName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"properties": {
"publicAccess": "Blob"
}
},
{
"type": "Microsoft.ManagedIdentity/userAssignedIdentities",
"apiVersion": "2018-11-30",
"name": "[variables('userAssignedIdentityName')]",
"location": "[resourceGroup().location]"
},
{
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2020-04-01-preview",
"name": "[variables('roleAssignmentName')]",
"dependsOn": [ "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('userAssignedIdentityName'))]" ],
"properties": {
"roleDefinitionId": "[variables('contributorRoleDefinitionId')]",
"principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('userAssignedIdentityName')), '2015-08-31-preview').principalId]",
"scope": "[resourceGroup().id]",
"principalType": "ServicePrincipal"
}
},
{
"type": "Microsoft.Resources/deploymentScripts",
"apiVersion": "2020-10-01",
"name": "[variables('deploymentScriptName')]",
"location": "[resourceGroup().location]",
"kind": "AzurePowerShell",
"dependsOn": [
"[resourceId('Microsoft.Authorization/roleAssignments', variables('roleAssignmentName'))]",
"[resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', variables('storageAccountName'), 'default', variables('storageBlobContainerName'))]"
],
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',variables('userAssignedIdentityName'))]": {}
}
},
"properties": {
"arguments": "[concat( '-File ', variables('singleQuote'), string(parameters('filesToCopy')), variables('singleQuote'))]",
"environmentVariables": [
{
"name": "ResourceGroupName",
"value": "[resourceGroup().name]"
},
{
"name": "StorageAccountName",
"value": "[variables('storageAccountName')]"
},
{
"name": "StorageContainerName",
"value": "[variables('storageBlobContainerName')]"
}
],
"azPowerShellVersion": "3.0",
"scriptContent": "
param([string]$File)
$fileList = $File -replace '(\[|\])' -split ',' | ForEach-Object { $_.trim() }
$storageAccount = Get-AzStorageAccount -ResourceGroupName $env:ResourceGroupName -Name $env:StorageAccountName -Verbose
$count = 0
$DeploymentScriptOutputs = @{}
foreach ($fileName in $fileList) {
Write-Host \"Copying $fileName to $env:StorageContainerName in $env:StorageAccountName.\"
Invoke-RestMethod -Uri \"https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/mslearn-arm-deploymentscripts-sample/$fileName\" -OutFile $fileName
$blob = Set-AzStorageBlobContent -File $fileName -Container $env:StorageContainerName -Blob $fileName -Context $storageAccount.Context
$DeploymentScriptOutputs[$fileName] = @{}
$DeploymentScriptOutputs[$fileName]['Uri'] = $blob.ICloudBlob.Uri
$DeploymentScriptOutputs[$fileName]['StorageUri'] =$blob.ICloudBlob.StorageUri
$count++
}
Write-Host \"Finished copying $count files.\"
",
"retentionInterval": "P1D"
}
}
],
"outputs": {
"fileUri": {
"type": "object",
"value": "[reference(variables('deploymentScriptName')).outputs]"
},
"storageAccountName": {
"type": "string",
"value": "[variables('storageAccountName')]"
}
}
}
@description('List of files to copy to application storage account.')
param filesToCopy array = [
'appsettings.json'
]
var storageAccountName = 'storage${uniqueString(resourceGroup().id)}'
var storageBlobContainerName = 'config'
var userAssignedIdentityName = 'configDeployer'
var roleAssignmentName = guid(resourceGroup().id, 'contributor')
var contributorRoleDefinitionId = resourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
var deploymentScriptName = 'CopyConfigScript'
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: storageAccountName
tags: {
displayName: storageAccountName
}
location: resourceGroup().location
kind: 'StorageV2'
sku: {
name: 'Standard_LRS'
tier: 'Standard'
}
properties: {
allowBlobPublicAccess: true
encryption: {
services: {
blob: {
enabled: true
}
}
keySource: 'Microsoft.Storage'
}
supportsHttpsTrafficOnly: true
}
resource blobService 'blobServices' existing = {
name: 'default'
}
}
resource blobContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2019-04-01' = {
parent: storageAccount::blobService
name: storageBlobContainerName
properties: {
publicAccess: 'Blob'
}
}
resource userAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = {
name: userAssignedIdentityName
location: resourceGroup().location
}
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = {
name: roleAssignmentName
properties: {
roleDefinitionId: contributorRoleDefinitionId
principalId: userAssignedIdentity.properties.principalId
principalType: 'ServicePrincipal'
}
}
resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
name: deploymentScriptName
location: resourceGroup().location
kind: 'AzurePowerShell'
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${userAssignedIdentity.id}': {}
}
}
properties: {
arguments: '-File \'${string(filesToCopy)}\''
environmentVariables: [
{
name: 'ResourceGroupName'
value: resourceGroup().name
}
{
name: 'StorageAccountName'
value: storageAccountName
}
{
name: 'StorageContainerName'
value: storageBlobContainerName
}
]
azPowerShellVersion: '3.0'
scriptContent: '''
param([string]$File)
$fileList = $File -replace '(\[|\])' -split ',' | ForEach-Object { $_.trim() }
$storageAccount = Get-AzStorageAccount -ResourceGroupName $env:ResourceGroupName -Name $env:StorageAccountName -Verbose
$count = 0
$DeploymentScriptOutputs = @{}
foreach ($fileName in $fileList) {
Write-Host "Copying $fileName to $env:StorageContainerName in $env:StorageAccountName."
Invoke-RestMethod -Uri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/mslearn-arm-deploymentscripts-sample/$fileName" -OutFile $fileName
$blob = Set-AzStorageBlobContent -File $fileName -Container $env:StorageContainerName -Blob $fileName -Context $storageAccount.Context
$DeploymentScriptOutputs[$fileName] = @{}
$DeploymentScriptOutputs[$fileName]['Uri'] = $blob.ICloudBlob.Uri
$DeploymentScriptOutputs[$fileName]['StorageUri'] = $blob.ICloudBlob.StorageUri
$count++
}
Write-Host "Finished copying $count files."
'''
retentionInterval: 'P1D'
}
dependsOn: [
roleAssignment
blobContainer
]
}
output fileUri object = deploymentScript.properties.outputs
output storageAccountName string = storageAccountName
如果不是,请复制示例或调整模板以与该示例一致。
创建参数文件
现在,你已设置好模板,接下来可以使用指定了新文件的参数文件来验证新的部署脚本。
手动创建 azuredeploy.parameters.json 文件或使用 VS Code 扩展来执行此操作。
编辑文件以指定两个
filesToCopy
:{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "filesToCopy": { "value": [ "swagger.Staging.json", "appsettings.Staging.json" ] } } }
创建 azuredeploy.parameters.json 文件。
编辑文件以指定两个
filesToCopy
:{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "filesToCopy": { "value": [ "swagger.Staging.json", "appsettings.Staging.json" ] } } }
部署模板
为此练习创建资源组
你需要创建一个资源组,使其包含将在本练习中创建的资源。 通过使用新的资源组,可在练习后更轻松地进行清理。
在 Visual Studio Code 的终端中运行以下命令,为此练习创建资源组。
resourceGroupName="learndeploymentscript_exercise_2"
az group create --location eastus --name $resourceGroupName
$resourceGroupName = 'learndeploymentscript_exercise_2'
New-AzResourceGroup -Location eastus -Name $resourceGroupName
将模板部署到 Azure
在 Visual Studio Code 终端中使用 Azure CLI 命令部署模板。
templateFile="azuredeploy.json"
templateParameterFile="azuredeploy.parameters.json"
today=$(date +"%d-%b-%Y")
deploymentName="deploymentscript-"$today
az deployment group create \
--resource-group $resourceGroupName \
--name $deploymentName \
--template-file $templateFile \
--parameters $templateParameterFile
将模板部署到 Azure
在终端中使用 Azure PowerShell 命令部署模板。
$templateFile = 'azuredeploy.json'
$templateParameterFile = 'azuredeploy.parameters.json'
$today = Get-Date -Format 'MM-dd-yyyy'
$deploymentName = "deploymentscript-$today"
New-AzResourceGroupDeployment `
-ResourceGroupName $resourceGroupName `
-Name $deploymentName `
-TemplateFile $templateFile `
-TemplateParameterFile $templateParameterFile
将模板部署到 Azure
在 Visual Studio Code 终端中使用 Azure CLI 命令部署模板。
templateFile="main.bicep"
templateParameterFile="azuredeploy.parameters.json"
today=$(date +"%d-%b-%Y")
deploymentName="deploymentscript-"$today
az deployment group create \
--resource-group $resourceGroupName \
--name $deploymentName \
--template-file $templateFile \
--parameters $templateParameterFile
将模板部署到 Azure
在终端中使用 Azure PowerShell 命令部署模板。
$templateFile = 'main.bicep'
$templateParameterFile = 'azuredeploy.parameters.json'
$today = Get-Date -Format 'MM-dd-yyyy'
$deploymentName = "deploymentscript-$today"
New-AzResourceGroupDeployment `
-ResourceGroupName $resourceGroupName `
-Name $deploymentName `
-TemplateFile $templateFile `
-TemplateParameterFile $templateParameterFile
查看模板结果
部署完成后,可通过列出 Blob 容器的内容来验证这两个文件是否已复制到存储帐户。
列出 Blob 容器的内容。
storageAccountName=$(az deployment group show --resource-group $resourceGroupName --name $deploymentName --query 'properties.outputs.storageAccountName.value' --output tsv) az storage blob list --account-name $storageAccountName --container-name config --query '[].name'
命令会返回以下代码:
[ "swagger.Staging.json", "appsettings.Staging.json" ]
还可以通过 Azure 门户或使用以下命令查看日志(以及有关部署的其他详细信息)。
az deployment-scripts show-log --resource-group $resourceGroupName --name CopyConfigScript
列出 Blob 容器的内容。
$storageAccountName = (Get-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName).Outputs.storageAccountName.Value $storageAccount = Get-AzStorageAccount -ResourceGroupName $resourceGroupName Get-AzStorageBlob -Context $storageAccount.Context -Container config | Select-Object Name
命令会返回以下代码:
Name ---- swagger.Staging.json appsettings.Staging.json
还可以通过 Azure 门户或使用以下命令查看日志(以及有关部署的其他详细信息)。
Get-AzDeploymentScriptLog -ResourceGroupName $resourceGroupName -Name CopyConfigScript
清理资源组
你已成功使用部署脚本部署 ARM 模板,并使用不同的方法来传入数据以自定义其行为。 接下来,可以删除包含已创建的所有资源和角色分配的资源组。
az group delete --name $resourceGroupName
Remove-AzResourceGroup -Name $resourceGroupName