แบบฝึกหัด - เพิ่มพารามิเตอร์ไปยังสคริปต์การปรับใช้

เสร็จสมบูรณ์เมื่อ

ตอนนี้คุณใช้สคริปต์การปรับใช้เพื่อโยกย้ายงานด้วยตนเองบางอย่างไปยังเทมเพลต Azure Resource Manager (ARM) ของคุณ ทีมแอปพลิเคชันคู่ค้าอื่นในองค์กรของคุณกําลังขอความช่วยเหลือบางอย่าง

กระบวนการของทีมมีข้อกําหนดที่คล้ายกัน แต่ทีมจําเป็นต้องปรับใช้หลายไฟล์ไปยังบัญชีเก็บข้อมูล ทีมมีสคริปต์ PowerShell ที่สามารถรับรายการไฟล์เป็นพารามิเตอร์ และอัปโหลดไฟล์ คล้ายกับสคริปต์ที่คุณใช้อยู่แล้วในเทมเพลตของคุณ

ในแบบฝึกหัดนี้ คุณใช้เทมเพลตก่อนหน้าของคุณเป็นจุดเริ่มต้นและอัปเดตสคริปต์ PowerShell เพื่อใช้เทมเพลตจากทีมคู่ค้าของคุณ จากนั้น คุณสามารถเพิ่มวิธีที่จะเปิดใช้งานบุคคลที่ปรับใช้เทมเพลตเพื่อระบุไฟล์การกําหนดค่าที่จะปรับใช้ (หนึ่งไฟล์ขึ้นไป)

ในระหว่างกระบวนการ คุณจะ:

  • อัปเดตสคริปต์การปรับใช้
  • เพิ่มตัวแปรสภาพแวดล้อมและพารามิเตอร์เทมเพลต และส่งผ่านตัวแปรเหล่านี้ไปยังสคริปต์การปรับใช้ของคุณ
  • เพิ่มผลลัพธ์ไปยังสคริปต์การปรับใช้
  • เพิ่มไฟล์พารามิเตอร์
  • ปรับใช้เทมเพลตและตรวจสอบผลลัพธ์

สร้างเทมเพลตเริ่มต้น

คุณเริ่มต้นด้วยแม่แบบที่คุณสร้างขึ้นในแบบฝึกหัดล่าสุด

  1. เปิด Visual Studio Code และสร้างไฟล์ใหม่ที่เรียกว่า azuredeploy.json

  2. คัดลอกเท็มเพลตเริ่มต้นต่อไปนี้ลงใน 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. บันทึกเทมเพลต

  1. เปิดรหัส Visual Studio และสร้างไฟล์ใหม่ที่เรียกว่า main.bicep

  2. คัดลอกเทมเพลตเริ่มต้นต่อไปนี้ลงใน 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. บันทึกเทมเพลต

อัปเดตสคริปต์ PowerShell

เนื่องจากทีมอื่นต้องทํางานหนักในการสร้างสคริปต์ PowerShell เพื่อคัดลอกหลายไฟล์ คุณจึงตัดสินใจที่จะใช้สคริปต์นั้นในเทมเพลตของคุณ

แก้ไข scriptContent ในส่วน 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."

เพิ่มตัวแปรสภาพแวดล้อม

สคริปต์ที่คุณนํามาใช้ต้องการตัวแปรสภาพแวดล้อมบางอย่าง คุณสามารถระบุได้โดยตรงในเทมเพลต แต่จะสร้างความยืดหยุ่นมากขึ้นในการใช้ฟังก์ชันเทมเพลตเพื่อรับค่าบางอย่าง

  1. เพิ่มคุณสมบัติ environmentVariables ไปยังส่วน properties ของสคริปต์การปรับใช้

    "environmentVariables": [
    ],
    
  2. เพิ่มตัวแปรสภาพแวดล้อมสําหรับ ResourceGroupName

    "environmentVariables": [
        {
            "name": "ResourceGroupName",
            "value": "[resourceGroup().name]"
        }
    ],
    
  3. เพิ่มตัวแปรสภาพแวดล้อมสําหรับ StorageAccountName

    "environmentVariables": [
        {
            "name": "ResourceGroupName",
            "value": "[resourceGroup().name]"
        },
        {
            "name": "StorageAccountName",
            "value": "[variables('storageAccountName')]"
        }
    ],
    
  4. เพิ่มตัวแปรสภาพแวดล้อมสําหรับ StorageContainerName

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

