연습 - ARM 템플릿에 배포 스크립트 추가

완료됨

중요

이 연습을 수행하려면 사용자의 Azure 구독이 필요하며 요금이 발생할 수 있습니다. Azure 구독이 아직 없는 경우 시작하기 전에 체험 계정을 만듭니다.

팀의 애플리케이션 배포 프로세스의 일부로 스토리지 계정을 만들고 애플리케이션이 파일을 읽을 수 있도록 BLOB 스토리지에 파일을 스테이징해야 합니다. 지금까지 새 환경이 설정되었을 때마다 파일을 수동으로 복사했습니다. 배포 스크립트를 사용하여 환경 조성 프로세스의 일부로 본 단계를 자동화하기로 결정합니다.

이 연습에서는 기존 ARM(Azure Resource Manager) 템플릿을 사용하고 새 배포 스크립트를 추가합니다.

프로세스 중에 다음을 수행합니다.

  • 시작 템플릿을 만듭니다.
  • 사용자 할당 관리 ID 및 역할 할당을 포함하여 배포 스크립트에 대한 필수 구성 요소를 추가합니다.
  • 배포 스크립트를 추가합니다.
  • 템플릿을 배포하고 결과를 확인합니다.

이 연습에서는 Visual Studio Code용 Azure Resource Manager 도구를 사용합니다. Visual Studio Code에서 해당 확장을 설치해야 합니다.

이 연습에서는 Visual Studio Code용 Bicep 확장을 사용합니다. Visual Studio Code에서 해당 확장을 설치해야 합니다.

시작 템플릿 만들기

팀에서 사용 중인 기존 템플릿으로 시작합니다. 템플릿은 스토리지 계정을 만들고, Blob 서비스를 설정하고, HTTPS가 필요하며, 구성 파일에 대한 Blob 컨테이너를 만듭니다.

  1. Visual Studio Code를 엽니다.

  2. azuredeploy.json이라는 새 파일을 만듭니다.

  3. Visual Studio Code에서 ARM 템플릿 도구가 로드되도록 빈 파일을 저장합니다.

    파일>다른 이름으로 저장을 선택해도 되고 Windows에서 Ctrl+S(macOS는 ⌘+S) 키를 눌러도 됩니다. 파일을 저장한 위치를 기억해야 합니다. 예를 들어 파일을 저장하기 위해 scripts 폴더를 만들 수 있습니다.

  4. 다음 시작 템플릿을 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"
        },
        "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"
                }
            }
        ]
    }
    
  5. 템플릿을 저장하는 경우

  1. Visual Studio Code를 엽니다.

  2. main.bicep이라는 새 파일을 만듭니다.

  3. Visual Studio Code에서 Bicep 도구가 로드되도록 빈 파일을 저장합니다.

    파일>다른 이름으로 저장을 선택해도 되고 Windows에서 Ctrl+S(macOS는 ⌘+S) 키를 눌러도 됩니다. 파일을 저장한 위치를 기억해야 합니다. 예를 들어 파일을 저장할 scripts 폴더를 만들 수 있습니다.

  4. 다음 시작 템플릿을 main.bicep에 복사합니다.

    var storageAccountName = 'storage${uniqueString(resourceGroup().id)}'
    var storageBlobContainerName = 'config'
    
    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'
      }
    }
    
  5. 템플릿을 저장하는 경우

사용자 할당 관리 ID 추가

다음으로, 사용자 할당 관리 ID를 만들어야 합니다. IaC(Infrastructure as Code) 접근 방식을 고려할 때 템플릿에서 ID를 만들 수 있습니다.

  1. 다음을 포함하도록 azuredeploy.jsonvariables 섹션을 편집합니다.

    "userAssignedIdentityName": "configDeployer",
    
  2. 다음을 포함하도록 azuredeploy.jsonresources 섹션을 편집합니다.

    {
        "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
        "apiVersion": "2018-11-30",
        "name": "[variables('userAssignedIdentityName')]",
        "location": "[resourceGroup().location]"
    }
    
  3. 템플릿을 저장하는 경우

  1. main.bicep의 변수 정의에서 다음을 추가합니다.

    var userAssignedIdentityName = 'configDeployer'
    
  2. 리소스 정의에서 다음을 추가합니다.

    resource userAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = {
      name: userAssignedIdentityName
      location: resourceGroup().location
    }
    
  3. 템플릿을 저장하는 경우

관리 ID에 대한 기여자 역할 설정

