Cvičení – přidání parametrů do skriptů nasazení

Dokončeno

Teď, když jste k migraci ruční práce do šablony Azure Resource Manageru (ARM) použili skript nasazení, požádal jiný tým partnerských aplikací ve vaší organizaci o pomoc.

Proces týmu má podobné požadavky, ale tým musí do svého účtu úložiště nasadit více souborů. Tým má skript PowerShellu, který může jako parametr vzít seznam souborů a nahrát je, podobně jako skript, který jste už v šabloně používali.

V tomto cvičení použijete předchozí šablonu jako výchozí bod a aktualizujete skript PowerShellu tak, aby používal ten z partnerského týmu. Pak přidáte způsob, jak povolit uživateli, který šablonu nasazuje, a určit, jaké konfigurační soubory se mají nasadit (jeden nebo více).

Během tohoto procesu:

  • Aktualizujte skript nasazení.
  • Přidejte proměnnou prostředí a parametr šablony a předejte je do skriptu nasazení.
  • Přidejte výstup do skriptu nasazení.
  • Přidejte soubor parametrů.
  • Nasaďte šablonu a ověřte výsledek.

Vytvoření počáteční šablony

Začnete se šablonou, kterou jste vytvořili v posledním cvičení.

  1. Otevřete Visual Studio Code a vytvořte nový soubor s názvem azuredeploy.json.

  2. Zkopírujte následující počáteční šablonu do 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]"
            }
        }
    }
    
  3. Uložte šablonu.

  1. Otevřete Visual Studio Code a vytvořte nový soubor s názvem main.bicep.

  2. Zkopírujte následující počáteční šablonu do 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
    
  3. Uložte šablonu.

Aktualizace skriptu PowerShellu

Vzhledem k tomu, že druhý tým udělal tvrdou práci při vytváření skriptu PowerShellu pro kopírování více souborů, rozhodnete se tento skript použít ve své šabloně.

Upravte scriptContent ho properties v části tak, aby obsahoval skript, který vám poskytl partnerový tým.

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."

Přidání proměnné prostředí

Skript, který jste přijali, vyžaduje některé proměnné prostředí. Můžete je zadat přímo v šabloně, ale bude flexibilnější používat funkce šablony k získání některých hodnot.

  1. environmentVariables Přidejte vlastnost do properties části skriptu nasazení.

    "environmentVariables": [
    ],
    
  2. Přidejte proměnnou prostředí pro ResourceGroupName.

    "environmentVariables": [
        {
            "name": "ResourceGroupName",
            "value": "[resourceGroup().name]"
        }
    ],
    
  3. Přidejte proměnnou prostředí pro StorageAccountName.

    "environmentVariables": [
        {
            "name": "ResourceGroupName",
            "value": "[resourceGroup().name]"
        },
        {
            "name": "StorageAccountName",
            "value": "[variables('storageAccountName')]"
        }
    ],
    
  4. Přidejte proměnnou prostředí pro StorageContainerName.

    "environmentVariables": [
        {
            "name": "ResourceGroupName",
            "value": "[resourceGroup().name]"
        },
        {
            "name": "StorageAccountName",
            "value": "[variables('storageAccountName')]"
        },
        {
            "name": "StorageContainerName",
            "value": "[variables('storageBlobContainerName')]"
        }
    ],
    

Tip

Použití funkcí šablony pro přístup k běžným hodnotám jako [resourceGroup().name] a [variables()].

Skript, který jste přijali, vyžaduje některé proměnné prostředí. Můžete je zadat přímo v šabloně, ale bude flexibilnější použít proměnné Bicep k získání některých hodnot.

  1. environmentVariables Přidejte vlastnost do properties části skriptu nasazení.

    environmentVariables: [
    ]
    
  2. Přidejte proměnnou prostředí pro ResourceGroupName.

    environmentVariables: [
      {
        name: 'ResourceGroupName'
        value: resourceGroup().name
      }
    ]
    
  3. Přidejte proměnnou prostředí pro StorageAccountName.

    environmentVariables: [
      {
        name: 'ResourceGroupName'
        value: resourceGroup().name
      }
      {
        name: 'StorageAccountName'
        value: storageAccountName
      }
    ]
    
  4. Přidejte proměnnou prostředí pro StorageContainerName.

    environmentVariables: [
      {
        name: 'ResourceGroupName'
        value: resourceGroup().name
      }
      {
        name: 'StorageAccountName'
        value: storageAccountName
      }
      {
        name: 'StorageContainerName'
        value: storageBlobContainerName
      }
    ]
    

