자습서: Azure App Service에서 고가용성 다중 지역 앱 만들기

고가용성 및 내결함성은 잘 설계된 솔루션의 핵심 구성 요소입니다. 오류가 발생할 때 자동으로 가동 중지 시간을 단축하고 시스템을 계속 가동할 수 있는 비상 계획을 마련하여 예기치 않은 사태에 대비하는 것이 가장 좋습니다.

클라우드에 애플리케이션을 배포할 때, 해당 클라우드에서 애플리케이션 인프라의 기반이 되는 지역을 선택합니다. 애플리케이션이 단일 지역에 배포되고 해당 지역을 사용할 수 없게 되면 애플리케이션도 사용할 수 없게 됩니다. 애플리케이션의 SLA 계약조건에 따라 가용성 부족이 허용되지 않을 수 있습니다. 이 경우 애플리케이션 및 해당 서비스를 여러 지역에 배포하는 것이 좋습니다.

이 자습서에서는 고가용성 다중 지역 웹앱을 배포하는 방법을 알아봅니다. 애플리케이션 구성 요소를 웹앱 하나와 Azure Front Door로 제한하여 이 시나리오를 간단하게 진행하지만 개념을 확장하고 다른 인프라 패턴에 적용할 수 있습니다. 예를 들어 애플리케이션이 Azure 데이터베이스 제품 또는 스토리지 계정에 연결하는 경우 SQL 데이터베이스의 활성 지역 복제스토리지 계정의 중복 옵션을 참조하세요. 보다 구체적인 시나리오의 참조 아키텍처는 고가용성 다중 지역 웹 애플리케이션을 참조하세요.

다음 아키텍처 다이어그램에서는 이 자습서에서 만드는 인프라를 보여줍니다. 인프라는 별도의 지역에 있는 2개의 동일한 App Services로 구성되는데, 하나는 활성 또는 주 지역이고 다른 하나는 대기 또는 보조 지역입니다. Azure Front Door는 App Services로 트래픽을 라우팅하는 데 사용되고, 인터넷에서 앱에 직접 액세스할 수 없도록 액세스 제한이 구성됩니다. 점선은 활성 지역이 다운된 경우에만 트래픽이 대기 지역으로 전송됨을 나타냅니다.

Azure는 다양한 부하 분산 및 트래픽 라우팅 옵션을 제공합니다. 이 사용 사례에서 Azure Front Door를 선택한 이유는 여러 지역에 배포된 Azure App Service에 호스트되는 인터넷 연결 웹앱을 사용하기 때문입니다. 사용 사례가 이 자습서와 다른 경우 해당 사용 사례에 무엇을 사용해야 하는지 도움이 되는 Azure에서 부하 분산을 위한 의사 결정 트리를 참조하세요.

Architecture diagram of a multi-region App Service.

이 아키텍처를 사용하는 경우:

  • 동일한 App Service 앱이 별도의 두 지역에 배포됩니다.
  • App Service 앱으로 직접 전송되는 공용 트래픽이 차단됩니다.
  • Azure Front Door는 트래픽을 주/활성 지역으로 라우팅하는 데 사용됩니다. 보조 지역에는 현재 가동 중이며 필요할 때 바로 트래픽을 처리할 수 있는 App Service가 있습니다.

학습할 내용:

  • 별도의 지역에 동일한 App Services를 만듭니다.
  • App Services에 대한 공용 액세스를 차단하는 액세스 제한이 있는 Azure Front Door를 만듭니다.

필수 조건

Azure를 구독하고 있지 않다면 시작하기 전에 Azure 체험 계정을 만듭니다.

이 자습서를 완료하려면 다음이 필요합니다.

웹앱의 두 인스턴스 만들기

이 자습서의 경우 서로 다른 Azure 지역에서 실행되는 웹앱 인스턴스 2개가 필요합니다. 지역 쌍인 미국 동부/미국 서부를 두 지역으로 사용하고 빈 웹앱 2개를 만듭니다. 필요한 경우 원하는 대로 지역을 선택할 수 있습니다.

관리 및 정리 작업이 더 간단하게 수행되도록 이 자습서의 모든 리소스에 단일 리소스 그룹을 사용합니다. 재해 복구 상황에서 리소스를 보다 철저하게 격리할 수 있도록 지역/리소스마다 별도의 리소스 그룹을 사용하는 것이 좋습니다.

다음 명령을 실행하여 리소스 그룹을 만듭니다.

az group create --name myresourcegroup --location eastus

App Service 계획 만들기

다음 명령을 실행하여 App Service 요금제를 만듭니다. <app-service-plan-east-us><app-service-plan-west-us> 자리 표시자를 해당 플랜이 있는 지역을 쉽게 식별할 수 있는 고유한 이름 2개로 바꿉니다.

az appservice plan create --name <app-service-plan-east-us> --resource-group myresourcegroup --is-linux --location eastus

az appservice plan create --name <app-service-plan-west-us> --resource-group myresourcegroup --is-linux --location westus

웹앱 만들기

