연습 - 배포 스크립트에 매개 변수 추가
지금까지 배포 스크립트를 사용하여 일부 수동 작업을 ARM(Azure Resource Manager) 템플릿으로 마이그레이션했으며 조직의 다른 파트너 애플리케이션 팀에서 도움을 요청했습니다.
팀의 프로세스에는 비슷한 요구 사항이 있지만 팀은 스토리지 계정에 여러 파일을 배포해야 합니다. 팀에는 파일 목록을 매개 변수로 사용하여 업로드할 수 있는 PowerShell 스크립트가 있으며, 이는 템플릿에서 이미 사용했던 스크립트와 유사합니다.
본 연습에서는 이전에 진행한 템플릿을 시작점으로 두고 파트너 팀의 템플릿을 사용하도록 PowerShell 스크립트를 업데이트합니다. 그런 다음, 템플릿을 배포하는 사용자가 배포할 구성 파일(하나 이상)을 지정할 수 있도록 하는 방법을 추가합니다.
프로세스 중에 다음을 수행합니다.
- 배포 스크립트를 업데이트합니다.
- 환경 변수 및 템플릿 매개 변수를 추가하고 배포 스크립트에 전달합니다.
- 배포 스크립트에 출력을 추가합니다.
- 매개 변수 파일을 추가합니다.
- 템플릿을 배포하고 결과를 확인합니다.
시작 템플릿 만들기
마지막 연습에서 만든 템플릿으로 시작합니다.
Visual Studio Code를 열고 azuredeploy.json이라는 새 파일을 만듭니다.
다음 시작 템플릿을 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]" } } }
템플릿을 저장하는 경우
Visual Studio Code를 열고 main.bicep이라는 새 파일을 만듭니다.
다음 시작 템플릿을 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
템플릿을 저장하는 경우
PowerShell 스크립트 업데이트
다른 팀이 여러 파일을 복사하는 PowerShell 스크립트를 만들기 위해 열심히 노력했으므로 템플릿에서 해당 스크립트를 사용하기로 결정했습니다.
파트너 팀이 제공한 스크립트를 포함하도록 properties
섹션에서 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.\"
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."
환경 변수 추가
채택한 스크립트에는 몇 가지 환경 변수가 필요합니다. 템플릿에서 직접 지정할 수 있지만 템플릿 함수를 사용하여 일부 값을 가져오는 것이 더 유연한 방법이 될 수도 있습니다.
배포 스크립트의
properties
섹션에environmentVariables
속성을 추가합니다."environmentVariables": [ ],
ResourceGroupName
에 대한 환경 변수를 추가합니다."environmentVariables": [ { "name": "ResourceGroupName", "value": "[resourceGroup().name]" } ],
StorageAccountName
에 대한 환경 변수를 추가합니다."environmentVariables": [ { "name": "ResourceGroupName", "value": "[resourceGroup().name]" }, { "name": "StorageAccountName", "value": "[variables('storageAccountName')]" } ],
StorageContainerName
에 대한 환경 변수를 추가합니다."environmentVariables": [ { "name": "ResourceGroupName", "value": "[resourceGroup().name]" }, { "name": "StorageAccountName", "value": "[variables('storageAccountName')]" }, { "name": "StorageContainerName", "value": "[variables('storageBlobContainerName')]" } ],
팁
템플릿 함수를 사용하여 [resourceGroup().name]
및 [variables()]
와 같은 일반적인 값에 액세스합니다.
채택한 스크립트에는 몇 가지 환경 변수가 필요합니다. 템플릿에서 직접 지정할 수 있지만 Bicep 변수를 사용하여 일부 값을 가져오는 것이 더 유연한 방법이 될 수도 있습니다.
배포 스크립트의
properties
섹션에environmentVariables
속성을 추가합니다.environmentVariables: [ ]
ResourceGroupName
에 대한 환경 변수를 추가합니다.environmentVariables: [ { name: 'ResourceGroupName' value: resourceGroup().name } ]
StorageAccountName
에 대한 환경 변수를 추가합니다.environmentVariables: [ { name: 'ResourceGroupName' value: resourceGroup().name } { name: 'StorageAccountName' value: storageAccountName } ]
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()]
과 같은 일반적인 함수에 액세스합니다.
배포 스크립트에
arguments
속성을 추가합니다. PowerShell 스크립트는filesToCopy
템플릿 매개 변수에서 가져와야 하는 파일 이름 문자열인File
이라는 매개 변수를 사용합니다. 제대로 전달되도록 전체 인수를 따옴표로 묶어야 합니다.주의
이
arguments
속성이 잘못되었습니다. Visual Studio Code의 Azure Resource Manager 확장을 사용하는 경우 이 줄에 플래그를 지정할 수 있습니다. 다음 단계에서 이 문제를 해결합니다."arguments": "[concat( '-File '', string(parameters('filesToCopy')), ''' )]",
팁
특히 명령줄 인수를 전달할 때 JSON에서 따옴표를 사용하는 것이 어려울 수 있습니다. 템플릿 변수를 사용하여 이스케이프하기 어려운 문자를 나타낼 수 있습니다.
작은따옴표 문자를 나타내는 템플릿 변수를 추가합니다.
"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" },
arguments
속성의 작은따옴표를 방금 정의한 변수로 바꿉니다."arguments": "[concat( '-File ', variables('singleQuote'), string(parameters('filesToCopy')), variables('singleQuote'))]",
다음으로 방금 정의한 매개 변수를 가져와 배포 스크립트에 전달할 수 있습니다. 문자열이 여러 수준에서 평가되기 때문에 명령줄 인수 전달이 까다로울 수 있습니다. 따옴표를 제대로 이스케이프하고 작업에 적합한 따옴표를 선택하는 것은 성공에 필수적입니다.
배포 스크립트에 arguments
속성을 추가합니다. PowerShell 스크립트는 filesToCopy
템플릿 매개 변수에서 가져와야 하는 파일 이름 문자열인 File
이라는 매개 변수를 사용합니다.
arguments: '-File \'${string(filesToCopy)}\''
여기에는 다음과 같은 여러 Bicep 기능이 사용됩니다.
- 문자열 보간을 통한 문자열 결합
- 작은 따옴표는 일반적으로 Bicep에서 예약된 문자로 사용되므로
\
이스케이프 문자를 사용하여 문자열 내에 작은따옴표 문자('
)를 포함하도록 할 수 있습니다. string()
함수를 사용하여filesToCopy
배열을 문자열로 변환합니다.
템플릿 출력 업데이트
하나 이상의 파일을 배포하도록 배포 스크립트를 변경하기 때문에 필요한 모든 정보를 제공하도록 템플릿 출력을 업데이트해야 합니다.
전체 개체를 반환하여 파일당 하나의 URI가 유지되도록 템플릿에서
outputs
를 업데이트합니다.$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++ }
스토리지 계정 이름(임의 식별자가 있는)을 사용하여 다른 출력을 추가합니다. 나중에 이를 사용하여 배포 스크립트가 예상한 작업을 수행했는지 확인합니다.
$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++ }
전체 개체를 반환하여 파일당 하나의 URI가 유지되도록 템플릿에서 출력을 업데이트합니다.
output fileUri object = deploymentScript.properties.outputs
스토리지 계정 이름(임의 식별자가 있는)을 사용하여 다른 출력을 추가합니다. 나중에 이를 사용하여 배포 스크립트가 예상한 작업을 수행했는지 확인합니다.
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
아닌 경우 예제를 복사하거나 예제와 일치하도록 템플릿을 조정합니다.
매개 변수 파일 만들기
이제 템플릿이 설정되었으므로 지정된 새 파일이 있는 매개 변수 파일을 사용하여 새 배포 스크립트의 유효성을 검사할 수 있습니다.
azuredeploy.parameters.json 파일을 수동으로 만들거나 VS Code 확장자를 사용하여 이 파일을 만듭니다.
파일을 편집하여 다음 두 가지
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" ] } } }
azuredeploy.parameters.json 파일을 만듭니다.
파일을 편집하여 다음 두 가지
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 Code의 터미널에서 이 명령을 실행하여 이 연습에 대한 리소스 그룹을 만듭니다.
resourceGroupName="learndeploymentscript_exercise_2"
az group create --location eastus --name $resourceGroupName
$resourceGroupName = 'learndeploymentscript_exercise_2'
New-AzResourceGroup -Location eastus -Name $resourceGroupName
Azure에 템플릿 배포
Visual Studio Code 터미널에서 Azure CLI 명령을 사용하여 템플릿을 배포합니다.
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에 템플릿 배포
Visual Studio Code 터미널에서 Azure CLI 명령을 사용하여 템플릿을 배포합니다.
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 컨테이너의 콘텐츠를 나열하여 두 파일이 스토리지 계정에 복사되었는지 확인할 수 있습니다.
Blob 컨테이너의 내용을 나열합니다.
storageAccountName=$(az deployment group show --resource-group $resourceGroupName --name $deploymentName --query 'properties.outputs.storageAccountName.value' --output tsv) az storage blob list --account-name $storageAccountName --container-name config --query '[].name'
명령은 다음 코드를 반환합니다.
[ "swagger.Staging.json", "appsettings.Staging.json" ]
Azure Portal에서 또는 다음 명령을 사용하여 로그(및 배포에 대한 기타 세부 정보)를 검토할 수도 있습니다.
az deployment-scripts show-log --resource-group $resourceGroupName --name CopyConfigScript
Blob 컨테이너의 내용을 나열합니다.
$storageAccountName = (Get-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName).Outputs.storageAccountName.Value $storageAccount = Get-AzStorageAccount -ResourceGroupName $resourceGroupName Get-AzStorageBlob -Context $storageAccount.Context -Container config | Select-Object Name
명령은 다음 코드를 반환합니다.
Name ---- swagger.Staging.json appsettings.Staging.json
Azure Portal에서 또는 다음 명령을 사용하여 로그(및 배포에 대한 기타 세부 정보)를 검토할 수도 있습니다.
Get-AzDeploymentScriptLog -ResourceGroupName $resourceGroupName -Name CopyConfigScript
리소스 그룹 정리
배포 스크립트를 사용하여 ARM 템플릿을 성공적으로 배포했으며 다양한 메서드를 사용하여 데이터를 전달하여 동작을 사용자 지정했습니다. 만든 모든 리소스 및 역할 할당이 포함된 리소스 그룹을 제거할 수 있습니다.
az group delete --name $resourceGroupName
Remove-AzResourceGroup -Name $resourceGroupName