다음을 통해 공유


ARM 및 Bicep을 사용하여 배포를 실행하도록 컨테이너 이미지 구성

이 문서에서는 사용자 지정 ARM(Azure Resource Manager) 및 Bicep 컨테이너 이미지를 빌드하여 ADE(Azure Deployment Environments)에 환경 정의를 배포하는 방법을 알아봅니다.

환경 정의는 최소한 두 개의 파일, 즉 azuredeploy.json 또는 main.bicep과 같은 템플릿 파일과 environment.yaml이라는 매니페스트 파일로 구성됩니다. ADE는 컨테이너를 사용하여 환경 정의를 배포하고 기본적으로 ARM 및 Bicep IaC 프레임워크를 지원합니다.

ADE 확장성 모델을 사용하면 환경 정의에서 사용할 사용자 지정 컨테이너 이미지를 만들 수 있습니다. 확장성 모델을 사용하면 고유한 사용자 지정 컨테이너 이미지를 만들고 DockerHub와 같은 컨테이너 레지스트리에 저장할 수 있습니다. 그런 다음 환경 정의에서 이러한 이미지를 참조하여 환경을 배포할 수 있습니다.

ADE 팀은 핵심 이미지와 ARM(Azure Resource Manager)/Bicep 이미지를 포함하여 시작하는 데 필요한 다양한 이미지를 제공합니다. Runner-Images 폴더에서 이러한 샘플 이미지에 액세스할 수 있습니다.

필수 조건

ADE에서 컨테이너 이미지 사용

ADE에서 컨테이너 이미지를 사용하려면 다음 방식 중 하나를 사용할 수 있습니다.

  • 표준 컨테이너 이미지 사용: 간단한 시나리오의 경우 ADE에서 제공하는 표준 Bicep 컨테이너 이미지를 사용합니다.
  • 사용자 지정 컨테이너 이미지 만들기: 더 복잡한 시나리오의 경우 특정 요구 사항을 충족하는 사용자 지정 컨테이너 이미지를 만듭니다.

어떤 방식을 선택하든 관계없이 Azure 리소스를 배포하려면 환경 정의에서 컨테이너 이미지를 지정해야 합니다.

표준 Bicep 컨테이너 이미지 사용

ADE는 기본적으로 Bicep을 지원하므로 카탈로그에 템플릿 파일(azuredeploy.json 및 Environment.yaml)을 추가하여 배포 환경에 Azure 리소스를 배포하는 환경 정의를 구성할 수 있습니다. 그런 다음 ADE는 표준 Bicep 컨테이너 이미지를 사용하여 배포 환경을 만듭니다.

Environment.yaml 파일에서 실행기 속성은 사용하려는 컨테이너 이미지의 위치를 ​​지정합니다. Microsoft 아티팩트 레지스트리에 게시된 샘플 이미지를 사용하려면 다음 표에 나열된 해당 식별자 실행기를 사용합니다.

다음 예에서는 샘플 Bicep 컨테이너 이미지를 참조하는 실행기를 보여 줍니다.

    name: WebApp
    version: 1.0.0
    summary: Azure Web App Environment
    description: Deploys a web app in Azure without a datastore
    runner: Bicep
    templatePath: azuredeploy.json

ARM-Bicep용 Runner-Images 폴더 이미지 아래의 ADE 샘플 리포지토리에서 표준 Bicep 컨테이너 이미지를 볼 수 있습니다.

ADE 컨테이너 이미지를 사용하여 Azure 리소스를 배포하는 환경 정의를 만드는 방법에 대한 자세한 내용은 환경 정의 추가 및 구성을 참조하세요.

사용자 지정 Bicep 컨테이너 이미지 만들기

사용자 지정 컨테이너 이미지를 만들면 요구 사항에 맞게 배포를 사용자 지정할 수 있습니다. ADE 표준 컨테이너 이미지를 기반으로 사용자 지정 이미지를 만들 수 있습니다.

이미지 사용자 지정을 완료한 후에는 이미지를 빌드하고 컨테이너 레지스트리에 푸시해야 합니다.

Docker를 사용하여 컨테이너 이미지 만들기 및 사용자 지정

이 예에서는 ADE 배포를 활용하고 ADE 빌드 이미지 중 하나를 기반으로 이미지를 기반으로 ADE CLI에 액세스하기 위해 Docker 이미지를 빌드하는 방법을 알아봅니다.

ADE CLI는 ADE 기본 이미지를 사용하여 사용자 지정 이미지를 빌드할 수 있는 도구입니다. ADE CLI를 사용하여 워크플로에 맞게 배포 및 삭제를 사용자 지정할 수 있습니다. ADE CLI는 샘플 이미지에 사전 설치되어 있습니다. ADE CLI에 대해 자세히 알아보려면 CLI 사용자 지정 실행기 이미지 참조를 확인합니다.

