Azure App Service에서 보안 N 계층 앱 만들기

많은 애플리케이션에 두 가지 이상의 구성 요소가 있습니다. 예를 들면 공개적으로 액세스할 수 있고 데이터베이스, 스토리지 계정, 키 자격 증명 모음, 다른 VM 또는 이러한 리소스 조합에 연결되는 백 엔드 API나 웹앱에 연결할 수 있는 프런트 엔드가 있을 수 있습니다. 이 아키텍처는 N 계층 애플리케이션을 구성합니다. 이 같은 애플리케이션은 백 엔드 리소스를 최대한 보호하도록 설계하는 것이 중요합니다.

이 자습서에서는 다른 네트워크 격리 웹앱에 연결하는 프런트 엔드 웹앱을 사용하여 보안 N 계층 애플리케이션을 배포하는 방법을 알아봅니다. 모든 트래픽은 Virtual Network 통합프라이빗 엔드포인트를 사용하여 Azure Virtual Network 내에서 격리됩니다. 다른 시나리오를 포함하는 좀 더 포괄적인 지침은 다음을 참조하세요.

시나리오 아키텍처

다음 다이어그램에는 이 자습서에서 만들 아키텍처가 나와 있습니다.

Architecture diagram of an n-tier App Service.

  • 가상 네트워크 - 서브넷을 두 개 포함합니다. 하나는 프런트 엔드 웹앱과 통합되고, 다른 하나에는 백 엔드 웹앱용 프라이빗 엔드포인트가 있습니다. 가상 네트워크는 통합된 프런트 엔드 앱을 제외하고 모든 인바운드 네트워크 트래픽을 차단합니다.
  • 프런트 엔드 웹앱 - 가상 네트워크에 통합되고 공용 인터넷에서 액세스할 수 있습니다.
  • 백 엔드 웹앱 - 가상 네트워크의 프라이빗 엔드포인트를 통해서만 액세스할 수 있습니다.
  • 프라이빗 엔드포인트 - 백 엔드 웹앱과 통합되고 개인 IP 주소를 사용하여 웹앱에 액세스할 수 있습니다.
  • 프라이빗 DNS 영역 - 프라이빗 엔드포인트의 IP 주소에 대한 DNS 이름을 확인할 수 있습니다.

참고 항목

가상 네트워크 통합 및 프라이빗 엔드포인트는 App Service의 기본 계층까지 사용할 수 있습니다. 무료 계층은 이러한 기능을 지원하지 않습니다. 이 아키텍처를 사용하는 경우:

  • 백 엔드 앱에 대한 공용 트래픽이 차단됩니다.
  • App Service의 아웃바운드 트래픽은 가상 네트워크로 라우팅되고 백 엔드 앱에 도달할 수 있습니다.
  • App Service는 백 엔드 앱에 대한 DNS를 확인할 수 있습니다.

이 시나리오는 App Service에서 가능한 N 계층 시나리오 중 하나를 보여 줍니다. 이 자습서에서 다루는 개념을 사용하여 더 복잡한 N 계층 앱을 빌드할 수 있습니다.

학습할 내용:

  • App Service 가상 네트워크를 통합하기 위한 가상 네트워크와 서브넷 만들기
  • 프라이빗 DNS 영역 만들기
  • 프라이빗 엔드포인트 만들기
  • App Service에서 가상 네트워크 통합 구성
  • App Service에서 기본 인증을 사용하지 않기
  • 잠긴 백 엔드 웹앱에 지속적으로 배포

필수 조건

이 자습서에서는 GitHub에서 호스트되는 두 가지 샘플 Node.js 앱을 사용합니다. GitHub 계정이 아직 없는 경우 무료로 계정을 만듭니다.

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

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

1. 웹앱의 두 인스턴스 만들기