ปลาย

ใช้ฟังก์ชันเทมเพลต เพื่อเข้าถึงค่าทั่วไป เช่น [resourceGroup().name] และ [variables()]

สคริปต์ที่คุณนํามาใช้ต้องการตัวแปรสภาพแวดล้อมบางอย่าง คุณสามารถระบุได้โดยตรงในเทมเพลต แต่จะสร้างความยืดหยุ่นมากขึ้นในการใช้ตัวแปร Bicep เพื่อรับค่าบางอย่าง

  1. เพิ่มคุณสมบัติ environmentVariables ไปยังส่วน properties ของสคริปต์การปรับใช้

    environmentVariables: [
    ]
    
  2. เพิ่มตัวแปรสภาพแวดล้อมสําหรับ ResourceGroupName

    environmentVariables: [
      {
        name: 'ResourceGroupName'
        value: resourceGroup().name
      }
    ]
    
  3. เพิ่มตัวแปรสภาพแวดล้อมสําหรับ StorageAccountName

    environmentVariables: [
      {
        name: 'ResourceGroupName'
        value: resourceGroup().name
      }
      {
        name: 'StorageAccountName'
        value: storageAccountName
      }
    ]
    
  4. เพิ่มตัวแปรสภาพแวดล้อมสําหรับ StorageContainerName

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

เพิ่มพารามิเตอร์เทมเพลต

เพื่อทําให้เทมเพลตของคุณใช้งานได้ง่ายขึ้นสําหรับทั้งสองทีม คุณสามารถเพิ่มพารามิเตอร์ไปยังเทมเพลตเพื่อให้แต่ละทีมสามารถระบุไฟล์ที่ต้องการคัดลอกได้

เพิ่มพารามิเตอร์ไปยังเทมเพลตเพื่อใช้อาร์เรย์ของชื่อไฟล์

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

ในฐานะโบนัส คุณสามารถใส่ค่าเริ่มต้นเพื่อให้เทมเพลตยังคงทํางานให้กับทีมของคุณโดยไม่มีการเปลี่ยนแปลงกระบวนการปรับใช้ แม้ว่าจะไม่จําเป็นต้องป้อนค่าเริ่มต้นใหม่ แต่ก็สามารถช่วยให้คุณเข้าใจรูปแบบที่สําคัญได้ การรักษากระบวนการปรับใช้ให้เหมือนเดิม จะทําให้ทีมสามารถนําเทมเพลตเวอร์ชันใหม่มาใช้ได้ง่ายขึ้น ทีมต่างๆ ยังคงประพฤติตัวเหมือนที่เคยทํามา และฟังก์ชันการทํางานใหม่นี้เป็นรางวัล กล่าวอีกนัยหนึ่งขั้นตอนนี้จะแสดงวิธีการรักษาลักษณะการทํางานที่มีอยู่ในขณะที่ทําการเปลี่ยนแปลงเพื่อสนับสนุนการทํางานในอนาคต

เพิ่มพารามิเตอร์ไปยังเทมเพลตเพื่อใช้อาร์เรย์ของชื่อไฟล์

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

ในฐานะโบนัส คุณสามารถใส่ค่าเริ่มต้นเพื่อให้เทมเพลตยังคงทํางานให้กับทีมของคุณโดยไม่มีการเปลี่ยนแปลงกระบวนการปรับใช้ แม้ว่าจะไม่จําเป็นต้องป้อนค่าเริ่มต้นใหม่ แต่ก็สามารถช่วยให้คุณเข้าใจรูปแบบที่สําคัญได้ การรักษากระบวนการปรับใช้ให้เหมือนเดิม จะทําให้ทีมสามารถนําเทมเพลตเวอร์ชันใหม่มาใช้ได้ง่ายขึ้น ทีมต่างๆ ยังคงประพฤติตัวเหมือนที่เคยทํามา และฟังก์ชันการทํางานใหม่นี้เป็นรางวัล กล่าวอีกนัยหนึ่งขั้นตอนนี้จะแสดงวิธีการรักษาลักษณะการทํางานที่มีอยู่ในขณะที่ทําการเปลี่ยนแปลงเพื่อสนับสนุนการทํางานในอนาคต

