자습서: 배포 스크립트를 사용하여 자체 서명된 인증서 만들기
ARM 템플릿(Azure Resource Manager 템플릿)에서 배포 스크립트를 사용하는 방법을 알아봅니다. 배포 스크립트를 사용하여 ARM 템플릿으로 수행할 수 없는 사용자 지정 단계를 수행할 수 있습니다. 예를 들어 자체 서명된 인증서를 만듭니다. 이 자습서에서는 Azure 키 자격 증명 모음을 배포하는 템플릿을 만들고, 동일한 템플릿의 Microsoft.Resources/deploymentScripts
리소스를 사용하여 인증서를 만든 다음, 이 인증서를 키 자격 증명 모음에 추가합니다. 배포 스크립트에 대한 자세한 내용은 ARM 템플릿에서 배포 스크립트 사용을 참조하세요.
Important
스크립트를 실행하고 문제를 해결하기 위해 두 개의 배포 스크립트 리소스, 즉 스토리지 계정과 컨테이너 인스턴스가 동일한 리소스 그룹에 만들어집니다. 일반적으로 스크립트 실행이 터미널 상태가 되면 스크립트 서비스에서 이러한 리소스를 삭제합니다. 리소스가 삭제될 때까지 해당 리소스에 대한 요금이 청구됩니다. 자세한 내용은 배포 스크립트 리소스 정리를 참조하세요.
이 자습서에서 다루는 작업은 다음과 같습니다.
- 빠른 시작 템플릿 열기
- 템플릿 편집
- 템플릿 배포
- 실패한 스크립트 디버그
- 리소스 정리
배포 스크립트를 다루는 Learn 모듈은 배포 스크립트를 사용하여 ARM 템플릿 확장을 참조하세요.
필수 조건
이 문서를 완료하려면 다음이 필요합니다.
Resource Manager Tools 확장이 있는 Visual Studio Code 빠른 시작: Visual Studio Code를 사용하여 ARM 템플릿 만들기를 참조하세요.
사용자가 할당한 관리 ID. 이 ID는 스크립트에서 Azure 관련 작업을 수행하는 데 사용됩니다. ID를 만들려면 사용자가 할당한 관리 ID를 참조하세요. 이 ID는 템플릿을 배포할 때 필요합니다. ID의 형식은 다음과 같습니다.
/subscriptions/<SubscriptionID>/resourcegroups/<ResourceGroupName>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<IdentityID>
다음 CLI 스크립트를 통해 리소스 그룹 이름과 ID 이름을 제공하여 ID를 가져옵니다.
echo "Enter the Resource Group name:" && read resourceGroupName && az identity list -g $resourceGroupName
빠른 시작 템플릿 열기
템플릿을 처음부터 만드는 대신 Azure 빠른 시작 템플릿에서 템플릿을 엽니다. Azure 빠른 시작 템플릿은 ARM 템플릿용 리포지토리입니다.
이 빠른 시작에서 사용되는 템플릿을 Create an Azure Key Vault and a secret(Azure Key Vault 및 비밀 만들기)이라고 합니다. 템플릿은 키 자격 증명 모음을 만든 다음, 비밀을 이 키 자격 증명 모음에 추가합니다.
Visual Studio Code에서 파일>파일 열기를 차례로 선택합니다.
파일 이름에서 다음 URL을 붙여넣습니다.
https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.keyvault/key-vault-create/azuredeploy.json
열기를 선택하여 파일을 엽니다.
파일>이름으로 저장을 차례로 선택하여 파일을 azuredeploy.json으로 저장합니다.
템플릿 편집
템플릿을 다음과 같이 변경합니다.
템플릿 정리(선택 사항)
원본 템플릿은 비밀을 키 자격 증명 모음에 추가합니다. 자습서를 간소화하기 위해 다음 리소스를 제거합니다.
Microsoft.KeyVault/vaults/secrets
다음 두 매개 변수 정의를 제거합니다.
secretName
secretValue
이러한 정의를 제거하지 않도록 선택하는 경우 배포 중에 매개 변수 값을 지정해야 합니다.
키 자격 증명 모음 액세스 정책 구성
배포 스크립트는 인증서를 키 자격 증명 모음에 추가합니다. 권한을 관리 ID에 부여하도록 키 자격 증명 모음 액세스 정책을 구성합니다.
관리 ID를 가져오는 매개 변수를 추가합니다.
"identityId": { "type": "string", "metadata": { "description": "Specifies the ID of the user-assigned managed identity." } },
참고 항목
Visual Studio Code의 Resource Manager 템플릿 확장은 아직 배포 스크립트의 형식을 지정할 수 없습니다. 다음과 같이 Shift+Alt+F를 사용하여
deploymentScripts
리소스의 형식을 지정하지 마세요.관리 ID에서 인증서를 키 자격 증명 모음에 추가할 수 있도록 키 자격 증명 모음 액세스 정책을 구성하는 매개 변수를 추가합니다.
"certificatesPermissions": { "type": "array", "defaultValue": [ "get", "list", "update", "create" ], "metadata": { "description": "Specifies the permissions to certificates in the vault. Valid values are: all, get, list, update, create, import, delete, recover, backup, restore, manage contacts, manage certificate authorities, get certificate authorities, list certificate authorities, set certificate authorities, delete certificate authorities." } }
기존 키 자격 증명 모음 액세스 정책을 다음으로 업데이트합니다.
"accessPolicies": [ { "objectId": "[parameters('objectId')]", "tenantId": "[parameters('tenantId')]", "permissions": { "keys": "[parameters('keysPermissions')]", "secrets": "[parameters('secretsPermissions')]", "certificates": "[parameters('certificatesPermissions')]" } }, { "objectId": "[reference(parameters('identityId'), '2018-11-30').principalId]", "tenantId": "[parameters('tenantId')]", "permissions": { "keys": "[parameters('keysPermissions')]", "secrets": "[parameters('secretsPermissions')]", "certificates": "[parameters('certificatesPermissions')]" } } ],
두 가지 정책, 즉 로그인한 사용자에 대한 정책과 관리 ID에 대한 정책이 정의되어 있습니다. 로그인한 사용자에게는 배포를 확인할 수 있는 list(목록) 권한만 있으면 됩니다. 자습서를 간소화하기 위해 관리 ID와 로그인한 사용자 둘 모두에 동일한 인증서가 할당됩니다.
배포 스크립트 추가
배포 스크립트에서 사용하는 세 개의 매개 변수를 추가합니다.
"certificateName": { "type": "string", "defaultValue": "DeploymentScripts2019" }, "subjectName": { "type": "string", "defaultValue": "CN=contoso.com" }, "utcValue": { "type": "string", "defaultValue": "[utcNow()]" }
deploymentScripts
리소스를 추가합니다.참고 항목
인라인 배포 스크립트는 큰따옴표로 묶여 있으므로 배포 스크립트 내의 문자열을 작은따옴표로 묶어야 합니다. PowerShell 이스케이프 문자는 backtick(
`
)입니다.{ "type": "Microsoft.Resources/deploymentScripts", "apiVersion": "2020-10-01", "name": "createAddCertificate", "location": "[resourceGroup().location]", "dependsOn": [ "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" ], "identity": { "type": "UserAssigned", "userAssignedIdentities": { "[parameters('identityId')]": { } } }, "kind": "AzurePowerShell", "properties": { "forceUpdateTag": "[parameters('utcValue')]", "azPowerShellVersion": "3.0", "timeout": "PT30M", "arguments": "[format(' -vaultName {0} -certificateName {1} -subjectName {2}', parameters('keyVaultName'), parameters('certificateName'), parameters('subjectName'))]", // can pass an argument string, double quotes must be escaped "scriptContent": " param( [string] [Parameter(Mandatory=$true)] $vaultName, [string] [Parameter(Mandatory=$true)] $certificateName, [string] [Parameter(Mandatory=$true)] $subjectName ) $ErrorActionPreference = 'Stop' $DeploymentScriptOutputs = @{} $existingCert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName if ($existingCert -and $existingCert.Certificate.Subject -eq $subjectName) { Write-Host 'Certificate $certificateName in vault $vaultName is already present.' $DeploymentScriptOutputs['certThumbprint'] = $existingCert.Thumbprint $existingCert | Out-String } else { $policy = New-AzKeyVaultCertificatePolicy -SubjectName $subjectName -IssuerName Self -ValidityInMonths 12 -Verbose # private key is added as a secret that can be retrieved in the Resource Manager template Add-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName -CertificatePolicy $policy -Verbose # it takes a few seconds for KeyVault to finish $tries = 0 do { Write-Host 'Waiting for certificate creation completion...' Start-Sleep -Seconds 10 $operation = Get-AzKeyVaultCertificateOperation -VaultName $vaultName -Name $certificateName $tries++ if ($operation.Status -eq 'failed') { throw 'Creating certificate $certificateName in vault $vaultName failed with error $($operation.ErrorMessage)' } if ($tries -gt 120) { throw 'Timed out waiting for creation of certificate $certificateName in vault $vaultName' } } while ($operation.Status -ne 'completed') $newCert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName $DeploymentScriptOutputs['certThumbprint'] = $newCert.Thumbprint $newCert | Out-String } ", "cleanupPreference": "OnSuccess", "retentionInterval": "P1D" } }
deploymentScripts
리소스는 키 자격 증명 모음 리소스 및 역할 할당 리소스에 따라 달라집니다. 다음과 같은 속성이 있습니다.identity
: 배포 스크립트는 사용자가 할당한 관리 ID를 사용하여 스크립트에서 작업을 수행합니다.kind
: 스크립트 유형을 지정합니다. 현재 PowerShell 스크립트만 지원됩니다.forceUpdateTag
: 스크립트 원본이 변경되지 않은 경우에도 배포 스크립트를 실행할지 여부를 결정합니다. 현재 타임스탬프 또는 GUID일 수 있습니다. 자세한 내용은 스크립트를 두 번 이상 실행을 참조하세요.azPowerShellVersion
: 사용할 Azure PowerShell 모듈 버전을 지정합니다. 배포 스크립트는 현재 2.7.0, 2.8.0 및 3.0.0 버전을 지원합니다.timeout
: ISO 8601 형식에 지정된 최대 허용 스크립트 실행 시간을 지정합니다. 기본값은 P1D입니다.arguments
: 매개 변수 값을 지정합니다. 값은 공백으로 구분됩니다.scriptContent
: 스크립트 콘텐츠를 지정합니다. 외부 스크립트를 실행하려면primaryScriptURI
를 대신 사용합니다. 자세한 내용은 외부 스크립트 사용을 참조하세요. 로컬 머신에서 스크립트를 테스트하는 경우에만$DeploymentScriptOutputs
를 선언해야 합니다. 이 변수를 선언하면 스크립트를 변경하지 않고도 로컬 머신과deploymentScript
리소스에서 실행할 수 있습니다.$DeploymentScriptOutputs
에 할당된 값은 배포에서 출력으로 사용할 수 있습니다. 자세한 내용은 PowerShell 배포 스크립트의 출력 작업 또는 CLI 배포 스크립트의 출력 작업을 참조하세요.cleanupPreference
: 배포 스크립트 리소스를 삭제할 시간에 대한 기본 설정을 지정합니다. 기본값은 Always(항상)이며, 이는 터미널 상태(성공, 실패, 취소됨)에도 불구하고 배포 스크립트 리소스가 삭제됨을 의미합니다. 이 자습서에서는 OnSuccess가 사용되므로 스크립트 실행 결과를 볼 수 있습니다.retentionInterval
: 서비스가 터미널 상태에 도달되면 스크립트 리소스를 유지하는 간격을 지정합니다. 이 기간이 만료되면 리소스가 삭제됩니다. 기간은 ISO 8601 패턴을 기반으로 합니다. 이 자습서에서는 하루를 의미하는 P1D를 사용합니다. 이 속성은cleanupPreference
가 OnExpiration으로 설정된 경우 사용됩니다. 이 속성은 현재 활성화되어 있지 않습니다.
배포 스크립트는
keyVaultName
,certificateName
및subjectName
의 세 가지 매개 변수를 사용합니다. 인증서를 만든 다음, 인증서를 키 자격 증명 모음에 추가합니다.$DeploymentScriptOutputs
는 출력 값을 저장하는 데 사용됩니다. 자세한 내용은 PowerShell 배포 스크립트의 출력 작업 또는 CLI 배포 스크립트의 출력 작업을 참조하세요.완성된 템플릿은 여기서 찾을 수 있습니다.
디버깅 프로세스를 확인하려면 다음 줄을 배포 스크립트에 추가하여 오류를 코드에 배치합니다.
Write-Output1 $keyVaultName
올바른 명령은
Write-Output1
대신Write-Output
입니다.파일>저장을 차례로 선택하여 파일을 저장합니다.
템플릿 배포
Azure Cloud Shell에 로그인
왼쪽 위 모서리에서 PowerShell 또는 Bash(CLI용)를 선택하여 기본 환경을 선택합니다. 전환하는 경우 셸을 다시 시작해야 합니다.
파일 업로드/다운로드를 선택한 다음, 업로드를 선택합니다. 이전 스크린샷을 참조하세요. 이전 섹션에서 저장한 파일을 선택합니다. 파일을 업로드한 후
ls
명령 및cat
명령을 사용하여 파일이 성공적으로 업로드되었는지 확인할 수 있습니다.다음 Azure CLI 또는 Azure PowerShell 스크립트를 실행하여 템플릿을 배포합니다.
echo "Enter a project name that is used to generate resource names:" && read projectName && echo "Enter the location (i.e. centralus):" && read location && echo "Enter your email address used to sign in to Azure:" && read upn && echo "Enter the user-assigned managed identity ID:" && read identityId && adUserId=$((az ad user show --id ${upn}) | jq -r '.id') && resourceGroupName="${projectName}rg" && keyVaultName="${projectName}kv" && az group create --name $resourceGroupName --location $location && az deployment group create --resource-group $resourceGroupName --template-file "$HOME/azuredeploy.json" --parameters identityId=$identityId keyVaultName=$keyVaultName objectId=$adUserId
배포 스크립트 서비스에서 스크립트 실행을 위한 추가 배포 스크립트 리소스를 만들어야 합니다. 준비 및 정리 프로세스는 실제 스크립트 실행 시간 외에도 완료하는 데 최대 1분 정도 걸릴 수 있습니다.
스크립트에
Write-Output1
이 사용되는 잘못된 명령으로 인해 배포에 실패했습니다. 다음과 같은 오류 메시지가 표시됩니다.The term 'Write-Output1' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
배포 스크립트 실행 결과는 문제 해결을 위해 배포 스크립트 리소스에 저장됩니다.
실패한 스크립트 디버그
Azure Portal에 로그인합니다.
리소스 그룹을 엽니다. rg가 추가된 프로젝트 이름입니다. 리소스 그룹에 두 개의 추가 리소스가 표시됩니다. 이러한 리소스는 배포 스크립트 리소스라고 합니다.
두 파일에는 모두 azscripts 접미사가 있습니다. 하나는 스토리지 계정이고, 다른 하나는 컨테이너 인스턴스입니다.
숨겨진 형식 표시를 선택하여
deploymentScripts
리소스를 나열합니다.azscripts 접미사가 있는 스토리지 계정을 선택합니다.
파일 공유 타일을 선택합니다. 배포 스크립트 실행 파일이 포함된 azscripts 폴더가 표시됩니다.
azscripts를 선택합니다. azscriptinput 및 azscriptoutput의 두 폴더가 표시됩니다. 입력 폴더에는 시스템 PowerShell 스크립트 파일과 사용자 배포 스크립트 파일이 포함되어 있습니다. 출력 폴더에는 executionresult.json 및 스크립트 출력 파일이 포함되어 있습니다. executionresult.json에서 오류 메시지를 볼 수 있습니다. 실행이 실패하여 출력 파일이 없습니다.
Write-Output1
줄을 제거하고, 해당 템플릿을 다시 배포합니다.
두 번째 배포가 성공적으로 실행되면 cleanupPreference
속성이 OnSuccess로 설정되어 있으므로 스크립트 서비스에서 배포 스크립트 리소스를 제거합니다.
리소스 정리
Azure 리소스가 더 이상 필요하지 않은 경우 리소스 그룹을 삭제하여 배포한 리소스를 정리합니다.
- Azure Portal의 왼쪽 메뉴에서 리소스 그룹을 선택합니다.
- 이름으로 필터링 필드에서 리소스 그룹 이름을 입력합니다.
- 해당 리소스 그룹 이름을 선택합니다.
- 위쪽 메뉴에서 리소스 그룹 삭제를 선택합니다.
다음 단계
이 자습서에서는 ARM 템플릿에서 배포 스크립트를 사용하는 방법을 알아보았습니다. 조건에 따라 Azure 리소스를 배포하는 방법을 배우려면 다음을 참조하세요.