웹앱 인스턴스가 두 개 필요합니다. 하나는 프런트 엔드용이고, 다른 하나는 백 엔드용입니다. 가상 네트워크 통합 및 프라이빗 엔드포인트를 사용하려면 최소한 기본 계층을 사용해야 합니다. 나중에 가상 네트워크 통합 및 기타 구성을 구성합니다.

  1. 이 자습서에서 만드는 리소스를 모두 관리하는 리소스 그룹을 만듭니다.

    # Save resource group name and region as variables for convenience
    groupName=myresourcegroup
    region=eastus
    az group create --name $groupName --location $region
    
  2. App Service 계획을 만듭니다. <app-service-plan-name>을 고유한 이름으로 바꿉니다. 다른 SKU를 사용해야 하는 경우 --sku 매개 변수를 수정합니다. SKU가 필수 네트워킹 기능을 지원하지 않아서 무료 계층을 사용하고 있지 않은지 확인합니다.

    # Save App Service plan name as a variable for convenience
    aspName=<app-service-plan-name>
    az appservice plan create --name $aspName --resource-group $groupName --is-linux --location $region --sku P1V3
    
  3. 웹앱을 만듭니다. <frontend-app-name><backend-app-name>을 전역적으로 고유한 두 가지 이름(유효한 문자는 a-z, 0-9, -)으로 바꿉니다. 이 자습서에서는 샘플 Node.js 앱이 제공됩니다. 고유한 앱을 사용하려는 경우 그에 따라 --runtime 매개 변수를 변경합니다. az webapp list-runtimes를 실행하여 사용 가능한 런타임 목록을 표시합니다.

    az webapp create --name <frontend-app-name> --resource-group $groupName --plan $aspName --runtime "NODE:18-lts"
    az webapp create --name <backend-app-name> --resource-group $groupName --plan $aspName --runtime "NODE:18-lts"
    

2. 네트워크 인프라 만들기

다음과 같은 네트워크 리소스를 만들게 됩니다.

  • 가상 네트워크.
  • App Service 가상 네트워크 통합용 서브넷
  • 프라이빗 엔드포인트용 서브넷
  • 프라이빗 DNS 영역
  • 프라이빗 엔드포인트.
  1. 가상 네트워크를 만듭니다. <virtual-network-name>을 고유한 이름으로 바꿉니다.

    # Save vnet name as variable for convenience
    vnetName=<virtual-network-name>
    az network vnet create --resource-group $groupName --location $region --name $vnetName --address-prefixes 10.0.0.0/16
    
  2. App Service 가상 네트워크 통합용 서브넷을 만듭니다.

    az network vnet subnet create --resource-group $groupName --vnet-name $vnetName --name vnet-integration-subnet --address-prefixes 10.0.0.0/24 --delegations Microsoft.Web/serverfarms --disable-private-endpoint-network-policies false
    

    App Service에서 가상 네트워크 통합 서브넷은 최소한 /26의 CIDR 블록을 사용하는 것이 좋습니다. /24가 충분합니다. --delegations Microsoft.Web/serverfarms는 서브넷이 App Service 가상 네트워크 통합을 위해 위임되도록 지정합니다.

  3. 프라이빗 엔드포인트에 다른 서브넷을 만듭니다.

    az network vnet subnet create --resource-group $groupName --vnet-name $vnetName --name private-endpoint-subnet --address-prefixes 10.0.1.0/24 --disable-private-endpoint-network-policies true
    

    프라이빗 엔드포인트 서브넷의 경우 --disable-private-endpoint-network-policiestrue로 설정하여 프라이빗 엔드포인트 네트워크 정책을 사용하지 않아야 합니다.

  4. 프라이빗 DNS 영역을 만듭니다.

    az network private-dns zone create --resource-group $groupName --name privatelink.azurewebsites.net
    

    이러한 설정에 대한 자세한 내용은 Azure 프라이빗 엔드포인트 DNS 구성을 참조하세요

    참고 항목

    포털을 사용하여 프라이빗 엔드포인트를 만들면 프라이빗 DNS 영역이 자동으로 만들어져서 별도로 만들 필요가 없습니다. 이 자습서와 일관되도록 Azure CLI를 사용하여 프라이빗 DNS 영역과 프라이빗 엔드포인트를 별도로 만듭니다.

  5. 프라이빗 DNS 영역을 가상 네트워크에 연결합니다.

    az network private-dns link vnet create --resource-group $groupName --name myDnsLink --zone-name privatelink.azurewebsites.net --virtual-network $vnetName --registration-enabled False
    
  6. 가상 네트워크의 프라이빗 엔드포인트 서브넷에서 백 엔드 웹앱용 프라이빗 엔드포인트를 만듭니다. <backend-app-name>을 백 엔드 웹앱 이름으로 바꿉니다.

    # Get backend web app resource ID
    resourceId=$(az webapp show --resource-group $groupName --name <backend-app-name> --query id --output tsv)
    az network private-endpoint create --resource-group $groupName --name myPrivateEndpoint --location $region --connection-name myConnection --private-connection-resource-id $resourceId --group-id sites --vnet-name $vnetName --subnet private-endpoint-subnet
    
  7. 백 엔드 웹앱 프라이빗 엔드포인트용 DNS 영역 그룹을 사용하여 프라이빗 DNS 영역에 프라이빗 엔드포인트를 연결합니다. 이 DNS 영역 그룹을 사용하면 프라이빗 엔드포인트에 대한 업데이트가 있을 때 프라이빗 DNS 영역을 자동으로 업데이트할 수 있습니다.

    az network private-endpoint dns-zone-group create --resource-group $groupName --endpoint-name myPrivateEndpoint --name myZoneGroup --private-dns-zone privatelink.azurewebsites.net --zone-name privatelink.azurewebsites.net
    
  8. App Service용 프라이빗 엔드포인트를 만들면 공용 액세스가 암시적으로 사용되지 않습니다. 기본 URL을 사용하여 백 엔드 웹앱에 액세스하려고 시도하면 액세스가 거부됩니다. 브라우저에서 <backend-app-name>.azurewebsites.net으로 이동하여 이 동작을 확인합니다.

    Screenshot of 403 error when trying to access backend web app directly.

    프라이빗 엔드포인트를 사용하는 App Service 액세스 제한에 대한 자세한 내용은 Azure App Service액세스 제한을 참조하세요.