เพิ่มอาร์กิวเมนต์ที่จะส่งผ่านในไฟล์ที่จะคัดลอก

ถัดไป คุณสามารถนําพารามิเตอร์ที่คุณกําหนดไว้ในขั้นตอนก่อนหน้าและส่งผ่านไปยังสคริปต์การปรับใช้ได้ การส่งผ่านอาร์กิวเมนต์บรรทัดคําสั่งอาจเป็นเรื่องยุ่งยาก เนื่องจากมีการประเมินสตริงในหลายระดับ การหลบหนีใบเสนอราคาอย่างเหมาะสมและการเบิกเครื่องหมายอัญประกาศที่เหมาะสมสําหรับงานเป็นสิ่งสําคัญสําหรับความสําเร็จ

ปลาย

ใช้ฟังก์ชันเทมเพลต เพื่อเข้าถึงฟังก์ชันทั่วไปเช่น [string()] เพื่อแปลงค่าของชนิดหนึ่งเป็นสตริง

  1. เพิ่มคุณสมบัติ arguments ลงในสคริปต์การปรับใช้ สคริปต์ PowerShell ใช้พารามิเตอร์ที่ชื่อ Fileซึ่งเป็นสตริงของชื่อไฟล์ที่ควรมาจากพารามิเตอร์เทมเพลต filesToCopy ตรวจสอบให้แน่ใจว่ามีเครื่องหมายอัญประกาศรอบๆ อาร์กิวเมนต์ทั้งหมดเพื่อให้ส่งผ่านอย่างถูกต้อง

    ความระมัดระวัง

    คุณสมบัติ arguments นี้ไม่ถูกต้อง หากคุณกําลังใช้ส่วนขยาย Azure Resource Manager ใน Visual Studio Code อาจตั้งค่าสถานะบรรทัดนี้ คุณจะแก้ไขปัญหานี้ในขั้นตอนถัดไป

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

    ปลาย

    การอธิบายสิ่งต่างๆ ใน JSON อาจเป็นเรื่องยาก โดยเฉพาะอย่างยิ่งเมื่อคุณกําลังส่งผ่านในอาร์กิวเมนต์บรรทัดคําสั่ง คุณสามารถใช้ตัวแปรแม่แบบเพื่อแสดงอักขระที่ยากต่อการหลีกเลี่ยงการใช้งาน

  2. เพิ่มตัวแปรเทมเพลตเพื่อแสดงอักขระเครื่องหมายคําพูดเดี่ยว

    "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. แทนที่เครื่องหมายอัญประกาศเดี่ยวใน arguments คุณสมบัติ ด้วยตัวแปรที่คุณกําหนดไว้ในขั้นตอนก่อนหน้า

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

ถัดไป คุณสามารถนําพารามิเตอร์ที่คุณกําหนดไว้ในขั้นตอนก่อนหน้าและส่งผ่านไปยังสคริปต์การปรับใช้ได้ การส่งผ่านอาร์กิวเมนต์บรรทัดคําสั่งอาจเป็นเรื่องยุ่งยาก เนื่องจากมีการประเมินสตริงในหลายระดับ การหลบหนีใบเสนอราคาอย่างเหมาะสมและการเบิกเครื่องหมายอัญประกาศที่เหมาะสมสําหรับงานเป็นสิ่งสําคัญสําหรับความสําเร็จ

เพิ่มคุณสมบัติ arguments ลงในสคริปต์การปรับใช้ สคริปต์ PowerShell ใช้พารามิเตอร์ที่ชื่อ Fileซึ่งเป็นสตริงของชื่อไฟล์ที่ควรมาจากพารามิเตอร์เทมเพลต filesToCopy

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