App Service 요금제를 만들었으면 다음 명령을 실행하여 웹앱을 만듭니다. <web-app-east-us><web-app-west-us> 자리 표시자를 전역적으로 고유한 2개의 이름(유효한 문자는 a-z, 0-9, -)으로 바꾸고, 각 플랜(그리고 따라서 각 지역)에 앱을 하나씩 배치하도록 --plan 매개 변수에 주의합니다. <runtime> 매개 변수를 앱의 언어 버전으로 바꿉니다. az webapp list-runtimes를 실행하여 사용 가능한 런타임 목록을 표시합니다. 이 자습서에 제공된 샘플 Node.js 앱을 다음 섹션에서 사용하려면 NODE:18-lts를 런타임으로 사용합니다.

az webapp create --name <web-app-east-us> --resource-group myresourcegroup --plan <app-service-plan-east-us> --runtime <runtime>

az webapp create --name <web-app-west-us> --resource-group myresourcegroup --plan <app-service-plan-west-us> --runtime <runtime>

다음 단계에서 Front Door를 배포할 때 백 엔드 주소를 정의할 수 있도록 각 웹앱의 기본 호스트 이름을 적어 둡니다. <web-app-name>.azurewebsites.net 형식이어야 합니다. 이러한 호스트 이름은 다음 명령을 실행하거나 Azure Portal에서 앱의 개요 페이지로 이동하여 찾을 수 있습니다.

az webapp show --name <web-app-name> --resource-group myresourcegroup --query "hostNames"

Azure Front Door 만들기

다중 지역 배포에는 활성-활성 또는 활성-수동 구성을 사용할 수 있습니다. 활성-활성 구성은 여러 활성 지역에 요청을 분산합니다. 활성-수동 구성은 인스턴스를 보조 지역에서 계속 실행하지만, 주 지역에 장애가 발생하지 않는 한 트래픽을 보로 지역으로 보내지 않습니다. Azure Front Door는 이러한 구성을 사용할 수 있는 기본 제공 기능을 제공합니다. 고가용성 및 내결함성 앱 설계에 대한 자세한 내용은 복원력 및 가용성을 위한 Azure 애플리케이션 설계를 참조하세요.

Azure Front Door 프로필 만들기

이제 트래픽이 앱으로 라우팅되도록 Azure Front Door 프리미엄을 만듭니다.

az afd profile create를 실행하여 Azure Front Door 프로필을 만듭니다.

참고 항목

Azure Front Door 프리미엄 대신 표준을 배포하려면 --sku 매개 변수의 값을 Standard_AzureFrontDoor로 바꿉니다. 표준 계층을 선택하면 WAF 정책을 사용하여 관리 규칙을 배포할 수 없습니다. 자세한 가격 책정 계층 비교는 Azure Front Door 계층 비교를 참조하세요.

az afd profile create --profile-name myfrontdoorprofile --resource-group myresourcegroup --sku Premium_AzureFrontDoor
매개 변수 설명
profile-name myfrontdoorprofile Azure Front Door 프로필의 이름이며, 리소스 그룹 내에서 고유합니다.
resource-group myresourcegroup 이 자습서의 리소스를 포함하는 리소스 그룹입니다.
sku Premium_AzureFrontDoor Azure Front Door 프로필의 가격 책정 계층입니다.

엔드포인트 추가

az afd endpoint create를 실행하여 프로필에 엔드포인트를 만듭니다. 환경 만들기를 완료하면 프로필에서 엔드포인트를 여러 개 만들 수 있습니다.

az afd endpoint create --resource-group myresourcegroup --endpoint-name myendpoint --profile-name myfrontdoorprofile --enabled-state Enabled
매개 변수 설명
endpoint-name myendpoint 프로필 아래의 엔드포인트 이름이며, 전역적으로 고유합니다.
enabled-state Enabled 이 엔드포인트의 사용 여부를 결정합니다.

원본 그룹 만들기

az afd origin-group create를 실행하여 웹앱 2개가 포함된 원본 그룹을 만듭니다.

az afd origin-group create --resource-group myresourcegroup --origin-group-name myorigingroup --profile-name myfrontdoorprofile --probe-request-type GET --probe-protocol Http --probe-interval-in-seconds 60 --probe-path / --sample-size 4 --successful-samples-required 3 --additional-latency-in-milliseconds 50
매개 변수 설명
origin-group-name myorigingroup 원본 그룹의 이름입니다.
probe-request-type GET 수행된 상태 프로브 요청의 유형입니다.
probe-protocol Http 상태 프로브에 사용하는 프로토콜입니다.
probe-interval-in-seconds 60 상태 프로브 간격(초)입니다.
probe-path / 원본의 상대 경로이며, 원본의 상태를 확인하는 데 사용됩니다.
sample-size 4 부하 분산을 결정할 때 고려해야 하는 샘플 수입니다.
successful-samples-required 3 성공해야 하는 샘플 기간 내의 샘플 수입니다.
additional-latency-in-milliseconds 50 최저 대기 시간 버킷으로 분류되는 프로브의 추가 대기 시간(밀리초)입니다.

그룹에 원본 추가

