Exercício - Adicionar parâmetros aos scripts de implantação
Agora que você usou um script de implantação para migrar algum trabalho manual para seu modelo do Azure Resource Manager (ARM), outra equipe de aplicativos parceiros em sua organização pediu ajuda.
O processo da equipe tem requisitos semelhantes, mas a equipe precisa implantar vários arquivos em sua conta de armazenamento. A equipe tem um script do PowerShell que pode usar uma lista de arquivos como parâmetro e carregá-los, semelhante ao script que você já estava usando em seu modelo.
Neste exercício, você tomará seu modelo anterior como ponto de partida e atualizará o script do PowerShell para usar o da sua equipe de parceiros. Em seguida, você adicionará uma maneira de permitir que a pessoa que está implantando o modelo especifique quais arquivos de configuração implantar (um ou mais).
Durante o processo, você:
- Atualize o script de implantação.
- Adicione uma variável de ambiente e um parâmetro de modelo e passe-os para o script de implantação.
- Adicione uma saída ao script de implantação.
- Adicione um arquivo de parâmetros.
- Implante o modelo e verifique o resultado.
Criar o modelo inicial
Você começa com o modelo que criou no último exercício.
Abra o Visual Studio Code e crie um novo ficheiro chamado azuredeploy.json.
Copie o seguinte modelo inicial para 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]" } } }
Guarde o modelo.
Abra o Visual Studio Code e crie um novo arquivo chamado main.bicep.
Copie o seguinte modelo inicial para 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
Guarde o modelo.
Atualizar o script do PowerShell
Como a outra equipe fez o trabalho árduo na criação de um script do PowerShell para copiar vários arquivos, você decide usar esse script em seu modelo.
Edite scriptContent
na properties
seção para incluir o script que sua equipe de parceiros forneceu.
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."
Adicionar uma variável de ambiente
O script adotado requer algumas variáveis de ambiente. Você pode especificá-los diretamente no modelo, mas será mais flexível usar funções de modelo para obter alguns dos valores.
Adicione uma
environmentVariables
propriedade àproperties
seção do script de implantação."environmentVariables": [ ],
Adicione uma variável de ambiente para
ResourceGroupName
."environmentVariables": [ { "name": "ResourceGroupName", "value": "[resourceGroup().name]" } ],
Adicione uma variável de ambiente para
StorageAccountName
."environmentVariables": [ { "name": "ResourceGroupName", "value": "[resourceGroup().name]" }, { "name": "StorageAccountName", "value": "[variables('storageAccountName')]" } ],
Adicione uma variável de ambiente para
StorageContainerName
."environmentVariables": [ { "name": "ResourceGroupName", "value": "[resourceGroup().name]" }, { "name": "StorageAccountName", "value": "[variables('storageAccountName')]" }, { "name": "StorageContainerName", "value": "[variables('storageBlobContainerName')]" } ],
Gorjeta
Use funções de modelo para acessar valores comuns como [resourceGroup().name]
e [variables()]
.
O script adotado requer algumas variáveis de ambiente. Você pode especificá-los diretamente no modelo, mas será mais flexível usar variáveis do Bíceps para obter alguns dos valores.
Adicione uma
environmentVariables
propriedade àproperties
seção do script de implantação.environmentVariables: [ ]
Adicione uma variável de ambiente para
ResourceGroupName
.environmentVariables: [ { name: 'ResourceGroupName' value: resourceGroup().name } ]
Adicione uma variável de ambiente para
StorageAccountName
.environmentVariables: [ { name: 'ResourceGroupName' value: resourceGroup().name } { name: 'StorageAccountName' value: storageAccountName } ]
Adicione uma variável de ambiente para
StorageContainerName
.environmentVariables: [ { name: 'ResourceGroupName' value: resourceGroup().name } { name: 'StorageAccountName' value: storageAccountName } { name: 'StorageContainerName' value: storageBlobContainerName } ]
Adicionar um parâmetro de modelo
Para facilitar o uso do modelo pelas duas equipes, você pode adicionar um parâmetro ao modelo para que cada equipe possa especificar os arquivos que deseja copiar.
Adicione um parâmetro ao modelo para obter uma matriz de nomes de arquivos.
"parameters": {
"filesToCopy": {
"type": "array",
"metadata": {
"description": "List of files to copy to application storage account."
}
}
},
Como bônus, você pode fornecer um valor padrão para que o modelo continue a trabalhar para sua equipe sem alterações no processo de implantação. Embora não seja obrigatório, inserir um novo valor padrão pode ajudá-lo a entender o padrão de tornar mais fácil para as equipes adotarem novas versões de modelos se continuarem a se comportar como antes, com a nova funcionalidade sendo a recompensa. Em outras palavras, esta etapa mostra como manter o comportamento existente enquanto faz as alterações para dar suporte ao trabalho futuro.
Adicione um parâmetro ao modelo para obter uma matriz de nomes de arquivos.
@description('List of files to copy to application storage account.')
param filesToCopy array
Como bônus, você pode fornecer um valor padrão para que o modelo continue a trabalhar para sua equipe sem alterações no processo de implantação. Embora não seja obrigatório, inserir um novo valor padrão pode ajudá-lo a entender o padrão de tornar mais fácil para as equipes adotarem novas versões de modelos se continuarem a se comportar como antes, com a nova funcionalidade sendo a recompensa. Em outras palavras, esta etapa mostra como manter o comportamento existente enquanto faz as alterações para dar suporte ao trabalho futuro.
Adicionar um argumento para passar os arquivos a serem copiados
Em seguida, você pode pegar o parâmetro que acabou de definir e passá-lo para o script de implantação. Passar argumentos de linha de comando pode ser complicado, porque as cadeias de caracteres são avaliadas em vários níveis. Escapar adequadamente das cotações e escolher as cotações certas para o trabalho são essenciais para o sucesso.
Gorjeta
Use funções de modelo para acessar funções comuns, como [string()]
converter valores de um tipo em uma cadeia de caracteres.
Adicione uma
arguments
propriedade ao script de implantação. O script do PowerShell usa um parâmetro chamadoFile
, que é uma cadeia de nomes de arquivos que deve vir dofilesToCopy
parâmetro template. Certifique-se de que há citações em torno de todo o argumento para que ele seja passado corretamente.Atenção
Esta
arguments
propriedade é inválida. Se você estiver usando a extensão do Azure Resource Manager no Visual Studio Code, ela poderá sinalizar essa linha. Você corrigirá esse problema nas próximas etapas."arguments": "[concat( '-File '', string(parameters('filesToCopy')), ''' )]",
Gorjeta
Citar coisas em JSON pode ser difícil, especialmente quando você está passando argumentos de linha de comando. Você pode usar uma variável de modelo para representar um caractere difícil de escapar.
Adicione uma variável de modelo para representar o caractere de aspas simples.
"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" },
Substitua as aspas simples na
arguments
propriedade pela variável que você acabou de definir."arguments": "[concat( '-File ', variables('singleQuote'), string(parameters('filesToCopy')), variables('singleQuote'))]",
Em seguida, você pode pegar o parâmetro que acabou de definir e passá-lo para o script de implantação. Passar argumentos de linha de comando pode ser complicado, porque as cadeias de caracteres são avaliadas em vários níveis. Escapar adequadamente das cotações e escolher as cotações certas para o trabalho são essenciais para o sucesso.
Adicione uma arguments
propriedade ao script de implantação. O script do PowerShell usa um parâmetro chamado File
, que é uma cadeia de nomes de arquivos que deve vir do filesToCopy
parâmetro template.
arguments: '-File \'${string(filesToCopy)}\''
Observe que isso usa vários recursos do Bíceps:
- Interpolação de cordas, para combinar as cadeias de caracteres.
- Usamos o
\
caractere escape para nos permitir incluir um caractere de aspas ('
) dentro da string, porque uma única citação é normalmente um caractere reservado no Bicep. - Usamos a função para converter a
string()
filesToCopy
matriz em uma cadeia de caracteres.
Atualizar a saída do modelo
Como você está alterando o script de implantação para implantar um ou mais arquivos, precisa atualizar a saída do modelo para fornecer todas as informações necessárias.
Atualize o
outputs
no modelo para retornar o objeto inteiro, que terá um URI por arquivo.$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++ }
Adicione outra saída com o nome da conta de armazenamento (que tem um identificador aleatório). Você usará isso mais tarde para validar se o script de implantação fez o esperado.
$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++ }
Atualize as saídas no modelo para retornar o objeto inteiro, que terá um URI por arquivo.
output fileUri object = deploymentScript.properties.outputs
Adicione outra saída com o nome da conta de armazenamento (que tem um identificador aleatório). Você usará isso mais tarde para validar se o script de implantação fez o esperado.
output storageAccountName string = storageAccountName
Verificar o modelo
O modelo deverá ter um aspeto semelhante ao seguinte:
{
"$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
Caso contrário, copie o exemplo ou ajuste o modelo para corresponder ao exemplo.
Criar um arquivo de parâmetros
Agora que você tem o conjunto de modelos, pode validar o novo script de implantação usando um arquivo de parâmetros com novos arquivos especificados.
Crie um arquivo azuredeploy.parameters.json manualmente ou use a extensão VS Code para fazer isso.
Edite o arquivo para que dois
filesToCopy
sejam especificados:{ "$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" ] } } }
Crie um arquivo azuredeploy.parameters.json .
Edite o arquivo para que dois
filesToCopy
sejam especificados:{ "$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" ] } } }
Implementar o modelo
Criar um grupo de recursos para o exercício
Você precisa criar um grupo de recursos para conter os recursos que você criará como parte deste exercício. Ao usar um novo grupo de recursos, você tornará a limpeza após o exercício muito mais fácil.
No terminal no Visual Studio Code, execute este comando para criar o grupo de recursos para este exercício.
resourceGroupName="learndeploymentscript_exercise_2"
az group create --location eastus --name $resourceGroupName
$resourceGroupName = 'learndeploymentscript_exercise_2'
New-AzResourceGroup -Location eastus -Name $resourceGroupName
Implementar o modelo no Azure
Implemente o modelo através dos comandos da CLI do Azure no terminal do Visual Studio Code.
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
Implementar o modelo no Azure
Implemente o modelo com os comandos do Azure PowerShell no terminal.
$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
Implementar o modelo no Azure
Implemente o modelo através dos comandos da CLI do Azure no terminal do Visual Studio Code.
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
Implementar o modelo no Azure
Implemente o modelo com os comandos do Azure PowerShell no terminal.
$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
Rever o resultado do seu modelo
Após a conclusão da implantação, você pode validar que ambos os arquivos foram copiados para sua conta de armazenamento listando o conteúdo do contêiner de blob.
Liste o conteúdo do contêiner de 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'
O comando retorna o seguinte código:
[ "swagger.Staging.json", "appsettings.Staging.json" ]
Você também pode revisar os logs (e outros detalhes sobre a implantação) no portal do Azure ou usando o comando a seguir.
az deployment-scripts show-log --resource-group $resourceGroupName --name CopyConfigScript
Liste o conteúdo do contêiner de 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
O comando retorna o seguinte código:
Name ---- swagger.Staging.json appsettings.Staging.json
Você também pode revisar os logs (e outros detalhes sobre a implantação) no portal do Azure ou usando o comando a seguir.
Get-AzDeploymentScriptLog -ResourceGroupName $resourceGroupName -Name CopyConfigScript
Limpar o grupo de recursos
Você implantou com êxito um modelo ARM com um script de implantação e usou métodos diferentes para passar dados para personalizar seu comportamento. Você pode remover o grupo de recursos que contém todos os recursos e atribuições de função que você criou.
az group delete --name $resourceGroupName
Remove-AzResourceGroup -Name $resourceGroupName