이제 관리 ID가 정의되었으므로 리소스 그룹에 대한 권한이 있는 역할을 할당할 수 있습니다. 기여자 역할을 할당합니다. 역할 정의 ID(GUID)로 역할을 식별합니다. 기여자 역할은 Azure에 기본 제공되므로 역할 정의 ID가 문서화됩니다.

역할 할당에는 GUID 이름도 필요합니다. guid 함수를 사용하여 리소스 그룹 및 역할 이름에 고유한 GUID를 만들 수 있습니다.

  1. 다음을 포함하도록 azuredeploy.jsonvariables 섹션을 편집합니다.

    "roleAssignmentName": "[guid(concat(resourceGroup().id, 'contributor'))]",
    "contributorRoleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
    
  2. 다음을 포함하도록 azuredeploy.jsonresources 섹션을 편집합니다.

    {
        "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"
        }
    }
    
  3. 템플릿을 저장하는 경우

  1. main.bicep의 변수 정의에서 다음을 추가합니다.

    var roleAssignmentName = guid(resourceGroup().id, 'contributor')
    var contributorRoleDefinitionId = resourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
    
  2. 리소스 정의에서 다음을 추가합니다.

    resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = {
      name: roleAssignmentName
      properties: {
        roleDefinitionId: contributorRoleDefinitionId
        principalId: userAssignedIdentity.properties.principalId
        principalType: 'ServicePrincipal'
      }
    }
    
  3. 템플릿을 저장하는 경우

배포 스크립트 만들기

이제 배포 스크립트에 대한 모든 필수 구성 요소가 있습니다. 배포 스크립트에 필요한 일반적인 값으로 시작합니다. 역할 할당과 Blob Storage 컨테이너의 두 가지 종속성이 있습니다. 스크립트를 실행하려면 두 가지 종속성이 모두 있어야 합니다.

  1. 다음을 포함하도록 azuredeploy.jsonvariables 섹션을 편집합니다.

    "deploymentScriptName": "CopyConfigScript"
    
  2. 다음을 포함하도록 azuredeploy.jsonresources 섹션을 편집합니다.

    {
        "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'))]": {}
            }
        }
    }
    
  3. 리소스에 properties 섹션을 추가하여 스크립트 및 기타 필수 값을 정의합니다.

    "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"
    }
    
  4. 템플릿을 저장하는 경우

  1. main.bicep의 변수 정의에서 다음을 추가합니다.

    var deploymentScriptName = 'CopyConfigScript'
    
  2. 리소스 정의에서 다음을 추가합니다.

    resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
      name: deploymentScriptName
      location: resourceGroup().location
      kind: 'AzurePowerShell'
      identity: {
        type: 'UserAssigned'
        userAssignedIdentities: {
          '${userAssignedIdentity.id}': {}
        }
      }
      dependsOn: [
        roleAssignment
        blobContainer
      ]
    }
    
  3. 리소스에 properties 섹션을 추가하여 스크립트 및 기타 필수 값을 정의합니다.

    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'
    }
    
  4. 템플릿을 저장하는 경우

템플릿 출력 추가

이제 Azure Blob Storage에 파일을 업로드하는 배포 스크립트가 있으므로 이후 자동화에서 해당 파일 위치를 참조해야 할 수 있습니다. (테스트를 실행하여 파일이 있어야 한다고 생각하는 위치에 있는지 확인합니다.)

ARM 템플릿의 resources 섹션 이후에 배포 스크립트에서 보고한 대로 파일에 대한 URI를 참조하는 출력을 추가합니다.

"outputs": {
    "fileUri": {
        "type": "string",
        "value": "[reference(variables('deploymentScriptName')).outputs.Uri]"
    }
}

파일 맨 아래, 리소스 정의 다음에 배포 스크립트에서 보고한 대로 파일에 대한 URI를 참조하는 출력을 추가합니다.

output fileUri string = deploymentScript.properties.outputs.Uri

템플릿 확인

템플릿은 다음과 같습니다.

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

그렇지 않은 경우 예제를 복사하거나 예제와 일치하도록 템플릿을 조정합니다.

템플릿 배포