az afd origin create를 실행하여 원본을 원본 그룹에 추가합니다. --host-name 매개 변수의 경우 <web-app-east-us> 자리 표시자를 해당 지역의 앱 이름으로 바꿉니다. --priority 매개 변수가 1로 설정됩니다. 이는 모든 트래픽이 기본 앱으로 전송된다는 의미입니다.

az afd origin create --resource-group myresourcegroup --host-name <web-app-east-us>.azurewebsites.net --profile-name myfrontdoorprofile --origin-group-name myorigingroup --origin-name primaryapp --origin-host-header <web-app-east-us>.azurewebsites.net --priority 1 --weight 1000 --enabled-state Enabled --http-port 80 --https-port 443
매개 변수 설명
host-name <web-app-east-us>.azurewebsites.net 기본 웹앱의 호스트 이름입니다.
origin-name primaryapp 원본의 이름입니다.
origin-host-header <web-app-east-us>.azurewebsites.net 이 원본 요청에 대해 보낼 호스트 헤더입니다. 이 값을 비워 두면 요청 호스트 이름이 이 값을 결정합니다. Web Apps, Blob Storage, Cloud Services 같은 Azure CDN 원본에는 기본적으로 원본 호스트 이름과 매칭하도록 이 호스트 헤더 값이 필요합니다.
priority 1 모든 트래픽을 기본 웹앱으로 보내려면 이 매개 변수를 1로 설정합니다.
weight 1000 부하 분산을 위해 지정된 원본 그룹에 있는 원본의 가중치입니다. 1~1000 사이여야 합니다.
enabled-state Enabled 이 원본의 사용 여부를 결정합니다.
http-port 80 원본에 대한 HTTP 요청에 사용되는 포트입니다.
https-port 443 원본에 대한 HTTPS 요청에 사용되는 포트입니다.

이 단계를 반복하여 두 번째 원본을 추가합니다. --priority 매개 변수에 주의해야 합니다. 이 원본의 경우 2로 설정됩니다. 이 우선 순위 설정은 주 지역이 중단되지 않는 한 모든 트래픽을 주 원본으로 보내도록 Azure Front Door에 지시합니다. 이 원본의 우선 순위를 1로 설정하면 Azure Front Door는 두 원본 모두 활성으로 취급하고 트래픽을 두 지역 모두에 전달합니다. <web-app-west-us> 자리 표시자의 두 인스턴스를 해당 웹앱의 이름으로 바꿔야 합니다.

az afd origin create --resource-group myresourcegroup --host-name <web-app-west-us>.azurewebsites.net --profile-name myfrontdoorprofile --origin-group-name myorigingroup --origin-name secondaryapp --origin-host-header <web-app-west-us>.azurewebsites.net --priority 2 --weight 1000 --enabled-state Enabled --http-port 80 --https-port 443

경로 추가

az afd route create를 실행하여 엔드포인트를 원본 그룹에 매핑합니다. 이 경로는 엔드포인트에서 원본 그룹으로 요청을 전달합니다.

az afd route create --resource-group myresourcegroup --profile-name myfrontdoorprofile --endpoint-name myendpoint --forwarding-protocol MatchRequest --route-name route --https-redirect Enabled --origin-group myorigingroup --supported-protocols Http Https --link-to-default-domain Enabled 
매개 변수 설명
endpoint-name myendpoint 엔드포인트의 이름입니다.
forwarding-protocol MatchRequest 이 규칙이 트래픽을 백 엔드로 전달할 때 사용하는 프로토콜입니다.
route-name route 경로의 이름입니다.
https-redirect Enabled HTTP 트래픽을 자동으로 HTTPS 트래픽으로 리디렉션할지 여부를 결정합니다.
supported-protocols Http Https 이 경로를 지원하는 프로토콜 목록입니다.
link-to-default-domain Enabled 이 경로를 기본 엔드포인트 도메인에 연결할 것인지 여부를 결정합니다.

이 변경 내용이 전역으로 전파되는 데 다소 시간이 걸리기 때문에 이 단계를 완료하는 데 약 15분이 소요됩니다. 이 기간이 지나면 Azure Front Door가 온전하게 작동합니다.

웹앱 액세스를 Azure Front Door 인스턴스로 제한

현재 이 시점의 URL을 사용하여 앱에 직접 액세스할 수 있습니다. 트래픽이 Azure Front Door를 통해서만 앱에 도달할 수 있게 하려면 각 앱에서 액세스 제한을 설정합니다. Front Door의 기능은 트래픽이 Front Door를 통과하는 경우에만 가장 잘 작동합니다. 아직 Front Door를 통해 전송되지 않은 트래픽이 차단되도록 원본을 구성해야 합니다. 그렇지 않으면 트래픽이 Front Door의 웹 애플리케이션 방화벽, DDoS 보호 및 기타 보안 기능을 우회할 수 있습니다. Azure Front Door에서 애플리케이션으로 이동하는 트래픽은 AzureFrontDoor.Backend 서비스 태그에 정의된 잘 알려진 IP 범위 집합에서 시작합니다. 서비스 태그 제한 규칙을 사용하여 Azure Front Door에서 시작되는 트래픽으로 제한할 수 있습니다.