Přidání parametru šablony

Pokud chcete usnadnit použití šablony pro oba týmy, můžete do šablony přidat parametr, aby každý tým mohl určit soubory, které chce kopírovat.

Přidejte do šablony parametr, který převezme pole názvů souborů.

"parameters": {
    "filesToCopy": {
        "type": "array",
        "metadata": {
            "description": "List of files to copy to application storage account."
        }
    }
},

Jako bonus můžete zadat výchozí hodnotu, takže šablona bude i nadále fungovat pro váš tým beze změn procesu nasazení. I když to není povinné, zadání nové výchozí hodnoty vám pomůže pochopit způsob, jak týmům usnadnit přijímání nových verzí šablon, pokud se budou chovat stejně jako předtím, a nové funkce jsou odměnou. Jinými slovy, tento krok ukazuje, jak zachovat stávající chování při provádění změn podpory budoucí práce.

Přidejte do šablony parametr, který převezme pole názvů souborů.

@description('List of files to copy to application storage account.')
param filesToCopy array

Jako bonus můžete zadat výchozí hodnotu, takže šablona bude i nadále fungovat pro váš tým beze změn procesu nasazení. I když to není povinné, zadání nové výchozí hodnoty vám pomůže pochopit způsob, jak týmům usnadnit přijímání nových verzí šablon, pokud se budou chovat stejně jako předtím, a nové funkce jsou odměnou. Jinými slovy, tento krok ukazuje, jak zachovat stávající chování při provádění změn podpory budoucí práce.

Přidání argumentu pro předání souborů ke zkopírování

Dále můžete použít parametr, který jste právě definovali, a předat ho skriptu nasazení. Předávání argumentů příkazového řádku může být složité, protože řetězce se vyhodnocují na více úrovních. Správné uvozovky a výběr správných uvozovek pro úlohu jsou nezbytné pro úspěch.

Tip

Pomocí funkcí šablon můžete získat přístup k běžným funkcím, jako [string()] je převod hodnot jednoho typu na řetězec.

  1. arguments Přidejte do skriptu nasazení vlastnost. Skript PowerShellu přebírá parametr s názvem File, což je řetězec názvů souborů, které by měly pocházet z parametru filesToCopy šablony. Ujistěte se, že jsou kolem celého argumentu uvozovky, aby se správně předaly.

    Upozornění

    Tato arguments vlastnost je neplatná. Pokud v editoru Visual Studio Code používáte rozšíření Azure Resource Manager, může tento řádek označit příznakem. Tento problém vyřešíte v dalších krocích.

    "arguments": "[concat( '-File '', string(parameters('filesToCopy')), ''' )]",
    

    Tip

    Uvozování věcí ve formátu JSON může být obtížné, zejména když předáváte argumenty příkazového řádku. Proměnnou šablony můžete použít k reprezentaci znaku, který je obtížné utéct.

  2. Přidejte proměnnou šablony, která představuje znak jednoduché uvozovky.

    "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"
    },
    
  3. Nahraďte jednoduché uvozovky ve arguments vlastnosti proměnnou, kterou jste právě definovali.

    "arguments": "[concat( '-File ', variables('singleQuote'), string(parameters('filesToCopy')), variables('singleQuote'))]",
    

Dále můžete použít parametr, který jste právě definovali, a předat ho skriptu nasazení. Předávání argumentů příkazového řádku může být složité, protože řetězce se vyhodnocují na více úrovních. Správné uvozovky a výběr správných uvozovek pro úlohu jsou nezbytné pro úspěch.

arguments Přidejte do skriptu nasazení vlastnost. Skript PowerShellu přebírá parametr s názvem File, což je řetězec názvů souborů, které by měly pocházet z parametru filesToCopy šablony.

arguments: '-File \'${string(filesToCopy)}\''

