Alıştırma - Dağıtım betiklerine parametre ekleme

Tamamlandı

El ile yapılan bazı işleri Azure Resource Manager (ARM) şablonunuz içine geçirmek için bir dağıtım betiği kullandığınıza göre, kuruluşunuzdaki başka bir iş ortağı uygulama ekibi biraz yardım istiyor.

Ekibin süreci benzer gereksinimlere sahiptir, ancak ekibin depolama hesabına birden çok dosya dağıtması gerekir. Ekibin, dosya listesini parametre olarak alıp karşıya yükleyebilen bir PowerShell betiği var. Şablonunuzda zaten kullanmakta olduğunuz betik gibi.

Bu alıştırmada, önceki şablonunuzu başlangıç noktası olarak alır ve PowerShell betiğini iş ortağı ekibinizden gelen şablonu kullanacak şekilde güncelleştirirsiniz. Ardından, şablonu dağıtan kişinin dağıtılacak yapılandırma dosyalarını (bir veya daha fazla) belirtmesini sağlamak için bir yol eklersiniz.

İşlem sırasında şunları yapacaksınız:

  • Dağıtım betiğini güncelleştirin.
  • Bir ortam değişkeni ve şablon parametresi ekleyin ve bunları dağıtım betiğinize geçirin.
  • Dağıtım betiğine bir çıkış ekleyin.
  • Parametre dosyası ekleyin.
  • Şablonu dağıtın ve sonucu doğrulayın.

Başlangıç şablonunu oluşturma