Azure에 해당 템플릿을 배포하려면 Visual Studio Code 터미널에서 Azure 계정에 로그인해야 합니다. Azure CLI 도구를 설치했는지 확인합니다.

  1. 터미널 메뉴에서 새 터미널을 선택합니다. 터미널 창은 일반적으로 화면의 아래쪽 절반에서 열립니다.

  2. 터미널 창의 오른쪽에 표시된 셸이 bash이면 올바른 셸이 열리고 다음 섹션으로 건너뛸 수 있습니다.

    Bash 옵션이 표시된 Visual Studio Code 터미널 창의 스크린샷

  3. bash 이외의 셸이 나타나면 셸 드롭다운 화살표를 선택한 다음 Azure Cloud Shell(Bash)을 선택합니다.

    표시되어 있는 터미널 셸 드롭다운에서 Git Bash 기본값이 선택된 상태의 Visual Studio Code 터미널 창 스크린샷

  4. 터미널 셸 목록에서 bash를 선택합니다.

    Bash 터미널이 선택되어 있는 Visual Studio Code 터미널 창의 스크린샷

  5. 터미널에서 템플릿을 저장한 디렉터리로 이동합니다. 예를 들어, templates 폴더에 템플릿을 저장한 경우 다음 명령을 사용할 수 있습니다.

    cd templates
    

Azure CLI를 사용하여 Azure에 로그인

  1. Visual Studio Code 터미널에서 다음 명령을 실행하여 Azure에 로그인합니다.

    az login
    
  2. 열리는 브라우저에서 Azure 계정에 로그인합니다.

    Visual Studio Code 터미널에는 이 계정과 연결된 구독 목록이 표시됩니다.

  3. 목록에서 이 연습에 사용할 구독을 찾습니다.

    로그인에서 목록을 누락한 경우 다음 조각을 사용하여 구독을 다시 나열할 수 있습니다.

    az account list --output table
    
  4. 이 세션에서 실행하는 모든 Azure CLI 명령에 대한 기본 구독을 설정합니다.

    az account set --subscription "Your Subscription Name or ID"
    

Azure에 해당 템플릿을 배포하려면 Visual Studio Code 터미널에서 Azure 계정에 로그인해야 합니다. Azure CLI 도구를 설치했는지 확인합니다.

  1. 터미널 메뉴에서 새 터미널을 선택합니다. 터미널 창은 일반적으로 화면의 아래쪽 절반에서 열립니다.

  2. 터미널 창의 오른쪽에 표시된 셸이 bash이면 올바른 셸이 열리고 다음 섹션으로 건너뛸 수 있습니다.

    Bash 옵션이 표시된 Visual Studio Code 터미널 창의 스크린샷

  3. bash 이외의 셸이 나타나면 셸 드롭다운 화살표를 선택한 다음 Azure Cloud Shell(Bash)을 선택합니다.

    표시되어 있는 터미널 셸 드롭다운에서 Git Bash 기본값이 선택된 상태의 Visual Studio Code 터미널 창 스크린샷

  4. 터미널 셸 목록에서 bash를 선택합니다.

    Bash 터미널이 선택되어 있는 Visual Studio Code 터미널 창의 스크린샷

  5. 터미널에서 템플릿을 저장한 디렉터리로 이동합니다. 예를 들어, templates 폴더에 템플릿을 저장한 경우 다음 명령을 사용할 수 있습니다.

    cd templates
    

Bicep 설치

다음 명령을 실행하여 최신 버전의 Bicep이 있는지 확인합니다.

az bicep install && az bicep upgrade

Azure CLI를 사용하여 Azure에 로그인

  1. Visual Studio Code 터미널에서 다음 명령을 실행하여 Azure에 로그인합니다.

    az login
    
  2. 열리는 브라우저에서 Azure 계정에 로그인합니다.

    Visual Studio Code 터미널에는 이 계정과 연결된 구독 목록이 표시됩니다.

  3. 목록에서 이 연습에 사용할 구독을 찾습니다.

    로그인에서 목록을 누락한 경우 다음 조각을 사용하여 구독을 다시 나열할 수 있습니다.

    az account list --output table
    
  4. 이 세션에서 실행하는 모든 Azure CLI 명령에 대한 기본 구독을 설정합니다.

    az account set --subscription "Your Subscription Name or ID"
    