3. 프런트 엔드 웹앱에서 가상 네트워크 통합 구성

앱에서 가상 네트워크 통합을 사용하도록 설정합니다. <frontend-app-name>을 프런트 엔드 웹앱 이름으로 바꿉니다.

az webapp vnet-integration add --resource-group $groupName --name <frontend-app-name> --vnet $vnetName --subnet vnet-integration-subnet

가상 네트워크 통합을 통해 아웃바운드 트래픽이 가상 네트워크로 직접 흐를 수 있습니다. 기본적으로 RFC-1918에 정의된 로컬 IP 트래픽만 프라이빗 엔드포인트에 필요한 가상 네트워크로 라우팅됩니다. 모든 트래픽을 가상 네트워크로 라우팅하려면 가상 네트워크 통합 라우팅 관리를 참조하세요. 모든 트래픽 라우팅은 Azure Virtual Network NAT 또는 Azure Firewall과 같은 Virtual Network를 통해 인터넷 트래픽을 라우팅하려는 경우에도 사용할 수 있습니다.

4. 인터넷에서 백 엔드 웹앱에 대한 배포 사용

백 엔드 웹앱에는 공개적으로 액세스할 수 없으므로, SCM 사이트에 공개적으로 액세스할 수 있도록 설정하여 지속적인 배포 도구가 앱에 도달하도록 해야 합니다. 기본 웹앱 자체는 모든 트래픽을 계속 거부할 수 있습니다.

  1. 백 엔드 웹앱에서 공용 액세스를 사용합니다.

    az webapp update --resource-group $groupName --name <backend-app-name> --set publicNetworkAccess=Enabled
    
  2. 모든 트래픽을 거부하도록 기본 웹앱에 일치하지 않는 규칙 작업을 설정합니다. 이 설정은 일반 앱 액세스 설정이 공용 액세스를 허용하도록 설정되어 있더라도 기본 웹앱에 대한 공용 액세스를 거부합니다.

    az resource update --resource-group $groupName --name <backend-app-name> --namespace Microsoft.Web --resource-type sites --set properties.siteConfig.ipSecurityRestrictionsDefaultAction=Deny
    
  3. 모든 트래픽을 허용하도록 SCM 사이트에 일치하지 않는 규칙 작업을 설정합니다.

    az resource update --resource-group $groupName --name <backend-app-name> --namespace Microsoft.Web --resource-type sites --set properties.siteConfig.scmIpSecurityRestrictionsDefaultAction=Allow
    