โปรดสังเกตว่านี่ใช้คุณลักษณะ Bicep หลายตัว:

  • การประมาณค่าในช่วงสตริงเพื่อรวมสตริง
  • เราใช้อักขระหลีก \ เพื่อให้เราสามารถรวมอักขระเครื่องหมายคําพูดเดี่ยว (') ภายในสตริงเนื่องจากเครื่องหมายอัญประกาศเดี่ยวเป็นอักขระที่สงวนไว้ใน Bicep
  • เราใช้ฟังก์ชัน string() เพื่อแปลงอาร์เรย์ filesToCopy เป็นสตริง

อัปเดตผลลัพธ์เทมเพลต

เนื่องจากคุณกําลังเปลี่ยนสคริปต์การปรับใช้เพื่อปรับใช้ไฟล์อย่างน้อยหนึ่งไฟล์ คุณจําเป็นต้องอัปเดตผลลัพธ์เทมเพลตเพื่อให้ข้อมูลที่จําเป็นทั้งหมด

  1. outputsอัปเดต ในเทมเพลตเพื่อส่งคืนออบเจ็กต์ทั้งหมดซึ่งมี URI สําหรับแต่ละไฟล์

    $DeploymentScriptOutputs = @{}
    foreach ($fileName in $fileList) {
        Write-Host \"Copying $fileName to $env:StorageContainerName in $env:StorageAccountName.\"
        Invoke-RestMethod -Uri \"https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/mslearn-arm-deploymentscripts-sample/$fileName\" -OutFile $fileName
        $blob = Set-AzStorageBlobContent -File $fileName -Container $env:StorageContainerName -Blob $fileName -Context $storageAccount.Context
        $DeploymentScriptOutputs[$fileName] = @{}
        $DeploymentScriptOutputs[$fileName]['Uri'] = $blob.ICloudBlob.Uri
        $DeploymentScriptOutputs[$fileName]['StorageUri'] =$blob.ICloudBlob.StorageUri
        $count++
    }
    
  2. เพิ่มเอาต์พุตอื่นด้วยชื่อบัญชีเก็บข้อมูล (ซึ่งมีตัวระบุแบบสุ่ม) คุณใช้ชื่อบัญชีนี้ในภายหลังเพื่อตรวจสอบสคริปต์การปรับใช้ได้ทําในสิ่งที่คุณคาดหวัง

    $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. อัปเดตเอาต์พุตในเทมเพลตเพื่อส่งคืนออบเจ็กต์ทั้งหมดซึ่งมี URI สําหรับแต่ละไฟล์

    output fileUri object = deploymentScript.properties.outputs
    
  2. เพิ่มเอาต์พุตอื่นด้วยชื่อบัญชีเก็บข้อมูล (ซึ่งมีตัวระบุแบบสุ่ม) คุณใช้ชื่อบัญชีนี้ในภายหลังเพื่อตรวจสอบสคริปต์การปรับใช้ได้ทําในสิ่งที่คุณคาดหวัง

    output storageAccountName string = storageAccountName
    

ตรวจสอบเทมเพลตของคุณ

เทมเพลตของคุณควรมีลักษณะคล้ายกับ:

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.1",
    "apiProfile": "",
    "parameters": {
        "filesToCopy": {
            "type": "array",
            "defaultValue": [ "appsettings.json" ],
            "metadata": {
                "description": "List of files to copy to application storage account."
            }
        }
    },
    "variables": {
        "singleQuote": "'",
        "storageAccountName": "[concat('storage', uniqueString(resourceGroup().id))]",
        "storageBlobContainerName": "config",
        "userAssignedIdentityName": "configDeployer",
        "roleAssignmentName": "[guid(concat(resourceGroup().id, 'contributor'))]",
        "contributorRoleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
        "deploymentScriptName": "CopyConfigScript"
    },
    "functions": [],
    "resources": [
        {
            "name": "[variables('storageAccountName')]",
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2023-01-01",
            "tags": {
                "displayName": "[variables('storageAccountName')]"
            },
            "location": "[resourceGroup().location]",
            "kind": "StorageV2",
            "sku": {
                "name": "Standard_LRS",
                "tier": "Standard"
            },
            "properties": {
                "allowBlobPublicAccess": true,
                "encryption": {
                    "services": {
                        "blob": {
                            "enabled": true
                        }
                    },
                    "keySource": "Microsoft.Storage"
                },
                "supportsHttpsTrafficOnly": true
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/blobServices",
            "apiVersion": "2019-04-01",
            "name": "[concat(variables('storageAccountName'), '/default')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
            ]
        },
        {
            "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
            "apiVersion": "2019-04-01",
            "name": "[concat(variables('storageAccountName'),'/default/',variables('storageBlobContainerName'))]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('storageAccountName'), 'default')]",
                "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
            ],
            "properties": {
                "publicAccess": "Blob"
            }
        },
        {
            "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
            "apiVersion": "2018-11-30",
            "name": "[variables('userAssignedIdentityName')]",
            "location": "[resourceGroup().location]"
        },
        {
            "type": "Microsoft.Authorization/roleAssignments",
            "apiVersion": "2020-04-01-preview",
            "name": "[variables('roleAssignmentName')]",
            "dependsOn": [ "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('userAssignedIdentityName'))]" ],
            "properties": {
                "roleDefinitionId": "[variables('contributorRoleDefinitionId')]",
                "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('userAssignedIdentityName')), '2015-08-31-preview').principalId]",
                "scope": "[resourceGroup().id]",
                "principalType": "ServicePrincipal"
            }
        },
        {
            "type": "Microsoft.Resources/deploymentScripts",
            "apiVersion": "2020-10-01",
            "name": "[variables('deploymentScriptName')]",
            "location": "[resourceGroup().location]",
            "kind": "AzurePowerShell",
            "dependsOn": [
                "[resourceId('Microsoft.Authorization/roleAssignments', variables('roleAssignmentName'))]",
                "[resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', variables('storageAccountName'), 'default', variables('storageBlobContainerName'))]"
            ],
            "identity": {
                "type": "UserAssigned",
                "userAssignedIdentities": {
                    "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',variables('userAssignedIdentityName'))]": {}
                }
            },
            "properties": {
                "arguments": "[concat( '-File ', variables('singleQuote'), string(parameters('filesToCopy')), variables('singleQuote'))]",
                "environmentVariables": [
                    {
                        "name": "ResourceGroupName",
                        "value": "[resourceGroup().name]"
                    },
                    {
                        "name": "StorageAccountName",
                        "value": "[variables('storageAccountName')]"
                    },
                    {
                        "name": "StorageContainerName",
                        "value": "[variables('storageBlobContainerName')]"
                    }
                ],
                "azPowerShellVersion": "3.0",
                "scriptContent": "
                    param([string]$File)
                    $fileList = $File -replace '(\[|\])' -split ',' | ForEach-Object { $_.trim() }
                    $storageAccount = Get-AzStorageAccount -ResourceGroupName $env:ResourceGroupName -Name $env:StorageAccountName -Verbose
                    $count = 0
                    $DeploymentScriptOutputs = @{}
                    foreach ($fileName in $fileList) {
                        Write-Host \"Copying $fileName to $env:StorageContainerName in $env:StorageAccountName.\"
                        Invoke-RestMethod -Uri \"https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/mslearn-arm-deploymentscripts-sample/$fileName\" -OutFile $fileName
                        $blob = Set-AzStorageBlobContent -File $fileName -Container $env:StorageContainerName -Blob $fileName -Context $storageAccount.Context
                        $DeploymentScriptOutputs[$fileName] = @{}
                        $DeploymentScriptOutputs[$fileName]['Uri'] = $blob.ICloudBlob.Uri
                        $DeploymentScriptOutputs[$fileName]['StorageUri'] =$blob.ICloudBlob.StorageUri
                        $count++
                    }
                    Write-Host \"Finished copying $count files.\"                    
                ",
                "retentionInterval": "P1D"
            }
        }
    ],
    "outputs": {
        "fileUri": {
            "type": "object",
            "value": "[reference(variables('deploymentScriptName')).outputs]"
        },
        "storageAccountName": {
            "type": "string",
            "value": "[variables('storageAccountName')]"
        }
    }
}
@description('List of files to copy to application storage account.')
param filesToCopy array = [
  'appsettings.json'
]