이 템플릿을 Azure에 배포하려면 Visual Studio Code 터미널에서 Azure 계정에 로그인합니다. Azure PowerShell을 설치했고 샌드박스를 활성화한 것과 동일한 계정에 로그인했는지 확인합니다.

  1. 터미널 메뉴에서 새 터미널을 선택합니다. 터미널 창은 일반적으로 화면의 아래쪽 절반에서 열립니다.

  2. 터미널 창의 오른쪽에 표시된 셸이 powershell 또는 pwsh이면 올바른 셸이 열리고 다음 섹션으로 건너뛸 수 있습니다.

    셸 드롭다운 목록에 pwsh 옵션이 표시된 Visual Studio Code 터미널 창의 스크린샷.

  3. powershell 또는 pwsh 이외의 셸이 나타나면 셸 드롭다운 화살표를 선택한 다음, PowerShell을 선택합니다.

    터미널 셸 드롭다운 목록이 표시되고 PowerShell이 선택되어 있는 Visual Studio Code 터미널 창의 스크린샷.

  4. 터미널 셸 목록에서 powershell 또는 pwsh를 선택합니다.

    PowerShell 터미널이 선택되어 있는 Visual Studio Code 터미널 창의 스크린샷.

  5. 터미널에서 템플릿을 저장한 디렉터리로 이동합니다. 예를 들어, templates 폴더에 템플릿을 저장한 경우 다음 명령을 사용할 수 있습니다.

    Set-Location -Path templates
    

Azure PowerShell을 사용하여 Azure에 로그인

  1. Visual Studio Code 터미널에서 다음 명령을 실행하여 Azure에 로그인합니다.

    Connect-AzAccount
    
  2. 열리는 브라우저에서 Azure 계정에 로그인합니다.

  3. 다음 명령을 실행하여 이 연습에 사용할 구독의 ID를 가져옵니다.

    Get-AzSubscription
    

    구독 ID는 두 번째 열입니다. 두 번째 열을 복사합니다. aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e와 비슷하게 보입니다.

  4. 이 세션에서 실행하는 모든 Azure PowerShell 명령에 대한 기본 구독을 설정합니다.

    Set-AzContext -SubscriptionId {Your subscription ID}
    

Azure에 이 템플릿을 배포하려면 Visual Studio Code 터미널에서 Azure 계정에 로그인합니다. Azure PowerShell을 설치했는지 확인합니다.

  1. 터미널 메뉴에서 새 터미널을 선택합니다. 터미널 창은 일반적으로 화면의 아래쪽 절반에서 열립니다.

  2. 터미널 창의 오른쪽에 표시된 셸이 powershell 또는 pwsh이면 올바른 셸이 열리고 다음 섹션으로 건너뛸 수 있습니다.

    셸 드롭다운 목록에 pwsh 옵션이 표시된 Visual Studio Code 터미널 창의 스크린샷.

  3. powershell 또는 pwsh 이외의 셸이 나타나면 셸 드롭다운 화살표를 선택한 다음, PowerShell을 선택합니다.

    터미널 셸 드롭다운 목록이 표시되고 PowerShell이 선택되어 있는 Visual Studio Code 터미널 창의 스크린샷.

  4. 터미널 셸 목록에서 powershell 또는 pwsh를 선택합니다.

    PowerShell 터미널이 선택되어 있는 Visual Studio Code 터미널 창의 스크린샷.

  5. 터미널에서 템플릿을 저장한 디렉터리로 이동합니다. 예를 들어, templates 폴더에 템플릿을 저장한 경우 다음 명령을 사용할 수 있습니다.

    Set-Location -Path templates
    

Bicep CLI 설치

Azure PowerShell에서 Bicep을 사용하려면 Bicep CLI를 설치합니다.

Azure PowerShell을 사용하여 Azure에 로그인

  1. Visual Studio Code 터미널에서 다음 명령을 실행하여 Azure에 로그인합니다.

    Connect-AzAccount
    
  2. 열리는 브라우저에서 Azure 계정에 로그인합니다.

  3. 다음 명령을 실행하여 이 연습에 사용할 구독의 ID를 가져옵니다.

    Get-AzSubscription
    

    구독 ID는 두 번째 열입니다. 두 번째 열을 복사합니다. aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e와 비슷하게 보입니다.

  4. 이 세션에서 실행하는 모든 Azure PowerShell 명령에 대한 기본 구독을 설정합니다.

    Set-AzContext -SubscriptionId {Your subscription ID}
    

다음으로, 이 연습의 일부로 만들 리소스를 포함하는 리소스 그룹을 만들어야 합니다. 새 리소스 그룹을 사용하면 연습 후 정리를 훨씬 쉽게 수행할 수 있습니다.

Visual Studio Code의 터미널에서 이 명령을 실행하여 이 연습에 대한 리소스 그룹을 만듭니다.

연습에 대한 리소스 그룹 만들기

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

참고