ADE용으로 구성된 이미지를 만들려면 다음 단계를 따릅니다.

  1. ADE에서 제작한 샘플 이미지 또는 FROM 문을 사용하여 선택한 이미지를 기반으로 합니다.
  2. RUN 문을 사용하여 이미지에 필요한 패키지를 설치합니다.
  3. Dockerfile과 같은 레벨에 스크립트 폴더를 만들고, 그 안에 deploy.shdelete.sh 파일을 저장한 다음, 생성한 컨테이너 내에서 해당 스크립트를 검색하고 실행할 수 있는지 확인합니다. 배포가 ADE 핵심 이미지를 사용하여 작동하려면 이 단계가 필요합니다.

FROM 문을 사용하여 샘플 컨테이너 이미지를 선택합니다.

Microsoft 아티팩트 레지스트리에서 호스트되는 샘플 이미지를 가리키는 새 이미지에 대해 만들어진 DockerFile 내에 FROM 문을 포함합니다.

다음은 샘플 코어 이미지를 참조하는 FROM 문의 예입니다.

FROM mcr.microsoft.com/deployment-environments/runners/core:latest

이 문은 가장 최근에 게시된 핵심 이미지를 끌어와 사용자 지정 이미지의 기반으로 만듭니다.

Dockerfile에 Bicep 설치

다음 예와 같이 RUN 문을 사용하여 Azure CLI로 Bicep 패키지를 설치할 수 있습니다.

RUN az bicep install

ADE 샘플 이미지는 Azure CLI 이미지를 기반으로 하며 ADE CLI 및 JQ 패키지가 미리 설치되어 있습니다. Azure CLIJQ 패키지에 대해 자세히 알아볼 수 있습니다.

이미지 내에 필요한 패키지를 더 설치하려면 RUN 문을 사용합니다.

작업 셸 스크립트 실행

샘플 이미지 내에서는 작업 이름을 기준으로 작업이 결정되고 실행됩니다. 현재 지원되는 두 가지 작업 이름은 deploydelete입니다.

이 구조를 활용하도록 사용자 지정 이미지를 설정하려면 Dockerfile 수준에서 scripts라는 폴더를 지정하고 deploy.shdelete.sh라는 두 파일을 지정합니다. 배포 셸 스크립트는 환경이 만들어지거나 다시 배포될 때 실행되고, 삭제 셸 스크립트는 환경이 삭제될 때 실행됩니다. ARM-Bicep용 Runner-Images 폴더 이미지 아래 리포지토리에서 셸 스크립트의 예를 볼 수 있습니다.

이러한 셸 스크립트가 실행 가능하도록 하려면 Dockerfile에 다음 줄을 추가합니다.