var storageAccountName = 'storage${uniqueString(resourceGroup().id)}'
var storageBlobContainerName = 'config'
var userAssignedIdentityName = 'configDeployer'
var roleAssignmentName = guid(resourceGroup().id, 'contributor')
var contributorRoleDefinitionId = resourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
var deploymentScriptName = 'CopyConfigScript'

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: storageAccountName
  tags: {
    displayName: storageAccountName
  }
  location: resourceGroup().location
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
    tier: 'Standard'
  }
  properties: {
    allowBlobPublicAccess: true
    encryption: {
      services: {
        blob: {
          enabled: true
        }
      }
      keySource: 'Microsoft.Storage'
    }
    supportsHttpsTrafficOnly: true
  }

  resource blobService 'blobServices' existing = {
    name: 'default'
  }
}

resource blobContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2019-04-01' = {
  parent: storageAccount::blobService
  name: storageBlobContainerName
  properties: {
    publicAccess: 'Blob'
  }
}

resource userAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = {
  name: userAssignedIdentityName
  location: resourceGroup().location
}

resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = {
  name: roleAssignmentName
  properties: {
    roleDefinitionId: contributorRoleDefinitionId
    principalId: userAssignedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
  }
}

resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
  name: deploymentScriptName
  location: resourceGroup().location
  kind: 'AzurePowerShell'
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${userAssignedIdentity.id}': {}
    }
  }
  properties: {
    arguments: '-File \'${string(filesToCopy)}\''
    environmentVariables: [
      {
        name: 'ResourceGroupName'
        value: resourceGroup().name
      }
      {
        name: 'StorageAccountName'
        value: storageAccountName
      }
      {
        name: 'StorageContainerName'
        value: storageBlobContainerName
      }
    ]
    azPowerShellVersion: '3.0'
    scriptContent: '''
      param([string]$File)
      $fileList = $File -replace '(\[|\])' -split ',' | ForEach-Object { $_.trim() }
      $storageAccount = Get-AzStorageAccount -ResourceGroupName $env:ResourceGroupName -Name $env:StorageAccountName -Verbose
      $count = 0
      $DeploymentScriptOutputs = @{}
      foreach ($fileName in $fileList) {
          Write-Host "Copying $fileName to $env:StorageContainerName in $env:StorageAccountName."
          Invoke-RestMethod -Uri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/mslearn-arm-deploymentscripts-sample/$fileName" -OutFile $fileName
          $blob = Set-AzStorageBlobContent -File $fileName -Container $env:StorageContainerName -Blob $fileName -Context $storageAccount.Context
          $DeploymentScriptOutputs[$fileName] = @{}
          $DeploymentScriptOutputs[$fileName]['Uri'] = $blob.ICloudBlob.Uri
          $DeploymentScriptOutputs[$fileName]['StorageUri'] = $blob.ICloudBlob.StorageUri
          $count++
      }
      Write-Host "Finished copying $count files."
    '''
    retentionInterval: 'P1D'
  }
  dependsOn: [
    roleAssignment
    blobContainer
  ]
}