App Service 액세스 제한을 설정하기 전에, 다음 명령을 실행하여 Front Door ID를 적어 둡니다. 이 ID는 트래픽이 특정 Front Door 인스턴스에서만 시작하도록 하는 데 필요합니다. 액세스 제한은 Azure Front Door에서 보내는 고유한 HTTP 헤더를 기반으로 수신 요청을 더욱 필터링합니다.

az afd profile show --resource-group myresourcegroup --profile-name myfrontdoorprofile --query "frontDoorId"

다음 명령을 실행하여 웹앱에 대한 액세스 제한을 설정합니다. <front-door-id> 자리 표시자를 이전 명령의 결과로 바꿉니다. 앱 이름 자리 표시자를 바꿉니다.

az webapp config access-restriction add --resource-group myresourcegroup -n <web-app-east-us> --priority 100 --service-tag AzureFrontDoor.Backend --http-header x-azure-fdid=<front-door-id>

az webapp config access-restriction add --resource-group myresourcegroup -n <web-app-west-us> --priority 100 --service-tag AzureFrontDoor.Backend --http-header x-azure-fdid=<front-door-id>

Front Door 테스트

Azure Front Door 표준/프리미엄 프로필을 만들 때 구성이 전역적으로 배포되는 데 몇 분 정도 걸립니다. 완료되면 앞서 만든 프런트 엔드 호스트에 액세스할 수 있습니다.

az afd endpoint show를 실행하여 Front Door 엔드포인트의 호스트 이름을 가져옵니다.

az afd endpoint show --resource-group myresourcegroup --profile-name myfrontdoorprofile --endpoint-name myendpoint --query "hostName"

브라우저에서, 이전 명령에서 반환한 엔드포인트 호스트 이름(<myendpoint>-<hash>.z01.azurefd.net)으로 이동합니다. 요청이 자동으로 미국 동부의 기본 앱으로 라우팅됩니다.

인스턴트 글로벌 장애 조치(failover)를 테스트하려면 다음을 수행합니다.

  1. 브라우저를 열고 엔드포인트 호스트 이름(<myendpoint>-<hash>.z01.azurefd.net)으로 이동합니다.

  2. az webapp stop을 실행하여 기본 앱을 중지합니다.

    az webapp stop --name <web-app-east-us> --resource-group myresourcegroup
    
  3. 브라우저를 새로 고칩니다. 이제 트래픽이 미국 서부에서 실행 중인 앱으로 전송되므로 동일한 정보 페이지가 표시됩니다.

    장애 조치(failover)를 완료하려면 페이지를 여러 번 새로 고쳐야 할 수 있습니다.

  4. 이제 보조 앱을 중지합니다.

    az webapp stop --name <web-app-west-us> --resource-group myresourcegroup
    
  5. 브라우저를 새로 고칩니다. 이번에는 오류 메시지가 표시됩니다.

    Screenshot of the message: Both instances of the web app stopped.

  6. az webapp start를 실행하여 Web Apps 중 하나를 다시 시작합니다. 브라우저를 새로 고치면 앱이 다시 표시됩니다.

    az webapp start --name <web-app-east-us> --resource-group myresourcegroup
    

Azure Front Door를 통해 앱에 액세스할 수 있고 장애 조치(failover)가 의도한 대로 작동하는 것을 확인했습니다. 장애 조치(failover) 테스트를 마쳤으면 다른 앱을 다시 시작합니다.

액세스 제한을 테스트하고 Azure Front Door를 통해서만 앱에 연결할 수 있는지 확인하려면 브라우저를 열고 각 앱의 URL로 이동합니다. URL을 찾으려면 다음 명령을 실행합니다.

az webapp show --name <web-app-east-us> --resource-group myresourcegroup --query "hostNames"

az webapp show --name <web-app-west-us> --resource-group myresourcegroup --query "hostNames"

앱에 액세스할 수 없다는 내용의 오류 페이지가 표시됩니다.

리소스 정리

이전 단계에서는 리소스 그룹에서 Azure 리소스를 만들었습니다. 나중에 이러한 리소스가 필요하지 않을 것으로 생가 생각되는 경우 Cloud Shell에서 다음 명령을 실행하여 리소스 그룹을 삭제합니다.

az group delete --name myresourcegroup

이 명령을 실행하는 데 몇 분 정도 걸릴 수 있습니다.

ARM/Bicep에서 배포

이 자습서에서 만든 리소스는 ARM/Bicep 템플릿을 사용하여 배포할 수 있습니다. 고가용성 다중 지역 웹앱 Bicep 템플릿을 사용하면 Azure Front Door 뒤에 있는 서로 다른 지역에 2개의 웹앱이 있는 안전한 고가용성 다중 지역 엔드투엔드 솔루션을 만들 수 있습니다.

ARM/Bicep 템플릿을 배포하는 방법을 알아보려면 Bicep 및 Azure CLI를 사용하여 리소스를 배포하는 방법을 참조하세요.

자주 묻는 질문

지금까지 이 자습서에서는 다중 지역 웹앱을 사용하기 위한 기준 인프라를 배포했습니다. App Service는 보안 모범 사례 및 권장 사항에 따라 애플리케이션을 실행하는 데 도움이 되는 기능을 제공합니다.

