Übung: Hinzufügen von Parametern zu Bereitstellungsskripts

Abgeschlossen

Nachdem Sie nun ein Bereitstellungsskript verwendet haben, um manuelle Arbeiten in Ihre ARM-Vorlage (Azure Resource Manager) zu migrieren, hat ein anderes Partneranwendungsteam in Ihrer Organisation um Hilfe gebeten.

Der Prozess des Teams bringt ähnliche Anforderungen mit sich, das Team muss jedoch mehrere Dateien in seinem Speicherkonto bereitstellen. Das Team verfügt über ein PowerShell-Skript, mit dem eine Liste von Dateien als Parameter verwendet und hochgeladen werden kann, ähnlich wie bei dem Skript, das Sie bereits in Ihrer Vorlage verwendet haben.

In dieser Übung verwenden Sie die vorherige Vorlage als Ausgangspunkt und aktualisieren das PowerShell-Skript, um das Skript des Partnerteams zu verwenden. Anschließend fügen Sie eine Option hinzu, mit der die Person, die die Vorlage bereitstellt, angeben kann, welche Konfigurationsdateien bereitgestellt werden sollen (eine oder mehrere).

In dem Prozess gehen Sie wie folgt vor:

  • Aktualisieren Sie das Bereitstellungsskript.
  • Fügen Sie eine Umgebungsvariable und einen Vorlagenparameter hinzu, und übergeben Sie diese an Ihr Bereitstellungsskript.
  • Fügen Sie dem Bereitstellungsskript eine Ausgabe hinzu.
  • Fügen Sie eine Parameterdatei hinzu.
  • Stellen Sie die Vorlage bereit, und überprüfen Sie das Ergebnis.

Erstellen der anfänglichen Vorlage

Sie verwenden die Vorlage, die Sie in der letzten Übung erstellt haben.

  1. Öffnen Sie Visual Studio Code, und erstellen Sie eine neue Datei namens azuredeploy.json.

  2. Kopieren Sie die folgende Startvorlage in 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. Speichern Sie die Vorlage.

  1. Öffnen Sie Visual Studio Code, und erstellen Sie eine neue Datei mit dem Namen main.bicep.

  2. Kopieren Sie die folgende Startvorlage in 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. Speichern Sie die Vorlage.

Aktualisieren des PowerShell-Skripts

Da das andere Team die Arbeit übernommen hat, ein PowerShell-Skript zum Kopieren mehrerer Dateien zu erstellen, entscheiden Sie sich, dieses Skript in Ihrer Vorlage zu verwenden.

Bearbeiten Sie scriptContent im Abschnitt properties, um das Skript einzufügen, das Ihr Partnerteam bereitgestellt hat.

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

Hinzufügen einer Umgebungsvariablen

Für das Skript, das Sie übernommen haben, sind einige Umgebungsvariablen erforderlich. Sie können sie direkt in der Vorlage angeben. Es ist jedoch flexibler, Vorlagenfunktionen zum Abrufen einiger Werte zu verwenden.

  1. Fügen Sie dem Abschnitt properties des Bereitstellungsskripts die Eigenschaft environmentVariables hinzu.

    "environmentVariables": [
    ],
    
  2. Fügen Sie eine Umgebungsvariable für ResourceGroupName hinzu.

    "environmentVariables": [
        {
            "name": "ResourceGroupName",
            "value": "[resourceGroup().name]"
        }
    ],
    
  3. Fügen Sie eine Umgebungsvariable für StorageAccountName hinzu.

    "environmentVariables": [
        {
            "name": "ResourceGroupName",
            "value": "[resourceGroup().name]"
        },
        {
            "name": "StorageAccountName",
            "value": "[variables('storageAccountName')]"
        }
    ],
    
  4. Fügen Sie eine Umgebungsvariable für StorageContainerName hinzu.

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

Tipp

Verwenden Sie Vorlagenfunktionen, um auf allgemeine Werte wie [resourceGroup().name] und [variables()] zuzugreifen.

Für das Skript, das Sie übernommen haben, sind einige Umgebungsvariablen erforderlich. Sie können sie direkt in der Vorlage angeben. Es ist jedoch flexibler, Bicep-Variablen zum Abrufen einiger Werte zu verwenden.

  1. Fügen Sie dem Abschnitt properties des Bereitstellungsskripts die Eigenschaft environmentVariables hinzu.

    environmentVariables: [
    ]
    
  2. Fügen Sie eine Umgebungsvariable für ResourceGroupName hinzu.

    environmentVariables: [
      {
        name: 'ResourceGroupName'
        value: resourceGroup().name
      }
    ]
    
  3. Fügen Sie eine Umgebungsvariable für StorageAccountName hinzu.

    environmentVariables: [
      {
        name: 'ResourceGroupName'
        value: resourceGroup().name
      }
      {
        name: 'StorageAccountName'
        value: storageAccountName
      }
    ]
    
  4. Fügen Sie eine Umgebungsvariable für StorageContainerName hinzu.

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

Hinzufügen eines Vorlagenparameters