output fileUri object = deploymentScript.properties.outputs
output storageAccountName string = storageAccountName

ถ้าไม่เป็นเช่นนั้น ให้คัดลอกตัวอย่างหรือปรับเทมเพลตของคุณให้ตรงกับตัวอย่าง

สร้างไฟล์พารามิเตอร์

หลังจากที่คุณมีชุดเทมเพลตแล้ว คุณสามารถตรวจสอบสคริปต์การปรับใช้ใหม่ได้โดยใช้ไฟล์พารามิเตอร์ที่มีไฟล์ใหม่ที่ระบุ

  1. สร้างไฟล์ azuredeploy.parameters.json ด้วยตนเอง หรือใช้ ส่วนขยาย VS Code ให้ทําเช่นนั้นได้

  2. แก้ไขไฟล์ให้มีการระบุ 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. สร้างไฟล์ azuredeploy.parameters.json

  2. แก้ไขไฟล์ให้มีการระบุ filesToCopy สองรายการ:

    {
        "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
        "contentVersion": "1.0.0.0",
        "parameters": {
            "filesToCopy": {
                "value": [
                    "swagger.Staging.json",
                    "appsettings.Staging.json"
                ]
            }
        }
    }
    

ปรับใช้เทมเพลต

สร้างกลุ่มทรัพยากรสําหรับแบบทดสอบ

คุณจําเป็นต้องสร้างกลุ่มทรัพยากรเพื่อประกอบด้วยทรัพยากรที่คุณสร้างขึ้นเป็นส่วนหนึ่งของแบบฝึกหัดนี้ เมื่อใช้กลุ่มทรัพยากรใหม่ คุณจะทําความสะอาดได้หลังจากออกกําลังกายง่ายขึ้น