5. FTP 및 SCM 액세스 잠금

이제 백 엔드 SCM 사이트에 공개적으로 액세스할 수 있으므로 보안을 강화하여 사이트를 잠가야 합니다.

  1. 프런트 엔드 웹앱과 백 엔드 웹앱에서 모두 FTP 액세스를 사용하지 않도록 합니다. <frontend-app-name><backend-app-name>을 앱 이름으로 바꿉니다.

    az resource update --resource-group $groupName --name ftp --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/<frontend-app-name> --set properties.allow=false
    az resource update --resource-group $groupName --name ftp --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/<backend-app-name> --set properties.allow=false
    
  2. 두 웹앱에서 모두 WebDeploy 포트 및 SCM/고급 도구 사이트에 대한 기본 인증 액세스를 사용하지 않도록 합니다. <frontend-app-name><backend-app-name>을 앱 이름으로 바꿉니다.

    az resource update --resource-group $groupName --name scm --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/<frontend-app-name> --set properties.allow=false
    az resource update --resource-group $groupName --name scm --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/<backend-app-name> --set properties.allow=false
    

App Service에서 기본 인증을 사용하지 않으면 Microsoft Entra ID에서 지원되는 사용자로 FTP/SCM 엔드포인트에 대한 액세스가 제한되어 앱이 더 안전하게 보호됩니다. 로그인을 테스트하고 모니터링하는 방법을 포함하여 기본 인증을 사용하지 않도록 설정하는 방법에 대한 자세한 내용은 App Service에서 기본 인증을 사용하지 않도록 설정을 참조하세요.

6. GitHub Actions를 사용하여 지속적인 배포 구성

  1. Node.js 백 엔드 샘플 앱으로 이동합니다. 이 앱은 간단한 Hello World 앱입니다.

  2. GitHub 페이지의 오른쪽 위에 있는 포크 단추를 선택합니다.

  3. 소유자를 선택하고 기본 리포지토리 이름을 그대로 둡니다.

  4. 포크 만들기를 선택합니다.

  5. Node.js 프런트 엔드 샘플 앱에서 동일한 프로세스를 반복합니다. 이 앱은 원격 URL에 액세스하는 기본 웹앱입니다.

  6. 서비스 주체를 만듭니다. <subscription-id>, <frontend-app-name>, <backend-app-name>을 사용자 값으로 바꿉니다.

    az ad sp create-for-rbac --name "myApp" --role contributor --scopes /subscriptions/<subscription-id>/resourceGroups/$groupName/providers/Microsoft.Web/sites/<frontend-app-name> /subscriptions/<subscription-id>/resourceGroups/$groupName/providers/Microsoft.Web/sites/<backend-app-name> --sdk-auth
    

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

  7. 서비스 주체의 자격 증명을 GitHub 비밀로 저장하려면 GitHub에서 포크된 샘플 리포지토리 중 하나로 이동한 후 설정>보안>비밀 및 변수>작업으로 이동합니다.

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

    속성
    AZURE_APP_ID <application/client-id>
    AZURE_PASSWORD <client-secret>
    AZURE_TENANT_ID <tenant-id>
    AZURE_SUBSCRIPTION_ID <subscription-id>
  9. 포크된 다른 샘플 리포지토리에서 이 프로세스를 반복합니다.

  10. GitHub Actions를 사용하여 지속적인 배포를 설정하려면 Azure Portal에 로그인합니다.

  11. 프런트 엔드 웹앱의 개요 페이지로 이동합니다.

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

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

    Screenshot that shows how to choose the deployment source.

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

  15. 필수 구성 요소의 일부로 포크된 Node.js 샘플 앱을 사용하는 경우 조직, 리포지토리분기에서 다음 설정을 사용합니다.

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

  17. 백 엔드 웹앱에서 동일한 단계를 반복합니다. 배포 센터 설정은 다음 표에 나와 있습니다.

    설정
    조직 <your-GitHub-organization>
    리포지토리 nodejs-backend
    지점 main