Všimněte si, že používá několik funkcí Bicep:

  • Interpolace řetězců pro kombinování řetězců
  • Pomocí řídicího znaku \ můžeme do řetězce zahrnout jeden znak uvozovky ('), protože jedna uvozovka je obvykle vyhrazeným znakem v Bicep.
  • Pomocí string() funkce filesToCopy převedeme pole na řetězec.

Aktualizace výstupu šablony

Vzhledem k tomu, že měníte skript nasazení tak, aby nasadil jeden nebo více souborů, musíte aktualizovat výstup šablony tak, aby poskytoval všechny potřebné informace.

  1. outputs Aktualizujte šablonu tak, aby vrátila celý objekt, který bude mít identifikátor URI na soubor.

    $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++
    }
    
  2. Přidejte další výstup s názvem účtu úložiště (který má náhodný identifikátor). Později ho použijete k ověření, že skript nasazení udělal to, co jste očekávali.

    $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++
    }
    
  1. Aktualizujte výstupy v šabloně tak, aby vracely celý objekt, který bude mít identifikátor URI na soubor.

    output fileUri object = deploymentScript.properties.outputs
    
  2. Přidejte další výstup s názvem účtu úložiště (který má náhodný identifikátor). Později ho použijete k ověření, že skript nasazení udělal to, co jste očekávali.

    output storageAccountName string = storageAccountName
    

Ověření šablony

Vaše šablona by měla vypadat nějak takto:

{
    "$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

Pokud tomu tak není, zkopírujte příklad nebo upravte šablonu tak, aby odpovídala příkladu.

Vytvoření souboru parametrů

Teď, když máte sadu šablon, můžete nový skript nasazení ověřit pomocí souboru parametrů s novými zadanými soubory.

  1. Buď vytvořte azuredeploy.parameters.json soubor ručně, nebo k tomu použijte příponu VS Code.

  2. Upravte soubor tak, aby byl zadán dva 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"
                ]
            }
        }
    }
    
  1. Vytvořte soubor azuredeploy.parameters.json .

  2. Upravte soubor tak, aby byl zadán dva 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"
                ]
            }
        }
    }
    

Nasazení šablony

Vytvoření skupiny prostředků pro cvičení

V rámci tohoto cvičení musíte vytvořit skupinu prostředků, která bude obsahovat prostředky, které vytvoříte. Když použijete novou skupinu prostředků, usnadníte si vyčištění po cvičení.

V terminálu v editoru Visual Studio Code spusťte tento příkaz a vytvořte skupinu prostředků pro toto cvičení.

resourceGroupName="learndeploymentscript_exercise_2"
az group create --location eastus --name $resourceGroupName
$resourceGroupName = 'learndeploymentscript_exercise_2'
New-AzResourceGroup -Location eastus -Name $resourceGroupName

Nasazení šablony do Azure

Nasaďte šablonu pomocí příkazů Azure CLI v terminálu editoru 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

Nasazení šablony do Azure

Nasaďte šablonu pomocí příkazů Azure PowerShellu v terminálu.

$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

Nasazení šablony do Azure

Nasaďte šablonu pomocí příkazů Azure CLI v terminálu editoru 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

Nasazení šablony do Azure

Nasaďte šablonu pomocí příkazů Azure PowerShellu v terminálu.

$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

Kontrola výsledku šablony

Po dokončení nasazení můžete ověřit, že se oba soubory zkopírovaly do účtu úložiště výpisem obsahu kontejneru objektů blob.

  1. Vypíše obsah kontejneru objektů 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'
    

    Příkaz vrátí následující kód:

    [
      "swagger.Staging.json",
      "appsettings.Staging.json"
    ]
    
  2. Protokoly (a další podrobnosti o nasazení) můžete také zkontrolovat na webu Azure Portal nebo pomocí následujícího příkazu.

    az deployment-scripts show-log --resource-group $resourceGroupName --name CopyConfigScript
    
  1. Vypíše obsah kontejneru objektů 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
    

    Příkaz vrátí následující kód:

    Name
    ----
    swagger.Staging.json
    appsettings.Staging.json
    
  2. Protokoly (a další podrobnosti o nasazení) můžete také zkontrolovat na webu Azure Portal nebo pomocí následujícího příkazu.

    Get-AzDeploymentScriptLog -ResourceGroupName $resourceGroupName -Name CopyConfigScript
    

Vyčištění skupiny prostředků

Úspěšně jste nasadili šablonu ARM se skriptem nasazení a pomocí různých metod předali data a přizpůsobili jejich chování. Můžete odebrat skupinu prostředků, která obsahuje všechny prostředky a přiřazení rolí, které jste vytvořili.

az group delete --name $resourceGroupName
Remove-AzResourceGroup -Name $resourceGroupName