จากเทอร์มินัลในรหัส Visual Studio ให้เรียกใช้คําสั่งนี้เพื่อสร้างกลุ่มทรัพยากรสําหรับแบบฝึกหัดนี้

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

ปรับใช้เทมเพลตกับ Azure

ปรับใช้เทมเพลตโดยใช้คําสั่ง Azure CLI ในเทอร์มินัล 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

ปรับใช้เทมเพลตกับ Azure

ปรับใช้เทมเพลตโดยใช้คําสั่ง Azure PowerShell ในเทอร์มินัล

$templateFile = 'azuredeploy.json'
$templateParameterFile = 'azuredeploy.parameters.json'
$today = Get-Date -Format 'MM-dd-yyyy'
$deploymentName = "deploymentscript-$today"

New-AzResourceGroupDeployment `
    -ResourceGroupName $resourceGroupName `
    -Name $deploymentName `
    -TemplateFile $templateFile `
    -TemplateParameterFile $templateParameterFile

ปรับใช้เทมเพลตกับ Azure

ปรับใช้เทมเพลตโดยใช้คําสั่ง Azure CLI ในเทอร์มินัล 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

ปรับใช้เทมเพลตกับ Azure

ปรับใช้เทมเพลตโดยใช้คําสั่ง Azure PowerShell ในเทอร์มินัล

$templateFile = 'main.bicep'
$templateParameterFile = 'azuredeploy.parameters.json'
$today = Get-Date -Format 'MM-dd-yyyy'
$deploymentName = "deploymentscript-$today"

New-AzResourceGroupDeployment `
    -ResourceGroupName $resourceGroupName `
    -Name $deploymentName `
    -TemplateFile $templateFile `
    -TemplateParameterFile $templateParameterFile

ตรวจสอบผลลัพธ์ของเทมเพลตของคุณ

หลังจากการปรับใช้เสร็จสมบูรณ์ คุณสามารถตรวจสอบว่า ไฟล์ทั้งสองถูกคัดลอกไปยังบัญชีเก็บข้อมูลของคุณ โดยแสดงรายการเนื้อหาของคอนเทนเนอร์ blob

  1. ทํารายการเนื้อหาของ blob container

    storageAccountName=$(az deployment group show --resource-group $resourceGroupName --name $deploymentName --query 'properties.outputs.storageAccountName.value' --output tsv)
    az storage blob list --account-name $storageAccountName --container-name config --query '[].name'
    

    คําสั่งส่งกลับโค้ดต่อไปนี้:

    [
      "swagger.Staging.json",
      "appsettings.Staging.json"
    ]
    
  2. คุณยังสามารถตรวจสอบบันทึก (และรายละเอียดอื่น ๆ เกี่ยวกับการปรับใช้) จากพอร์ทัล Azure หรือโดยใช้คําสั่งต่อไปนี้

    az deployment-scripts show-log --resource-group $resourceGroupName --name CopyConfigScript
    
  1. ทํารายการเนื้อหาของ blob container

    $storageAccountName = (Get-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName).Outputs.storageAccountName.Value
    $storageAccount = Get-AzStorageAccount -ResourceGroupName $resourceGroupName
    Get-AzStorageBlob -Context $storageAccount.Context -Container config |
        Select-Object Name
    

    คําสั่งส่งกลับโค้ดต่อไปนี้:

    Name
    ----
    swagger.Staging.json
    appsettings.Staging.json
    
  2. คุณยังสามารถตรวจสอบบันทึก (และรายละเอียดอื่น ๆ เกี่ยวกับการปรับใช้) จากพอร์ทัล Azure หรือโดยใช้คําสั่งต่อไปนี้

    Get-AzDeploymentScriptLog -ResourceGroupName $resourceGroupName -Name CopyConfigScript
    

ล้างกลุ่มทรัพยากร

ยินดีด้วย! คุณปรับใช้เทมเพลต ARM ด้วยสคริปต์การปรับใช้และใช้วิธีการที่แตกต่างกันเพื่อส่งผ่านข้อมูลเพื่อปรับแต่งลักษณะการทํางาน คุณสามารถลบกลุ่มทรัพยากรที่ประกอบด้วยการกําหนดทรัพยากรและบทบาททั้งหมดที่คุณสร้างขึ้น

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