7. GitHub Actions 배포에 서비스 주체 사용

배포 센터 구성은 각 샘플 리포지토리에 기본 워크플로 파일을 만들었지만, 기본 인증을 사용하는 게시 프로필을 기본적으로 사용합니다. 기본 인증을 사용할 수 없으므로 배포 센터에서 로그 탭을 선택하면 자동으로 트리거되는 배포로 인해 오류가 발생합니다. 서비스 주체를 사용하여 App Service를 인증하도록 워크플로 파일을 수정해야 합니다. 샘플 워크플로는 GitHub 리포지토리에 워크플로 파일 추가를 참조하세요.

  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
    
    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:
          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 }}
              package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
    
          - name: logout
            run: |
              az logout
    
  3. 포크된 다른 GitHub 리포지토리의 워크플로 파일에서 이 프로세스를 반복합니다.

새 GitHub 커밋은 각 앱에 다른 배포를 트리거합니다. 이때 워크플로는 서비스 주체를 사용하여 앱의 SCM 사이트를 인증하므로 배포에 성공해야 합니다.

GitHub Actions 같은 공급자를 사용하여 지속적인 배포를 구성하는 방법에 대한 자세한 지침은 Azure App Service에 지속적인 배포를 참조하세요.

8. 연결 및 앱 액세스의 유효성 검사

  1. URL(https://<frontend-app-name>.azurewebsites.net)을 사용하여 프런트 엔드 웹앱으로 이동합니다.

  2. 텍스트 상자에 백 엔드 웹앱의 URL(https://<backend-app-name>.azurewebsites.net)을 입력합니다. 연결을 올바르게 설정하면 백 엔드 웹앱의 전체 콘텐츠인 "Hello from the backend web app!"이라는 메시지가 표시됩니다. 프런트 엔드 웹앱의 모든 아웃바운드 트래픽은 가상 네트워크를 통해 라우팅됩니다. 프런트 엔드 웹앱은 프라이빗 엔드포인트를 통해 백 엔드 웹앱에 안전하게 연결됩니다. 연결에 문제가 있으면 프런트 엔드 웹앱이 충돌합니다.

  3. URL(https://<backend-app-name>.azurewebsites.net)을 사용하여 백 엔드 웹앱으로 바로 이동해 보세요. 메시지 Web App - Unavailable이 표시되어야 합니다. 앱에 연결할 수 있는 경우 프라이빗 엔드포인트를 구성했고 앱에 대한 액세스 제한이 기본 웹앱의 모든 트래픽을 거부하도록 설정되어 있는지 확인합니다.

  4. 프런트 엔드 웹앱이 프라이빗 링크를 통해 백 엔드 웹앱에 도달하고 있는지 추가로 확인하려면, 프런트 엔드의 인스턴스 중 하나에 SSH합니다. SSH하려면 다음 명령을 실행하여 앱의 웹 컨테이너에 SSH 세션을 설정하고 브라우저에서 원격 셸을 엽니다.

    az webapp ssh --resource-group $groupName --name <frontend-app-name>
    
  5. 브라우저에서 셸이 열리면 nslookup을 실행하여 백 엔드 웹앱의 개인 IP를 통해 백 엔드 웹앱에 도달하고 있는지 확인합니다. 또한 curl을 실행하여 사이트 콘텐츠의 유효성을 다시 검사할 수 있습니다. <backend-app-name>을 백 엔드 웹앱 이름으로 바꿉니다.

    nslookup <backend-app-name>.azurewebsites.net
    curl https://<backend-app-name>.azurewebsites.net
    

    Screenshot of SSH session showing how to validate app connections.

    nslookup은 백 엔드 웹앱의 개인 IP 주소로 확인되어야 합니다. 개인 IP 주소는 가상 네트워크의 주소여야 합니다. 개인 IP를 확인하려면 백 엔드 웹앱의 네트워킹 페이지로 이동합니다.

    Screenshot of App Service Networking page showing the inbound IP of the app.

  6. 다른 터미널(프런트 엔드 인스턴스의 SSH 세션이 아닌 터미널)에서 동일한 nslookup 명령과 curl 명령을 반복합니다.

    Screenshot of an external terminal doing a nslookup and curl of the back-end web app.

    nslookup은 백 엔드 웹앱에서 사용되는 공용 IP를 반환합니다. 백 엔드 웹앱에 대한 공용 액세스를 사용할 수 없으므로, 공용 IP에 도달하려고 하면 액세스 거부 오류가 발생합니다. 이 오류는 공용 인터넷에서 이 사이트에 액세스할 수 없음을 의미하며, 의도된 동작입니다. nslookup은 프라이빗 DNS 영역을 통해 가상 네트워크 내에서만 확인할 수 있으므로 개인 IP로 확인되지 않습니다. 프런트 엔드 웹앱만 가상 네트워크 내에 있습니다. 외부 터미널의 백 엔드 웹앱에서 curl을 실행하려고 하면 반환되는 HTML에 Web App - Unavailable이 포함됩니다. 이 오류는 브라우저에서 백 엔드 웹앱으로 이동하려고 할 때 이전에 본 오류 페이지의 HTML을 표시합니다.

9. 리소스 정리

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

az group delete --name myresourcegroup

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

자주 묻는 질문

서비스 주체를 사용하는 배포의 대안이 있나요?

이 자습서에서는 기본 인증을 사용하지 않도록 설정했으므로 사용자 이름과 암호를 이용해 백 엔드 SCM 사이트를 인증할 수 없고, 게시 프로필도 사용할 수 없습니다. 서비스 주체 대신 OpenID Connect를 사용할 수도 있습니다.

App Service에서 GitHub Actions 배포를 구성하면 어떻게 되나요?

Azure는 리포지토리에서 워크플로 파일을 자동 생성합니다. 선택한 리포지토리 및 분기의 새 커밋이 이제 App Service 앱에 지속적으로 배포됩니다. 로그 탭에서 커밋 및 배포를 추적할 수 있습니다.

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

백 엔드 SCM을 공개적으로 액세스할 수 있는 상태로 유지해도 안전한가요?

FTP 및 SCM 액세스를 잠그면 공개적으로 액세스할 수 있다 해도 Microsoft Entra 지원 보안 주체만 SCM 엔드포인트에 액세스할 수 있습니다. 이 설정은 백 엔드 웹앱이 계속 보호된다는 확신을 갖게 합니다.

백 엔드 SCM 사이트를 전혀 열지 않고 배포할 수 있는 방법이 있나요?

SCM 사이트에 대한 공용 액세스를 사용하는 것이 우려되거나 정책에 의해 제한되는 경우 ZIP 패키지에서 실행과 같은 다른 App Service 배포 옵션을 사용하는 것이 좋습니다.

ARM/Bicep을 사용하여 이 아키텍처를 배포하려면 어떻게 하나요?

이 자습서에서 만든 리소스는 ARM/Bicep 템플릿을 사용하여 배포할 수 있습니다. 백 엔드 웹앱 Bicep 템플릿에 연결된 앱을 사용하면 안전한 N 계층 앱 솔루션을 만들 수 있습니다.

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

다음 단계