Son alıştırmada oluşturduğunuz şablonla başlarsınız.

  1. Visual Studio Code’u açın ve azuredeploy.json adlı yeni bir dosya oluşturun.

  2. Aşağıdaki başlangıç şablonunu azuredeploy.json kopyalayın.

    {
        "$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. Şablonu kaydedin.

  1. Visual Studio Code'u açın ve main.bicep adlı yeni bir dosya oluşturun.

  2. Aşağıdaki başlangıç şablonunu main.bicep'e kopyalayın.

    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. Şablonu kaydedin.

PowerShell betiğini güncelleştirme

Diğer ekip birden çok dosyayı kopyalamak için Bir PowerShell betiği oluşturma konusunda sıkı bir çalışma yaptığı için, bu betiği şablonunuzda kullanmaya karar verirsiniz.

Edit scriptContent kısmında iş ortağı ekibinizin sağladığı betiği içerecek şekilde düzenleyin properties.

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

Ortam değişkeni ekleme

Benimsediğiniz betik bazı ortam değişkenleri gerektirir. Bunları doğrudan şablonda belirtebilirsiniz, ancak bazı değerleri almak için şablon işlevlerini kullanmak daha fazla esneklik sağlar.

  1. Dağıtım betiğinin environmentVariables bölümüne bir properties özellik ekleyin.

    "environmentVariables": [
    ],
    
  2. için ResourceGroupNamebir ortam değişkeni ekleyin.

    "environmentVariables": [
        {
            "name": "ResourceGroupName",
            "value": "[resourceGroup().name]"
        }
    ],
    
  3. için StorageAccountNamebir ortam değişkeni ekleyin.

    "environmentVariables": [
        {
            "name": "ResourceGroupName",
            "value": "[resourceGroup().name]"
        },
        {
            "name": "StorageAccountName",
            "value": "[variables('storageAccountName')]"
        }
    ],
    
  4. için StorageContainerNamebir ortam değişkeni ekleyin.

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

İpucu

ve gibi [resourceGroup().name] ortak değerlere erişmek için şablon işlevlerini[variables()].

Benimsediğiniz betik bazı ortam değişkenleri gerektirir. Bunları doğrudan şablonda belirtebilirsiniz, ancak bazı değerleri almak için Bicep değişkenlerini kullanmak daha fazla esneklik sağlar.

  1. Dağıtım betiğinin environmentVariables bölümüne bir properties özellik ekleyin.

    environmentVariables: [
    ]
    
  2. için ResourceGroupNamebir ortam değişkeni ekleyin.

    environmentVariables: [
      {
        name: 'ResourceGroupName'
        value: resourceGroup().name
      }
    ]
    
  3. için StorageAccountNamebir ortam değişkeni ekleyin.

    environmentVariables: [
      {
        name: 'ResourceGroupName'
        value: resourceGroup().name
      }
      {
        name: 'StorageAccountName'
        value: storageAccountName
      }
    ]
    
  4. için StorageContainerNamebir ortam değişkeni ekleyin.

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

Şablon parametresi ekleme

şablonunuzu iki ekibin kullanmasını kolaylaştırmak için şablona bir parametre ekleyerek her ekibin kopyalamak istediği dosyaları belirtmesini sağlayabilirsiniz.

Dosya adları dizisini almak için şablona bir parametre ekleyin.

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

Ek olarak, şablonun dağıtım işleminde hiçbir değişiklik olmadan ekibiniz için çalışmaya devam etmesi için varsayılan bir değer sağlayabilirsiniz. Yeni bir varsayılan değer girmek gerekli olmasa da, önemli bir düzeni anlamanıza yardımcı olabilir. Dağıtım işlemini aynı tutarak, ekiplerin şablonların yeni sürümlerini benimsemesini kolaylaştırırsınız. Ekipler, yaptıkları gibi davranmaya devam ederler ve yeni işlevsellik ödüldür. Başka bir deyişle, bu adım gelecekteki çalışmayı destekleyecek değişiklikleri yaparken mevcut davranışı nasıl koruyacağınızı gösterir.

Dosya adları dizisini almak için şablona bir parametre ekleyin.

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

Ek olarak, şablonun dağıtım işleminde hiçbir değişiklik olmadan ekibiniz için çalışmaya devam etmesi için varsayılan bir değer sağlayabilirsiniz. Yeni bir varsayılan değer girmek gerekli olmasa da, önemli bir düzeni anlamanıza yardımcı olabilir. Dağıtım işlemini aynı tutarak, ekiplerin şablonların yeni sürümlerini benimsemesini kolaylaştırırsınız. Ekipler, yaptıkları gibi davranmaya devam ederler ve yeni işlevsellik ödüldür. Başka bir deyişle, bu adım gelecekteki çalışmayı destekleyecek değişiklikleri yaparken mevcut davranışı nasıl koruyacağınızı gösterir.

Kopyalanacak dosyaları geçirmek için bağımsız değişken ekleme

Ardından, önceki adımda tanımladığınız parametreyi alıp dağıtım betiğine geçirebilirsiniz. Dizeler birden çok düzeyde değerlendirildiğinden, komut satırı bağımsız değişkenlerini geçirmek zor olabilir. Tekliflerin doğru şekilde kaçılması ve iş için doğru tekliflerin seçilmesi başarı için gereklidir.

İpucu

Bir türün değerlerini dizeye dönüştürmek gibi yaygın işlevlere erişmek için şablon işlevlerini[string()].

  1. Dağıtım betiğine bir arguments özellik ekleyin. PowerShell betiği, şablon parametresinden File gelmesi gereken dosya adları dizesi olan adlı filesToCopybir parametre alır. Bağımsız değişkenin düzgün bir şekilde geçirilmesi için bağımsız değişkenin tamamında tırnak işareti bulunduğundan emin olun.

    Dikkat

    Bu arguments özellik geçersiz. Visual Studio Code'da Azure Resource Manager uzantısını kullanıyorsanız bu satır bayrakla işaretlenebilir. Bu sorunu sonraki adımlarda çözeceksiniz.

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

    İpucu

    Özellikle komut satırı bağımsız değişkenlerini geçirirken JSON'da öğeleri alıntılama zor olabilir. Kaçışı zor olan bir karakteri temsil etmek için şablon değişkeni kullanabilirsiniz.

  2. Tek tırnak karakterini temsil eden bir şablon değişkeni ekleyin.

    "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. özelliğindeki arguments tek tırnakları önceki adımda tanımladığınız değişkenle değiştirin.

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

Ardından, önceki adımda tanımladığınız parametreyi alıp dağıtım betiğine geçirebilirsiniz. Dizeler birden çok düzeyde değerlendirildiğinden, komut satırı bağımsız değişkenlerini geçirmek zor olabilir. Tekliflerin doğru şekilde kaçılması ve iş için doğru tekliflerin seçilmesi başarı için gereklidir.

Dağıtım betiğine bir arguments özellik ekleyin. PowerShell betiği, şablon parametresinden File gelmesi gereken dosya adları dizesi olan adlı filesToCopybir parametre alır.

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

Bunun birkaç Bicep özelliği kullandığına dikkat edin:

  • Dizeleri birleştirmek için dize ilişkilendirmesi.
  • Tek tırnak normalde Bicep'te ayrılmış bir karakter olduğundan, dizenin içine tek tırnak karakteri (\) eklememize izin vermek için kaçış karakterini kullanırız'.
  • dizisini string() dizeye dönüştürmek filesToCopy için işlevini kullanırız.

Şablon çıkışını güncelleştirme

Dağıtım betiğini bir veya daha fazla dosya dağıtacak şekilde değiştirdiğiniz için, gerekli tüm bilgileri sağlamak için şablon çıktısını güncelleştirmeniz gerekir.

  1. Şablondaki outputs öğesini, her dosya için bir URI içeren nesnenin tamamını döndürecek şekilde güncelleyin.

    $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. Depolama hesabı adıyla (rastgele tanımlayıcısı olan) başka bir çıkış ekleyin. Bu hesap adını daha sonra dağıtım betiğinin beklediğiniz gibi yaptığını doğrulamak için kullanırsınız.

    $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. Şablonun çıktısını, her dosya için bir URI içeren nesnenin tamamını döndürecek şekilde güncelleyin.

    output fileUri object = deploymentScript.properties.outputs
    
  2. Depolama hesabı adıyla (rastgele tanımlayıcısı olan) başka bir çıkış ekleyin. Bu hesap adını daha sonra dağıtım betiğinin beklediğiniz gibi yaptığını doğrulamak için kullanırsınız.

    output storageAccountName string = storageAccountName
    

Şablonunuzu doğrulama

Şablonunuz şuna benzemelidir:

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

Aksi takdirde, örneği kopyalayın veya şablonunuzu örnekle eşleşecek şekilde ayarlayın.

Parametre dosyası oluşturma

Artık şablon kümesini edindiğinize göre, belirtilen yeni dosyaları içeren bir parametre dosyası kullanarak yeni dağıtım betiğini doğrulayabilirsiniz.

  1. El ile bir azuredeploy.parameters.json dosyası oluşturun veya bunu yapmak için VS Code uzantısını kullanın.

  2. Dosyayı iki filesToCopy tane belirtecek şekilde düzenleyin:

    {
        "$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. azuredeploy.parameters.json dosyası oluşturun.

  2. Dosyayı iki filesToCopy tane belirtecek şekilde düzenleyin:

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

Şablonu dağıtma

Alıştırma için kaynak grubu oluşturma

Bu alıştırmanın bir parçası olarak oluşturduğunuz kaynakları içerecek bir kaynak grubu oluşturmanız gerekir. Yeni bir kaynak grubu kullanarak, alıştırmadan sonra temizlemeyi daha kolay hale getireceksiniz.

Visual Studio Code'daki terminalden bu komutu çalıştırarak bu alıştırmanın kaynak grubunu oluşturun.

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

Şablonu Azure’a dağıtma

Visual Studio Code terminalinde Azure CLI komutlarını kullanarak şablonu dağıtın.

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

Şablonu Azure’a dağıtma

Terminalde Azure PowerShell komutlarını kullanarak şablonu dağıtın.

$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

Şablonu Azure’a dağıtma

Visual Studio Code terminalinde Azure CLI komutlarını kullanarak şablonu dağıtın.

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

Şablonu Azure’a dağıtma

Terminalde Azure PowerShell komutlarını kullanarak şablonu dağıtın.

$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

Şablonunuzun sonucunu gözden geçirin

Dağıtım tamamlandıktan sonra blob kapsayıcısının içeriğini listeleyerek her iki dosyanın da depolama hesabınıza kopyalandığını doğrulayabilirsiniz.

  1. Blob kapsayıcısının içeriğini listeleyin.

    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'
    

    komutu aşağıdaki kodu döndürür:

    [
      "swagger.Staging.json",
      "appsettings.Staging.json"
    ]
    
  2. Azure portalından veya aşağıdaki komutu kullanarak günlükleri (ve dağıtımla ilgili diğer ayrıntıları) da gözden geçirebilirsiniz.

    az deployment-scripts show-log --resource-group $resourceGroupName --name CopyConfigScript
    
  1. Blob kapsayıcısının içeriğini listeleyin.

    $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
    

    komutu aşağıdaki kodu döndürür:

    Name
    ----
    swagger.Staging.json
    appsettings.Staging.json
    
  2. Azure portalından veya aşağıdaki komutu kullanarak günlükleri (ve dağıtımla ilgili diğer ayrıntıları) da gözden geçirebilirsiniz.

    Get-AzDeploymentScriptLog -ResourceGroupName $resourceGroupName -Name CopyConfigScript
    

Kaynak grubunu temizleme

Tebrikler! Arm şablonunu dağıtım betiğiyle başarıyla dağıttınız ve davranışını özelleştirmek için verileri geçirmek için farklı yöntemler kullandınız. Oluşturduğunuz tüm kaynakları ve rol atamalarını içeren kaynak grubunu kaldırabilirsiniz.

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