COPY scripts/* /scripts/
RUN find /scripts/ -type f -iname "*.sh" -exec dos2unix '{}' '+'
RUN find /scripts/ -type f -iname "*.sh" -exec chmod +x {} \;

ARM 또는 Bicep 템플릿을 배포하기 위한 작업 셸 스크립트 작성

ADE를 통해 ARM 또는 Bicep 인프라를 성공적으로 배포하려면 다음을 수행해야 합니다.

  • ADE 매개 변수를 ARM에서 허용되는 매개 변수로 변환
  • 배포에 사용되는 경우 연결된 템플릿을 확인합니다.
  • 권한 있는 관리 ID를 사용하여 배포 수행

코어 이미지의 진입점 동안 현재 환경에 대해 설정된 모든 매개 변수는 변수 $ADE_OPERATION_PARAMETERS 아래에 저장됩니다. 이를 ARM에서 허용되는 매개 변수로 변환하려면 JQ를 사용하여 다음 명령을 실행할 수 있습니다.

# format the parameters as arm parameters
deploymentParameters=$(echo "$ADE_OPERATION_PARAMETERS" | jq --compact-output '{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": (to_entries | if length == 0 then {} else (map( { (.key): { "value": .value } } ) | add) end) }' )

다음으로, ARM JSON 기반 템플릿 내에서 사용되는 링크된 템플릿을 확인하려면 기본 템플릿 파일을 디컴파일하면 됩니다. 이 파일은 많은 Bicep 모듈에 사용되는 모든 로컬 인프라 파일을 확인합니다. 그런 다음 해당 모듈을 기본 ARM 템플릿에 중첩 템플릿으로 포함된 연결된 템플릿을 사용하여 단일 ARM 템플릿으로 다시 빌드합니다. 이 단계는 배포 작업 중에만 필요합니다. 기본 템플릿 파일은 코어 이미지 진입점에서 설정된 $ADE_TEMPLATE_FILE을 사용하여 지정할 수 있으며, 다시 컴파일된 템플릿 파일을 사용하여 이 변수를 다시 설정해야 합니다. 다음 예제를 참조하십시오.

if [[ $ADE_TEMPLATE_FILE == *.json ]]; then

    hasRelativePath=$( cat $ADE_TEMPLATE_FILE | jq '[.. | objects | select(has("templateLink") and (.templateLink | has("relativePath")))] | any' )

    if [ "$hasRelativePath" = "true" ]; then
        echo "Resolving linked ARM templates"

        bicepTemplate="${ADE_TEMPLATE_FILE/.json/.bicep}"
        generatedTemplate="${ADE_TEMPLATE_FILE/.json/.generated.json}"

        az bicep decompile --file "$ADE_TEMPLATE_FILE"
        az bicep build --file "$bicepTemplate" --outfile "$generatedTemplate"

        # Correctly reassign ADE_TEMPLATE_FILE without the $ prefix during assignment
        ADE_TEMPLATE_FILE="$generatedTemplate"
    fi
fi

구독 내에서 리소스 배포 및 삭제를 실행하는 데 배포에 필요한 권한을 제공하려면 ADE 프로젝트 환경 유형과 연결된 권한 있는 관리 ID를 사용합니다. 배포를 완료하기 위해 특정 역할과 같은 특별 권한이 필요한 경우 해당 역할을 프로젝트 환경 유형의 ID에 할당합니다. 컨테이너에 들어갈 때 관리 ID를 즉시 사용할 수 없는 경우도 있습니다. 로그인이 성공할 때까지 다시 시도할 수 있습니다.

echo "Signing into Azure using MSI"
while true; do
    # managed identity isn't available immediately
    # we need to do retry after a short nap
    az login --identity --allow-no-subscriptions --only-show-errors --output none && {
        echo "Successfully signed into Azure"
        break
    } || sleep 5
done

ARM 또는 Bicep 템플릿 배포를 시작하려면 az deployment group create 명령을 실행합니다. 컨테이너 내에서 이 명령을 실행할 때 이전 배포를 재정의하지 않는 배포 이름을 선택하고 다음 예와 같이 --no-prompt true--only-show-errors 플래그를 사용하여 경고로 인해 배포가 실패하거나 사용자 입력을 기다리는 동안 중단되지 않도록 합니다.

deploymentName=$(date +"%Y-%m-%d-%H%M%S")
az deployment group create --subscription $ADE_SUBSCRIPTION_ID \
    --resource-group "$ADE_RESOURCE_GROUP_NAME" \
    --name "$deploymentName" \
    --no-prompt true --no-wait \
    --template-file "$ADE_TEMPLATE_FILE" \
    --parameters "$deploymentParameters" \
    --only-show-errors

환경을 삭제하려면 다음 예와 같이 전체 모드 배포를 수행하고 지정된 ADE 리소스 그룹 내의 모든 리소스를 제거하는 빈 ARM 템플릿을 제공합니다.

deploymentName=$(date +"%Y-%m-%d-%H%M%S")
az deployment group create --resource-group "$ADE_RESOURCE_GROUP_NAME" \
    --name "$deploymentName" \
    --no-prompt true --no-wait --mode Complete \
    --only-show-errors \
    --template-file "$DIR/empty.json"

아래 명령을 실행하여 프로비전 상태 및 세부 정보를 확인할 수 있습니다. ADE는 몇 가지 특수 함수를 사용하여 Runner-Images 폴더에서 찾을 수 있는 프로비전 세부 정보를 기반으로 더 많은 컨텍스트를 읽고 제공합니다. 간단한 구현은 다음과 같습니다.

if [ $? -eq 0 ]; then # deployment successfully created
    while true; do

        sleep 1

        ProvisioningState=$(az deployment group show --resource-group "$ADE_RESOURCE_GROUP_NAME" --name "$deploymentName" --query "properties.provisioningState" -o tsv)
        ProvisioningDetails=$(az deployment operation group list --resource-group "$ADE_RESOURCE_GROUP_NAME" --name "$deploymentName")

        echo "$ProvisioningDetails"

        if [[ "CANCELED|FAILED|SUCCEEDED" == *"${ProvisioningState^^}"* ]]; then

            echo -e "\nDeployment $deploymentName: $ProvisioningState"

            if [[ "CANCELED|FAILED" == *"${ProvisioningState^^}"* ]]; then
                exit 11
            else
                break
            fi
        fi
    done
fi

마지막으로 배포 출력을 보고 ADE에 전달하여 Azure CLI를 통해 액세스할 수 있도록 하려면 다음 명령을 실행하면 됩니다.

deploymentOutput=$(az deployment group show -g "$ADE_RESOURCE_GROUP_NAME" -n "$deploymentName" --query properties.outputs)
if [ -z "$deploymentOutput" ]; then
    deploymentOutput="{}"
fi
echo "{\"outputs\": $deploymentOutput}" > $ADE_OUTPUTS

ADE에서 사용자 지정 이미지에 액세스할 수 있도록 설정

ADE에서 사용할 수 있도록 하려면 Docker 이미지를 빌드하고 컨테이너 레지스트리에 푸시해야 합니다. Docker CLI를 사용하거나 ADE에서 제공하는 스크립트를 사용하여 이미지를 빌드할 수 있습니다.

각 방식에 대해 자세히 알아보려면 해당 탭을 선택합니다.

레지스트리에 푸시할 이미지를 빌드하기 전에 컴퓨터에 Docker 엔진이 설치되어 있는지 확인합니다. 그런 다음 Dockerfile 디렉터리로 이동하여 다음 명령을 실행합니다.

docker build . -t {YOUR_REGISTRY}.azurecr.io/{YOUR_REPOSITORY}:{YOUR_TAG}

예를 들어, customImage라는 레지스트리 내의 리포지토리에 이미지를 저장하고 1.0.0 태그 버전으로 업로드하려면 다음을 실행합니다.

docker build . -t {YOUR_REGISTRY}.azurecr.io/customImage:1.0.0

Docker 이미지를 레지스트리에 푸시

사용자 지정 이미지를 사용하려면 익명 이미지 끌어오기가 사용하도록 설정된 공개적으로 액세스 가능한 이미지 레지스트리를 설정해야 합니다. 이러한 방식으로 Azure Deployment Environments는 사용자 지정 이미지에 액세스하여 컨테이너에서 실행할 수 있습니다.

Azure Container Registry는 컨테이너 이미지 및 유사한 아티팩트를 저장하는 Azure 제공 사항입니다.

Azure CLI, Azure Portal, PowerShell 명령 등을 통해 수행할 수 있는 레지스트리를 만들려면 빠른 시작 중 하나를 따릅니다.

익명 이미지 풀을 사용하도록 설정하도록 레지스트리를 설정하려면 Azure CLI에서 다음 명령을 실행합니다.

az login
az acr login -n {YOUR_REGISTRY}
az acr update -n {YOUR_REGISTRY} --public-network-enabled true
az acr update -n {YOUR_REGISTRY} --anonymous-pull-enabled true

이미지를 레지스트리에 푸시할 준비가 되면 다음 명령을 실행합니다.

docker push {YOUR_REGISTRY}.azurecr.io/{YOUR_IMAGE_LOCATION}:{YOUR_TAG}

이미지를 환경 정의에 연결

배포에서 사용자 지정 이미지를 사용하기 위해 환경 정의를 작성할 때 매니페스트 파일(environment.yaml 또는 manifest.yaml)에서 runner 속성을 편집합니다.

runner: "{YOUR_REGISTRY}.azurecr.io/{YOUR_REPOSITORY}:{YOUR_TAG}"

ADE 컨테이너 이미지를 사용하여 Azure 리소스를 배포하는 환경 정의를 만드는 방법에 대해 자세히 알아보려면 환경 정의 추가 및 구성을 참조하세요.

액세스 작업 로그 및 오류 세부 정보

ADE는 실패한 배포에 대한 오류 세부 정보를 컨테이너 내의 $ADE_ERROR_LOG 파일에 저장합니다.

실패한 배포 문제를 해결하려면

  1. 개발자 포털에 로그인합니다.

  2. 배포에 실패한 환경을 식별하고 세부 정보 보기를 선택합니다.

    실패한 배포 오류 세부 정보, 특히 스토리지 계정의 잘못된 이름을 보여 주는 스크린샷.

  3. 오류 세부 정보 섹션에서 오류 세부 정보를 검토합니다.

    세부 정보 보기 단추가 표시된 환경 배포 실패를 보여 주는 스크린샷.

또한 Azure CLI를 사용하면 다음 명령을 사용하여 환경의 오류 세부 정보를 볼 수 있습니다.

az devcenter dev environment show --environment-name {YOUR_ENVIRONMENT_NAME} --project {YOUR_PROJECT_NAME}

환경 배포 또는 삭제에 대한 작업 로그를 보려면 Azure CLI를 사용하여 환경에 대한 최신 작업을 검색한 다음 해당 작업 ID에 대한 로그를 봅니다.

# Get list of operations on the environment, choose the latest operation
az devcenter dev environment list-operation --environment-name {YOUR_ENVIRONMENT_NAME} --project {YOUR_PROJECT_NAME}
# Using the latest operation ID, view the operation logs
az devcenter dev environment show-logs-by-operation --environment-name {YOUR_ENVIRONMENT_NAME} --project {YOUR_PROJECT_NAME} --operation-id {LATEST_OPERATION_ID}