리소스 그룹에 다른 이름을 사용하는 경우 스크립트를 업데이트해야 합니다. 본 모듈의 뒷부분에서는 스크립트에서 리소스 그룹 이름을 하드 코딩하지 않는 방법을 알아봅니다.

Azure에 템플릿 배포

다음 코드는 ARM 템플릿을 Azure에 배포합니다. 배포 성공 메시지가 표시됩니다.

Visual Studio Code 터미널에서 Azure CLI 명령을 사용하여 템플릿을 배포합니다.

templateFile="azuredeploy.json"
today=$(date +"%d-%b-%Y")
deploymentName="deploymentscript-"$today

az deployment group create \
    --resource-group $resourceGroupName \
    --name $deploymentName \
    --template-file $templateFile

다음 코드는 ARM 템플릿을 Azure에 배포합니다. 배포 성공 메시지가 표시됩니다.

Visual Studio Code 터미널에서 Azure CLI 명령을 사용하여 템플릿을 배포합니다.

templateFile="main.bicep"
today=$(date +"%d-%b-%Y")
deploymentName="deploymentscript-"$today

az deployment group create \
    --resource-group $resourceGroupName \
    --name $deploymentName \
    --template-file $templateFile

다음 코드는 템플릿을 Azure에 배포합니다. 배포 성공 메시지가 표시됩니다.

터미널에서 Azure PowerShell 명령을 사용하여 템플릿을 배포합니다.

$templateFile = 'azuredeploy.json'
$today = Get-Date -Format 'MM-dd-yyyy'
$deploymentName = "deploymentscript-$today"
New-AzResourceGroupDeployment `
  -ResourceGroupName $resourceGroupName `
  -Name $deploymentName `
  -TemplateFile $templateFile

다음 코드는 템플릿을 Azure에 배포합니다. 배포 성공 메시지가 표시됩니다.

터미널에서 Azure PowerShell 명령을 사용하여 템플릿을 배포합니다.

$templateFile = 'main.bicep'
$today = Get-Date -Format 'MM-dd-yyyy'
$deploymentName = "deploymentscript-$today"
New-AzResourceGroupDeployment `
  -ResourceGroupName $resourceGroupName `
  -Name $deploymentName `
  -TemplateFile $templateFile

템플릿의 결과 검토

배포가 완료되면 배포 스크립트가 Blob Storage에 복사한 파일을 가리키는 URL이 제공됩니다.

  1. 템플릿 배포의 URL 출력으로 해당 파일을 검색하여 배포 스크립트가 제대로 작동하는지 확인합니다.

    uri=$(az deployment group show --resource-group $resourceGroupName --name $deploymentName --query 'properties.outputs.fileUri.value' --output tsv)
    curl $uri
    

    이 명령은 다음 코드를 반환합니다.

    {
      "environment": "production",
      "hostname": "tailwindtraders.com",
      "Logging": {
        "LogLevel": {
          "Default": "Debug"
        }
      },
      "ApplicationInsights": {
        "InstrumentationKey": ""
      },
      "AllowedHosts": "*",
      "CosmosDb": {
        "Host": "",
        "Key": "",
        "Database": "Products"
      }
    }
    
  2. Azure Portal에서 또는 다음 명령을 사용하여 로그(및 배포에 대한 기타 세부 정보)를 검토할 수도 있습니다.

    az deployment-scripts show-log --resource-group $resourceGroupName --name CopyConfigScript
    
  1. 템플릿 배포의 URL 출력으로 해당 파일을 검색하여 배포 스크립트가 제대로 작동하는지 확인합니다.

    $fileUri = (Get-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName).Outputs.fileUri.Value
    Invoke-RestMethod $fileUri
    

    이 명령은 다음 코드를 반환합니다.

    environment         : production
    hostname            : tailwindtraders.com
    Logging             : @{LogLevel=}
    ApplicationInsights : @{InstrumentationKey=}
    AllowedHosts        : *
    CosmosDb            : @{Host=; Key=; Database=Products}
    
  2. Azure Portal에서 또는 다음 명령줄을 사용하여 로그(및 배포에 대한 기타 세부 정보)를 검토할 수도 있습니다.

    Get-AzDeploymentScriptLog -ResourceGroupName $resourceGroupName -Name CopyConfigScript
    

리소스 그룹 정리

배포 스크립트를 사용하여 ARM 템플릿을 성공적으로 배포했으므로 만든 모든 리소스 및 역할 할당이 포함된 리소스 그룹을 제거할 수 있습니다.

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