이 섹션에는 앱을 더욱 안전하게 보호하고 모범 사례에 따라 리소스를 배포하고 관리하는 데 도움이 되는 질문과 대답이 포함되어 있습니다.

이 자습서에서는 Azure CLI를 사용하여 인프라 리소스를 배포했습니다. 지속적인 배포 메커니즘을 구성하여 애플리케이션 인프라를 관리하는 방안을 고려해 보세요. 여러 지역에 리소스를 배포하므로 지역 전체에서 독립적으로 리소스를 관리해야 합니다. 모든 지역에 동일한 리소스를 배포할 수 있도록 Azure Resource Manager 템플릿 또는 Terraform과 같은 IaC(Infrastructure as code)를 Azure Pipelines 또는 GitHub Actions 같은 배포 파이프라인과 함께 사용해야 합니다. 이 방식으로 적절하게 구성하면 리소스가 변경될 때 리소스가 배포된 모든 지역에서 업데이트가 트리거됩니다. 자세한 내용은 Azure App Service에 지속적인 배포를 참조하세요.

스테이징 슬롯을 사용하여 프로덕션에 안전하게 배포하는 연습을 하려면 어떻게 해야 하나요?

애플리케이션 코드를 프로덕션 앱/슬롯에 직접 배포하는 것은 좋지 않습니다. 프로덕션으로 푸시하기 전에 앱을 테스트하고 변경 내용 유효성을 검사할 수 있는 안전한 장소가 있어야 하기 때문입니다. 스테이징 슬롯과 슬롯 스왑의 조합을 사용하여 테스트 환경에서 프로덕션으로 코드를 이동하세요.

여러분은 이 시나리오의 기준 인프라를 이미 만들었습니다. 이제 앱 인스턴스마다 배포 슬롯을 만들고 GitHub Actions를 사용하여 이러한 스테이징 슬롯에 대한 지속적인 배포를 구성합니다. 인프라 관리와 마찬가지로, 변경 내용이 지역 간에 동기화되도록 애플리케이션 소스 코드에 대한 지속적인 배포를 구성하는 것이 좋습니다. 지속적인 배포를 구성하지 않으면 코드가 변경될 때마다 각 지역의 모든 앱을 수동으로 업데이트해야 합니다.

이 자습서의 나머지 단계에서는 앱을 App Services에 배포할 준비가 완료되어 있을 것입니다. 샘플 앱이 필요하면 Node.js Hello World 샘플 앱을 사용하면 됩니다. 해당 리포지토리를 포크하여 고유의 복사본을 만듭니다.

앱의 App Service 스택 설정을 꼭 지정해야 합니다. 스택 설정은 앱에 사용되는 언어 또는 런타임을 의미합니다. 이 설정은 Azure CLI에서 az webapp config set 명령을 사용하거나 포털에서 다음 단계에 따라 구성할 수 있습니다. Node.js 샘플을 사용하는 경우 스택 설정을 Node 18 LTS로 설정합니다.

  1. 앱으로 이동한 후 왼쪽 목차에서 구성을 선택합니다.
  2. 일반 설정 탭을 선택합니다.
  3. 스택 설정에서 앱에 적합한 값을 선택합니다.
  4. 저장을 선택하고 계속을 선택하여 업데이트를 확인합니다.
  5. 다른 앱에도 이 단계를 반복합니다.

앱마다 다음 명령을 실행하여 "stage"라는 스테이징 슬롯을 만듭니다. <web-app-east-us><web-app-west-us> 자리 표시자를 앱 이름으로 바꿉니다.

az webapp deployment slot create --resource-group myresourcegroup --name <web-app-east-us> --slot stage --configuration-source <web-app-east-us>

az webapp deployment slot create --resource-group myresourcegroup --name <web-app-west-us> --slot stage --configuration-source <web-app-west-us>

지속적인 배포를 설정하려면 Azure Portal을 사용해야 합니다. GitHub Actions 같은 공급자를 사용하여 지속적인 배포를 구성하는 방법에 대한 자세한 지침은 Azure App Service에 지속적인 배포를 참조하세요.

GitHub Actions를 사용하여 지속적인 배포를 구성하려면 스테이징 슬롯마다 다음 단계를 완료합니다.

  1. Azure Portal에서 App Service 앱 슬롯 중 하나의 관리 페이지로 이동합니다.

  2. 왼쪽 창에서 배포 센터를 선택합니다. 그런 다음, 설정을 선택합니다.

  3. 원본 상자의 CI/CD 옵션에서 "GitHub"를 선택합니다.

    Screenshot that shows how to choose the deployment source

  4. 처음으로 GitHub에서 배포하는 경우 권한 부여를 선택하고 권한 부여 프롬프트를 따릅니다. 다른 사용자의 리포지토리에서 배포하려면 계정 변경을 선택합니다.

  5. Azure 계정에 GitHub에 대한 권한을 부여한 후에는 조직, 리포지토리분기를 선택하여 관련 CI/CD를 구성합니다. 조직 또는 리포지토리를 찾을 수 없는 경우 GitHub에 대한 추가 권한을 사용하도록 설정해야 할 수 있습니다. 자세한 내용은 조직의 리포지토리에 대한 액세스 관리를 참조하세요.

    1. Node.js 샘플 앱을 사용하는 경우 다음 설정을 사용합니다.

      설정
      조직 <your-GitHub-organization>
      리포지토리 nodejs-docs-hello-world
      지점 main
  6. 저장을 선택합니다.

    선택한 리포지토리 및 분기의 새 커밋이 이제 App Service 앱에 지속적으로 배포됩니다. 로그 탭에서 커밋 및 배포를 추적할 수 있습니다.