Um die Verwendung der Vorlage für die beiden Teams zu vereinfachen, können Sie der Vorlage einen Parameter hinzufügen, damit jedes Team die Dateien angeben kann, die kopiert werden sollen.

Fügen Sie der Vorlage einen Parameter hinzu, um ein Array von Dateinamen zu verwenden.

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

Zusätzlich können Sie einen Standardwert angeben, damit die Vorlage für Ihr Team weiterhin genutzt werden kann, ohne dass Änderungen am Bereitstellungsprozess vorgenommen werden müssen. Die Eingabe eines neuen Standardwerts ist zwar nicht erforderlich, kann Ihnen aber helfen, das Muster zu verstehen, mit dem es für Teams einfacher wird, neue Versionen von Vorlagen zu übernehmen, wenn sie sich weiterhin so verhalten wie bisher. Dabei stehen jedoch neue Funktionen zur Verfügung. Mit anderen Worten: In diesem Schritt erfahren Sie, wie Sie das vorhandene Verhalten beibehalten und gleichzeitig Änderungen vornehmen, um zukünftige Arbeiten zu ermöglichen.

Fügen Sie der Vorlage einen Parameter hinzu, um ein Array von Dateinamen zu verwenden.

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

Zusätzlich können Sie einen Standardwert angeben, damit die Vorlage für Ihr Team weiterhin genutzt werden kann, ohne dass Änderungen am Bereitstellungsprozess vorgenommen werden müssen. Die Eingabe eines neuen Standardwerts ist zwar nicht erforderlich, kann Ihnen aber helfen, das Muster zu verstehen, mit dem es für Teams einfacher wird, neue Versionen von Vorlagen zu übernehmen, wenn sie sich weiterhin so verhalten wie bisher. Dabei stehen jedoch neue Funktionen zur Verfügung. Mit anderen Worten: In diesem Schritt erfahren Sie, wie Sie das vorhandene Verhalten beibehalten und gleichzeitig Änderungen vornehmen, um zukünftige Arbeiten zu ermöglichen.

Hinzufügen eines Arguments zur Übergabe von zu kopierenden Dateien

Als Nächstes können Sie den gerade definierten Parameter an das Bereitstellungsskript übergeben. Das Übergeben von Befehlszeilenargumenten kann schwierig sein, da die Zeichenfolgen auf mehreren Ebenen ausgewertet werden. Das ordnungsgemäße Setzen von Anführungszeichen und das Auswählen der richtigen Anführungszeichen für den Vorgang sind für eine erfolgreiche Durchführung von entscheidender Bedeutung.

Tipp

Verwenden Sie Vorlagenfunktionen, um auf allgemeine Funktionen wie [string()] zuzugreifen und die Werte eines Typs in eine Zeichenfolge zu konvertieren.

  1. Fügen Sie dem Bereitstellungsskript die Eigenschaft arguments hinzu. Das PowerShell-Skript verwendet einen Parameter namens File, bei dem es sich um eine Zeichenfolge von Dateinamen handelt, die aus dem Vorlagenparameter filesToCopy stammen sollten. Stellen Sie sicher, dass Anführungszeichen um das gesamte Argument gesetzt wurden, damit es ordnungsgemäß übergeben wird.

    Achtung

    Die Eigenschaft arguments ist ungültig. Wenn Sie die Azure Resource Manager-Erweiterung in Visual Studio Code verwenden, wird diese Zeile möglicherweise gekennzeichnet. Sie beheben dieses Problem im Folgenden.

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

    Tipp

    Das Setzen von Anführungszeichen in JSON kann sich als schwierig erweisen, insbesondere wenn Sie Befehlszeilenargumente übergeben. Sie können eine Vorlagenvariable nutzen, um ein Zeichen darzustellen, das schwer mit einem Escapezeichen zu versehen ist.

  2. Fügen Sie eine Vorlagenvariable hinzu, um das einfache Anführungszeichen darzustellen.

    "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. Ersetzen Sie die einfachen Anführungszeichen in der Eigenschaft arguments mit der gerade definierten Variable.

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

Als Nächstes können Sie den gerade definierten Parameter an das Bereitstellungsskript übergeben. Das Übergeben von Befehlszeilenargumenten kann schwierig sein, da die Zeichenfolgen auf mehreren Ebenen ausgewertet werden. Das ordnungsgemäße Setzen von Anführungszeichen und das Auswählen der richtigen Anführungszeichen für den Vorgang sind für eine erfolgreiche Durchführung von entscheidender Bedeutung.

Fügen Sie dem Bereitstellungsskript die Eigenschaft arguments hinzu. Das PowerShell-Skript verwendet einen Parameter namens File, bei dem es sich um eine Zeichenfolge von Dateinamen handelt, die aus dem Vorlagenparameter filesToCopy stammen sollten.

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