게시 프로필을 사용하여 App Service에 인증하는 기본 워크플로 파일이 GitHub 리포지토리에 추가됩니다. <repo-name>/.github/workflows/ 디렉터리로 이동하여 이 파일을 볼 수 있습니다.

App Service에서 기본 인증을 사용하지 않으려면 어떻게 해야 하나요?

기본 인증을 사용하지 않도록 설정하는 것이 좋습니다. 그러면 FTP 및 SCM 엔드포인트에 대한 액세스가 Microsoft Entra ID에서 지원하는 사용자로 제한됩니다. 지속적인 배포 도구를 사용하여 애플리케이션 소스 코드를 배포하는 경우 기본 인증을 사용하지 않도록 설정하려면 지속적인 배포를 구성하는 추가 단계를 수행해야 합니다. 예를 들어 게시 프로필에서 Microsoft Entra 자격 증명을 사용하지 않으므로 이 프로필을 사용할 수 없습니다. 대신 서비스 주체나 OpenID Connect를 사용해야 합니다.

App Service에 기본 인증을 사용하지 않도록 설정하려면 앱과 슬롯마다 다음 명령을 실행하고 <web-app-east-us><web-app-west-us> 자리 표시자를 앱 이름으로 바꿉니다. 첫 번째 명령 집합은 프로덕션 사이트 및 스테이징 슬롯에 FTP 액세스를 사용하지 않도록 설정하고, 두 번째 명령 집합은 프로덕션 사이트 및 스테이징 슬롯에 WebDeploy 포트 및 SCM 사이트에 대한 기본 인증 액세스를 사용하지 않도록 설정합니다.

az resource update --resource-group myresourcegroup --name ftp --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/<web-app-east-us> --set properties.allow=false

az resource update --resource-group myresourcegroup --name ftp --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/<web-app-east-us>/slots/stage --set properties.allow=false

az resource update --resource-group myresourcegroup --name ftp --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/<web-app-west-us> --set properties.allow=false

az resource update --resource-group myresourcegroup --name ftp --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/<web-app-west-us>/slots/stage --set properties.allow=false
az resource update --resource-group myresourcegroup --name scm --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/<web-app-east-us> --set properties.allow=false

az resource update --resource-group myresourcegroup --name scm --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/<web-app-east-us>/slots/stage --set properties.allow=false

az resource update --resource-group myresourcegroup --name scm --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/<web-app-west-us> --set properties.allow=false

az resource update --resource-group myresourcegroup --name scm --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/<web-app-west-us>/slots/stage --set properties.allow=false

로그인을 테스트하고 모니터링하는 방법을 포함하여 기본 인증을 사용하지 않도록 설정하는 방법에 대한 자세한 내용은 App Service 배포에서 기본 인증 사용 안 함을 참조하세요.

기본 인증을 사용하지 않도록 설정한 경우 지속적인 배포를 사용하여 코드를 배포하려면 어떻게 해야 하나요?

App Service 앱에서 기본 인증을 허용하도록 선택하는 경우 스테이징 슬롯 섹션에서 구성한 게시 프로필을 포함하여 App Service에서 사용 가능한 모든 배포 방법을 사용할 수 있습니다.

App Services에 기본 인증을 사용하지 않도록 설정하는 경우 지속적인 배포를 사용하려면 인증을 위한 서비스 주체 또는 OpenID Connect가 필요합니다. GitHub Actions를 코드 리포지토리로 사용하는 경우 서비스 주체 또는 OpenID Connect를 사용하여 GitHub Actions를 통해 App Service에 배포하는 방법에 대한 단계별 자습서를 참조하거나 다음 섹션의 단계를 완료하세요.

서비스 주체를 만들고 GitHub Actions를 사용하여 자격 증명 구성

GitHub Actions와 서비스 주체를 사용하여 지속적인 배포를 구성하려면 다음 단계를 수행합니다.

  1. 다음 명령을 실행하여 서비스 주체를 만듭니다. <subscription-id> 자리 표시자를 앱 이름으로 바꿉니다. App Service 앱에 대한 액세스를 제공하는 역할 할당 자격 증명이 있는 JSON 개체가 출력됩니다. 다음 단계를 위해 이 JSON 개체를 복사합니다. 여기에는 현재만 표시되는 클라이언트 암호가 포함됩니다. 항상 최소한의 액세스 권한을 부여하는 것이 좋습니다. 이 예제의 범위는 전체 리소스 그룹이 아닌 앱으로 제한됩니다.

    az ad sp create-for-rbac --name "myApp" --role contributor --scopes /subscriptions/<subscription-id>/resourceGroups/myresourcegroup/providers/Microsoft.Web/sites/<web-app-east-us> /subscriptions/<subscription-id>/resourceGroups/myresourcegroup/providers/Microsoft.Web/sites/<web-app-west-us> --sdk-auth
    
  2. 서비스 주체 자격 증명을 사용 중인 GitHub Actions 워크플로의 일부로 Azure/로그인 작업에 제공해야 합니다. 이러한 값은 워크플로에서 직접 제공하거나 GitHub 비밀에 저장하고 워크플로에서 참조할 수 있습니다. 값을 GitHub 비밀로 저장하는 것이 더 안전한 옵션입니다.

    1. GitHub 리포지토리를 열고 설정>보안>비밀 및 변수>작업으로 이동합니다.

    2. 새 리포지토리 비밀을 선택하고 다음 값 각각의 비밀을 만듭니다. 이 값은 앞에서 복사한 json 출력에서 찾을 수 있습니다.

      속성
      AZURE_APP_ID <application/client-id>
      AZURE_PASSWORD <client-secret>
      AZURE_TENANT_ID <tenant-id>
      AZURE_SUBSCRIPTION_ID <subscription-id>

GitHub Actions 워크플로 만들기

이제 App Service 앱에 액세스할 수 있는 서비스 주체가 생겼으므로, 지속적인 배포를 구성할 때 앱에 대해 만들어진 기본 워크플로를 편집합니다. 게시 프로필 대신 서비스 주체를 사용하여 인증해야 합니다. 샘플 워크플로는 GitHub 리포지토리에 워크플로 파일 추가의 “서비스 주체” 탭을 참조하세요. 다음은 제공된 Node.js 샘플 앱에 사용할 수 있는 샘플 워크플로입니다.

  1. 앱의 GitHub 리포지토리를 열고 <repo-name>/.github/workflows/ 디렉터리로 이동합니다. 자동 생성된 워크플로가 표시되어야 합니다.

  2. 워크플로 파일마다 오른쪽 위에서 "연필" 단추를 선택하여 파일을 편집합니다. 콘텐츠를 다음 텍스트로 바꿉니다. 이 텍스트는 이전에 자격 증명의 GitHub 비밀을 만들었다고 가정합니다. "env" 섹션에서 <web-app-name> 자리 표시자를 업데이트한 다음, 기본 분기에 직접 커밋합니다. 이 커밋은 GitHub Actions를 트리거하여 다시 실행하고 코드를 배포합니다. 이때 서비스 주체를 사용하여 인증합니다.

    
    name: Build and deploy Node.js app to Azure Web App
    
    on:
      push:
        branches:
          - main
      workflow_dispatch:
    
    env:
      AZURE_WEBAPP_NAME: <web-app-name>   # set this to your application's name
      NODE_VERSION: '18.x'                # set this to the node version to use
      AZURE_WEBAPP_PACKAGE_PATH: '.'      # set this to the path to your web app project, defaults to the repository root
      AZURE_WEBAPP_SLOT_NAME: stage       # set this to your application's slot name
    
    jobs:
      build:
        runs-on: ubuntu-latest
    
        steps:
          - uses: actions/checkout@v2
    
          - name: Set up Node.js version
            uses: actions/setup-node@v1
            with:
              node-version: ${{ env.NODE_VERSION }}
    
          - name: npm install, build
            run: |
              npm install
              npm run build --if-present
    
          - name: Upload artifact for deployment job
            uses: actions/upload-artifact@v2
            with:
              name: node-app
              path: .
    
      deploy:
        runs-on: ubuntu-latest
        needs: build
        environment:
          name: 'stage'
          url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
    
        steps:
          - name: Download artifact from build job
            uses: actions/download-artifact@v2
            with:
              name: node-app
    
          - uses: azure/login@v1
            with:
              creds: |
                {
                  "clientId": "${{ secrets.AZURE_APP_ID }}",
                  "clientSecret":  "${{ secrets.AZURE_PASSWORD }}",
                  "subscriptionId": "${{ secrets.AZURE_SUBSCRIPTION_ID }}",
                  "tenantId": "${{ secrets.AZURE_TENANT_ID }}"
                }
    
          - name: 'Deploy to Azure Web App'
            id: deploy-to-webapp
            uses: azure/webapps-deploy@v2
            with:
              app-name: ${{ env.AZURE_WEBAPP_NAME }}
              slot-name: ${{ env.AZURE_WEBAPP_SLOT_NAME }}
              package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
    
          - name: logout
            run: |
              az logout
    

슬롯 트래픽 라우팅을 통해 앱 업데이트를 테스트하려면 어떻게 해야 하나요?