Beachten Sie, dass hierbei mehrere Bicep-Features verwendet werden:

  • Die Zeichenfolgeninterpolation (zum Kombinieren der Zeichenfolgen).
  • Wir verwenden das Escapezeichen \, um ein einzelnes Anführungszeichen (') in die Zeichenfolge einzuschließen, da ein einfaches Anführungszeichen in Bicep normalerweise ein reserviertes Zeichen ist.
  • Wir verwenden die Funktion string(), um das Array filesToCopy in eine Zeichenfolge zu konvertieren.

Aktualisieren der Vorlagenausgabe

Da Sie das Bereitstellungsskript so ändern, dass mindestens eine Datei bereitgestellt wird, müssen Sie die Vorlagenausgabe aktualisieren, um alle erforderlichen Informationen bereitzustellen.

  1. Aktualisieren Sie die outputs in der Vorlage, um das gesamte Objekt zurückzugeben, das über einen URI pro Datei verfügt.

    $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. Fügen Sie eine weitere Ausgabe mit dem Namen des Speicherkontos hinzu (der über einen zufälligen Bezeichner verfügt). Sie verwenden diese später, um zu überprüfen, ob das Bereitstellungsskript sich wie erwartet verhält.

    $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. Aktualisieren Sie die Ausgaben in der Vorlage, um das gesamte Objekt zurückzugeben, das über einen URI pro Datei verfügt.

    output fileUri object = deploymentScript.properties.outputs
    
  2. Fügen Sie eine weitere Ausgabe mit dem Namen des Speicherkontos hinzu (der über einen zufälligen Bezeichner verfügt). Sie verwenden diese später, um zu überprüfen, ob das Bereitstellungsskript sich wie erwartet verhält.

    output storageAccountName string = storageAccountName
    

Überprüfen der Vorlage

Die Vorlage sollte in etwa wie folgt aussehen:

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

Andernfalls kopieren Sie das Beispiel, oder passen Sie Ihre Vorlage an das Beispiel an.

Erstellen einer Parameterdatei

Da Sie nun über den Vorlagensatz verfügen, können Sie das neue Bereitstellungsskript überprüfen, indem Sie eine Parameterdatei mit angegebenen neuen Dateien verwenden.

  1. Erstellen Sie entweder manuell eine azuredeploy.parameters.json-Datei, oder verwenden Sie dazu die VS Code-Erweiterung.

  2. Bearbeiten Sie die Datei so, dass zwei filesToCopy angegeben sind:

    {
        "$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. Erstellen Sie eine azuredeploy.parameters.json-Datei.

  2. Bearbeiten Sie die Datei so, dass zwei filesToCopy angegeben sind:

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

Bereitstellen der Vorlage

Erstellen einer Ressourcengruppe für die Übung

Sie müssen eine Ressourcengruppe erstellen, die die Ressourcen enthält, die Sie im Rahmen dieser Übung erstellen. Wenn Sie eine neue Ressourcengruppe verwenden, vereinfachen Sie die Bereinigung nach der Übung erheblich.

Führen Sie im Terminal in Visual Studio Code den folgenden Befehl aus, um die Ressourcengruppe für diese Übung zu erstellen.

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

Bereitstellen der Vorlage in Azure

Stellen Sie die Vorlage mithilfe von Azure CLI-Befehlen im Visual Studio Code-Terminal bereit.

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

Bereitstellen der Vorlage in Azure

Stellen Sie die Vorlage mithilfe von Azure PowerShell-Befehle im Terminal bereit.

$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

Bereitstellen der Vorlage in Azure

Stellen Sie die Vorlage mithilfe von Azure CLI-Befehlen im Visual Studio Code-Terminal bereit.

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

Bereitstellen der Vorlage in Azure

Stellen Sie die Vorlage mithilfe von Azure PowerShell-Befehle im Terminal bereit.

$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

Überprüfen des Ergebnisses Ihrer Vorlage

Nach Abschluss der Bereitstellung können Sie überprüfen, ob beide Dateien in Ihr Speicherkonto kopiert wurden, indem Sie den Inhalt des Blobcontainers auflisten.

  1. Listen Sie den Inhalt des Blobcontainers auf.

    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'
    

    Der Befehl gibt den folgenden Code zurück:

    [
      "swagger.Staging.json",
      "appsettings.Staging.json"
    ]
    
  2. Sie können auch die Protokolle (und andere Details zur Bereitstellung) über das Azure-Portal oder mithilfe des folgenden Befehls überprüfen.

    az deployment-scripts show-log --resource-group $resourceGroupName --name CopyConfigScript
    
  1. Listen Sie den Inhalt des Blobcontainers auf.

    $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
    

    Der Befehl gibt den folgenden Code zurück:

    Name
    ----
    swagger.Staging.json
    appsettings.Staging.json
    
  2. Sie können auch die Protokolle (und andere Details zur Bereitstellung) über das Azure-Portal oder mithilfe des folgenden Befehls überprüfen.

    Get-AzDeploymentScriptLog -ResourceGroupName $resourceGroupName -Name CopyConfigScript
    

Bereinigen der Ressourcengruppe

Sie haben eine ARM-Vorlage erfolgreich mit einem Bereitstellungsskript bereitgestellt und verschiedene Methoden zum Übergeben von Daten verwendet, um ihr Verhalten anzupassen. Sie können die Ressourcengruppe entfernen, in der alle von Ihnen erstellten Ressourcen und Rollenzuweisungen enthalten sind.

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