슬롯을 사용하여 트래픽을 라우팅하면 미리 정의된 사용자 트래픽의 일부가 각 슬롯으로 전송될 수 있습니다. 처음에는 트래픽의 100%가 프로덕션 사이트로 전송됩니다. 하지만 원하는 만큼, 예를 들어 트래픽의 10%를 스테이징 슬롯으로 보낼 수 있습니다. 이 방식으로 슬롯 트래픽 라우팅을 구성하는 경우 사용자가 앱에 액세스하려고 하면 Front Door 인스턴스가 변경되지 않고 트래픽의 10%가 스테이징 슬롯으로 자동 라우팅됩니다. App Service의 슬롯 스왑 및 스테이징 환경에 대해 자세히 알아보려면 Azure App Service에서 스테이징 환경 설정을 참조하세요.

스테이징 슬롯에서 프로덕션 슬롯으로 코드를 옮기려면 어떻게 해야 하나요?

스테이징 슬롯에서 테스트 및 유효성 검사를 마쳤으면 스테이징 슬롯에서 프로덕션 사이트로 슬롯 스왑을 수행할 수 있습니다. 각 지역의 앱 인스턴스마다 이 스왑을 수행해야 합니다. 슬롯 스왑 중에 App Service 플랫폼은 대상 슬롯이 가동 중지되지 않게 합니다.

스왑을 수행하려면 앱마다 다음 명령을 실행합니다. <web-app-name> 자리 표시자를 바꿉니다.

az webapp deployment slot swap --resource-group MyResourceGroup -name <web-app-name> --slot stage --target-slot production

몇 분 후에 Front Door의 엔드포인트로 이동하여 슬롯 스왑이 성공했는지 확인할 수 있습니다.

현재 앱이 실행 중이며 애플리케이션 소스 코드를 변경하면 두 스테이징 슬롯에 대한 업데이트가 자동으로 트리거됩니다. 이후에 해당 코드를 프로덕션으로 이동할 준비가 되면 슬롯 스왑 프로세스를 반복하면 됩니다.

다중 지역 배포에 Azure Front Door를 사용하는 또 다른 방법은 무엇인가요?

일부 고객에게는 앱의 한 버전이 표시되고 나머지 고객에게는 앱의 다른 버전이 표시되는 경우처럼 지역 간 연속성의 중단 가능성 또는 관련 문제가 우려되는 경우 또는 앱을 크게 변경하는 경우에는 슬롯 스왑을 진행 중인 사이트를 Front Door의 원본 그룹에서 일시적으로 제거하면 됩니다. 그러면 모든 트래픽이 다른 원본으로 전송됩니다. 원본 그룹 업데이트 창으로 이동한 다음, 변경 중인 원본을 삭제합니다. 변경 작업을 마치고 트래픽을 다시 처리할 준비가 되면 동일한 창으로 돌아가서 + 원본 추가를 선택하여 원본을 읽을 수 있습니다.

Screenshot showing how to remove an Azure Front Door origin.

원본을 삭제한 후 읽는 방법이 마음에 들지 않으면 Front Door 인스턴스에 대한 추가 원본 그룹을 만드는 방법이 있습니다. 그 후 의도한 원본을 가리키는 원본 그룹에 경로를 연결하면 됩니다. 예를 들어 주 지역과 보조 지역에 각각 하나씩 총 2개의 새 원본 그룹을 만들 수 있습니다. 주 지역을 변경 중이면 경로를 보조 지역에 연결하고, 보조 지역을 변경 중이면 경로를 주 지역에 연결합니다. 모든 변경 작업이 완료되면 두 지역이 모두 포함된 원래 원본 그룹에 경로를 연결하면 됩니다. 이 방법이 작동하는 이유는 경로를 한 번에 하나의 원본 그룹에만 연결할 수 있기 때문입니다.

여러 원본을 사용하는 방법을 보여드리기 위해 다음 스크린샷에는 3개의 원본 그룹이 있습니다. "MyOriginGroup"은 웹앱 2개로 구성되고, 다른 원본 그룹 2개는 각각 해당 지역의 웹앱으로 구성됩니다. 이 예제에서는 주 지역의 앱을 변경하고 있습니다. 변경이 시작되기 전에, 경로가 "MySecondaryRegion"과 연결되었으므로 변경이 진행되는 동안에는 모든 트래픽이 보조 지역의 앱으로 전송됩니다. 연결 안 됨을 선택하면 경로 연결 창이 표시되고 경로를 업데이트할 수 있습니다.

Screenshot showing how to associate routes with Azure Front Door.

고급 도구 사이트에 대한 액세스를 제한하려면 어떻게 해야 하나요?

Azure 앱 서비스를 사용하면 앱을 관리하고 애플리케이션 소스 코드를 배포하는 데 SCM/고급 도구 사이트가 사용됩니다. Front Door를 통해 이 사이트에 연결할 일이 거의 없으므로 SCM/고급 도구 사이트를 잠그는 것이 좋습니다. 예를 들어 원하는 도구로 테스트를 수행하고 지속적인 배포를 사용하도록 설정하는 것만 허용하는 액세스 제한을 설정할 수 있습니다. 배포 슬롯을 사용하는 경우, 특히 프로덕션 슬롯인 경우 테스트와 유효성 검사가 스테이징 슬롯에서 수행되므로 SCM 사이트에 대한 거의 모든 액세스를 거부할 수 있습니다.

다음 단계