다음을 통해 공유


Visual Studio에서 만든 GitHub Actions 워크플로를 사용하여 Azure에 애플리케이션 배포

Visual Studio 2019 버전 16.11부터 GitHub.com 호스트되는 .NET 프로젝트에 대한 새 GitHub Actions 워크플로를 만들 수 있습니다.

필수 구성 요소

  • Visual Studio에서 GitHub 계정 로그인해야 합니다.
  • Azure 계정. Azure 계정이 없는 경우 Visual Studio 구독자가 Azure 혜택을 활성화하거나 평가판 등록할있습니다.

GitHub Actions를 사용하여 Azure에 단일 프로젝트 배포

솔루션 탐색기에서 GitHub.com에 호스팅된 프로젝트를 오른쪽 클릭한 후 게시를 선택합니다.

마우스 오른쪽 단추로 > 게시

다음 화면에서 Azure을 선택한 후, 다음을 선택합니다.

에서 Azure 선택

프로젝트 유형따라 선택할 다른 Azure 서비스 목록을 가져옵니다. 요구 사항에 맞는 지원되는 Azure 서비스 중 하나를 선택합니다.

프로젝트 적합한 Azure 서비스를 선택합니다.

마법사의 마지막 단계에서 yml 파일을 생성하는 GitHub Actions 워크플로를 사용하여 CI/CD을 선택한 다음 마침을 선택합니다.

GitHub Actions 워크플로를 사용하여 CI/CD를 수행하며 yml 파일을 생성합니다

Visual Studio는 새 GitHub Actions 워크플로를 생성하고 커밋하고 GitHub.com 푸시하도록 요청합니다.

커밋 및 푸시

기본 제공 Git 도구사용하여 이 단계를 완료하면 Visual Studio에서 워크플로 실행을 검색합니다.

워크플로가 실행 중인

GitHub 비밀 설정

생성된 워크플로가 Azure에 성공적으로 배포되려면 게시 프로필액세스해야 할 수 있습니다.

하나의 GitHub 비밀

배포에 성공하려면 서비스 주체액세스해야 할 수도 있습니다.

두 개의 GitHub 비밀

모든 경우에 Visual Studio는 올바른 값으로 GitHub 비밀을 설정하려고 합니다. 실패하면 알려 주며 다시 시도할 수 있는 기회를 제공합니다.

GitHub 비밀 누락

비밀을 다시 설정하지 못하면 Visual Studio에서 비밀에 수동으로 액세스할 수 있는 기회를 제공하므로 GitHub.com 리포지토리의 페이지를 통해 프로세스를 완료할 수 있습니다.

누락된 GitHub 비밀 설정

GitHub Actions를 사용하여 Azure Container Apps에 여러 프로젝트 배포

이러한 단계는 Docker 컨테이너를 사용하는 프로젝트가 둘 이상 있고 다중 프로젝트 앱으로 배포하려는 경우에 적합합니다. 마이크로 서비스를 구현하는 앱과 같은 다중 프로젝트 앱을 배포하여 Azure Container Apps 또는 AKS(Azure Kubernetes Service) 수 있습니다. 이 문서에서는 Azure Container Apps에 대해 설명합니다.

  1. 솔루션 탐색기에서 GitHub Actions 노드를 마우스 오른쪽 단추로 클릭하고 새 워크플로 선택합니다. GitHub Actions 워크플로 마법사가 나타납니다.

    GitHub Actions 노드 메뉴의 스크린샷

  2. GitHub Actions 워크플로 대상 화면에서 Azure을 선택합니다.

  3. 특정 대상에 대해 Azure Container Apps 을 선택합니다. 마법사가 Container App 화면으로 이동됩니다.

    기존 Azure Container Apps를 보여 주는 스크린샷.

  4. 기존 Azure Container App을 선택하거나 새로 만들기를 선택합니다.

    기존 Azure Container Apps를 보여 주는 스크린샷.

    새 항목을 만들면 이 화면이 표시됩니다. 테스트 또는 학습할 때 나중에 모든 항목을 더 쉽게 삭제할 수 있도록 새 리소스 그룹을 만드는 것이 가장 좋습니다. Container Apps 환경은 동일한 가상 네트워크를 공유하고 동일한 로깅 대상에 로그를 쓰는 컨테이너 앱 그룹을 둘러싼 보안 경계입니다. Azure Container Apps 환경 참조하세요. 그 내용이 무엇인지 모르거나 이전에 만들지 않은 경우 이 인스턴스에 대한 새 인스턴스를 만듭니다.

    새 Azure Container Apps 인스턴스 만들기를 보여 주는 스크린샷

    만들어지면 새 Azure Container Apps 인스턴스가 표시됩니다.

    새로 만든 Azure Container Apps 인스턴스를 보여 주는 스크린샷

  5. 다음 선택하여 레지스트리 화면으로 진행합니다. 기존 Azure Container Registry를 선택하거나 새로 만듭니다.

    Azure Container Registry 화면의 스크린샷

    새 항목을 만들도록 선택하면 이 화면이 표시됩니다. 리소스 그룹 SKU를 제공하고 가능한 경우 이전과 동일한 지역을 선택합니다. Azure Container Registry의 SKU에 대한 자세한 내용은 Azure Container Registry 서비스 계층참조하세요.

    방금 만든 새 Azure 컨테이너 레지스트리를 보여 주는 스크린샷

    만든 후에는 새 레지스트리가 화면에 표시됩니다.

    새 Azure 컨테이너 레지스트리 만들기를 보여 주는 스크린샷

  6. 솔루션에 배포 가능한 프로젝트가 표시됩니다. 동일한 Azure Container Apps 인스턴스에서 함께 배포하려는 프로젝트를 선택합니다.

    배포할 프로젝트의 선택을 보여 주는 스크린샷

  7. 완료를선택하세요. Azure에서 자산을 만들고 인증을 설정하기 위해 실행 중인 명령을 볼 수 있습니다. 아무 것도 실패하면 CLI에서 다시 시도할 수 있으므로 사용된 명령줄에 유의하세요. 이 단계에서 권한 부여 실패가 발생하면 크게 걱정하지 마세요. 나중에 Visual Studio에서 인증을 설정할 수도 있습니다.

  8. 완료되면 요약 화면이 나타납니다. 요약 화면에는 GitHub Actions 비밀 아래의 GitHub 리포지토리에서 Visual Studio가 만드는 항목과 일치하는 자격 증명이 표시됩니다. 노란색 경고 표시가 있는지 확인합니다. 만들기 프로세스 중에 인증 단계가 실패한 경우 경고 기호로 링크를 클릭하고 몇 단계를 수행하여 여기에서 이를 수정할 수 있습니다.

  9. 워크플로 파일을 열어 Visual Studio에서 생성한 내용을 확인합니다. Visual Studio는 상황에 맞는 워크플로를 생성하기 위해 최선을 다하지만 모든 앱과 리포지토리는 고유하므로 Visual Studio에서 생성된 워크플로 YML 파일을 수동으로 편집해야 성공적으로 실행됩니다. 방금 생성한 워크플로를 열려면 솔루션 탐색기에서 GitHub Actions 노드를 확장하고, 해당 워크플로를 마우스 오른쪽 버튼으로 클릭하여 편집을 선택하십시오.

다음은 배포 가능한 두 프로젝트인 WebAPI 및 WebFrontEnd가 있는 솔루션을 위해 Visual Studio에서 만든 워크플로 파일의 예를 보여 줍니다.

on:
push:
  branches:
  - main
env:
CONTAINER_REGISTRY_LOGIN_SERVER: registry20230810121555.azurecr.io
CONTAINER_APP_NAME: containerapp20230810121017
CONTAINER_APP_RESOURCE_GROUP_NAME: webfrontend-container-app-1234
CONTAINER_APP_CONTAINER_NAME: containerapp
jobs:
WebApi_buildImageAndDeploy:
  runs-on: ubuntu-latest
  steps:
  - name: Checkout source code
    uses: actions/checkout@v3
  - name: Set up Docker Buildx
    uses: docker/setup-buildx-action@v2
  - name: Login to Docker registry
    uses: docker/login-action@v2
    with:
      registry: ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }}
      username: ${{ secrets.registry20230810121555_USERNAME_6891 }}
      password: ${{ secrets.registry20230810121555_PASSWORD_6891 }}
  - name: Build and push Docker image to Azure container registry
    uses: docker/build-push-action@v4
    with:
      push: true
      tags: ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }}/webapi:${{ github.sha }}
      file: WebApi\Dockerfile
  - name: Azure login
    uses: azure/login@v1
    with:
      creds: ${{ secrets.containerapp20230810121017_SPN }}
  - name: Deploy to Azure container app
    uses: azure/CLI@v1
    with:
      inlineScript: >-
        az config set extension.use_dynamic_install=yes_without_prompt
        az containerapp registry set --name ${{ env.CONTAINER_APP_NAME }} --resource-group ${{ env.CONTAINER_APP_RESOURCE_GROUP_NAME }} --server ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }} --username ${{ secrets.registry20230810121555_USERNAME_2047 }} --password ${{ secrets.registry20230810121555_PASSWORD_2047 }}
        az containerapp update --name ${{ env.CONTAINER_APP_NAME }} --container-name ${{ env.CONTAINER_APP_CONTAINER_NAME }} --resource-group ${{ env.CONTAINER_APP_RESOURCE_GROUP_NAME }} --image ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }}/webapi:${{ github.sha }}
  - name: Azure logout
    run: az logout
WebFrontEnd_buildImageAndDeploy:
  runs-on: ubuntu-latest
  needs: WebApi_buildImageAndDeploy
  steps:
  - name: Checkout source code
    uses: actions/checkout@v3
  - name: Set up Docker Buildx
    uses: docker/setup-buildx-action@v2
  - name: Login to Docker registry
    uses: docker/login-action@v2
    with:
      registry: ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }}
      username: ${{ secrets.registry20230810121555_USERNAME_2047 }}
      password: ${{ secrets.registry20230810121555_PASSWORD_2047 }}
  - name: Build and push Docker image to Azure container registry
    uses: docker/build-push-action@v4
    with:
      push: true
      tags: ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }}/webfrontend:${{ github.sha }}
      file: WebFrontEnd\Dockerfile
  - name: Azure login
    uses: azure/login@v1
    with:
      creds: ${{ secrets.containerapp20230810121017_SPN }}
  - name: Deploy to Azure container app
    uses: azure/CLI@v1
    with:
      inlineScript: >-
        az config set extension.use_dynamic_install=yes_without_prompt
        az containerapp registry set --name ${{ env.CONTAINER_APP_NAME }} --resource-group ${{ env.CONTAINER_APP_RESOURCE_GROUP_NAME }} --server ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }} --username ${{ secrets.registry20230810121555_USERNAME_2047 }} --password ${{ secrets.registry20230810121555_PASSWORD_2047 }}
        az containerapp update --name ${{ env.CONTAINER_APP_NAME }} --container-name ${{ env.CONTAINER_APP_CONTAINER_NAME }} --resource-group ${{ env.CONTAINER_APP_RESOURCE_GROUP_NAME }} --image ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }}/webfrontend:${{ github.sha }}
  - name: Azure logout
    run: az logout

워크플로의 주요 기능은 올바른 인증을 사용하여 Azure 서비스에 로그인하고 명령을 실행하여 앱을 빌드하고 배포하는 것입니다.

워크플로 편집 및 테스트

위의 절차에서는 워크플로 YML 파일을 생성하지만 일반적으로 배포에 사용하려면 이를 검토하고 사용자 지정해야 합니다. 워크플로 작업 작성에 대한 GitHub의 지침을 참조해야 할 수도 있습니다. 사용자 지정 작업 정보 참조하세요. 워크플로 파일에는 환경 변수에 대한 설정 및 비밀 이름과 같은 많은 구성 가능한 요소가 포함되어 있습니다. Dockerfiles의 위치, Azure 컨테이너 앱의 이름, 워크플로 실행을 트리거하는 데 사용할 리포지토리의 분기 및 GitHub의 비밀에 대한 참조를 볼 수 있습니다. 비밀은 구문 ${{ secrets.SECRET_NAME }}을 사용하여 참조됩니다. GitHub Actions 비밀을 참조하세요.

프로젝트가 리포지토리의 루트에 없는 경우 워크플로를 변경하여 Dockerfiles를 찾을 경로를 지정해야 합니다. 두 프로젝트의 Dockerfile에 대한 상대 경로에 대한 환경 변수를 추가합니다.

DOCKER_FILEPATH_WEBAPI: docker/ComposeSample/WebApi/Dockerfile
DOCKER_FILEPATH_WEBFRONTEND: docker/ComposeSample/WebFrontend/Dockerfile

다음과 같이 file 매개 변수에 이러한 환경 변수의 값을 사용합니다.

- name: Build and push Docker image to Azure container registry
  uses: docker/build-push-action@v4
  with:
    push: true
    tags: ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }}/webfrontend:${{ github.sha }}
    file: ${{ env.DOCKER_FILEPATH_WEBFRONTEND }}

Dockerfile을 변경해야 하는 경우 변경 내용을 만들고 저장하고, 커밋하고, 원격 리포지토리로 푸시합니다. Visual Studio에서 생성하는 워크플로에는 지정된 분기에서 업데이트된 경우 실행되도록 하는 트리거가 포함됩니다. working 브랜치에 푸시하는 경우 다음과 같아야 합니다.

on:
  push:
  branches:
  - working

변경 내용을 테스트하려면 변경 내용을 커밋하고 트리거 코드에 지정된 리포지토리의 분기로 푸시합니다. PR(끌어오기 요청)를 만들 필요가 없습니다. 워크플로는 push 트리거가 올바른 분기로 설정된 한 실행됩니다.

GitHub.com 저장소의 작업 탭에서 워크플로 실행 기록을 찾습니다. Visual Studio의 GitHub Actions 요약 탭에 있는 링크를 사용하여 직접 가져올 수 있습니다. GitHub에서 워크플로 실행을 열어 로그를 볼 수 있습니다.

문제 해결

워크플로가 성공적으로 실행되지 않는 경우 다음 문제 해결 팁이 유용할 수 있습니다.

문제: 빌드 단계가 실행되지 않음

Dockerfile에서 발생할 수 있는 한 가지 문제는 빌드 단계가 Visual Studio에서와 같이 작동하지 않는다는 것입니다. Visual Studio에서 프로젝트에 대해 생성하는 기본 Dockerfile은 이 문제를 보여 줍니다. 이러한 Dockerfile이 있는 경우 빌드 단계를 다음과 같이 수정하는 것이 좋습니다. 다음은 리포지토리의 docker/ComposeSample/WebApi 프로젝트가 있었던 예제입니다. 워크플로 빌드 컨테이너의 Dockerfile 컨텍스트가 리포지토리의 루트로 설정되어 있지만 Visual Studio에서는 프로젝트 폴더 위의 폴더로 설정되기 때문에 전체 경로가 지정됩니다. 빌드 폴더를 만들기 위해 여기에 접미사 _build 추가되고 프로젝트 파일을 복사하는 대신 전체 폴더가 복사됩니다. Visual Studio에서 생성한 기본 Dockerfile과 비교하여 COPY 명령의 첫 번째 인수에 있는 경로의 파일 부분이 제거되어 프로젝트 파일 대신 전체 폴더를 복사합니다. 이러한 변경이 없으면 이 단계에서 MSBuild 오류가 발생합니다.

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["docker/ComposeSample/WebApi/", "WebApi_build/"]
RUN dotnet restore "WebApi_build/WebApi.csproj"
COPY . .
WORKDIR "/src/WebApi_build"
RUN dotnet build "WebApi.csproj" -c Release -o /app/build

문제: 인증 자격 증명

워크플로를 사용하려면 Azure 액세스를 위해 올바른 사용자 이름 및 암호 비밀을 설정해야 합니다. Visual Studio는 Azure 자산을 만들 때 또는 Microsoft Visual Studio IDE의 GitHub Actions 화면에서 이 작업을 자동으로 수행하려고 시도합니다. GitHub에서 비밀을 확인하고 해당 암호가 있는지 확인하거나 리포지토리의 설정 섹션을 사용하여 필요한 경우 GitHub에 다시 추가할 수 있습니다. 워크플로의 각 섹션에서 참조되는 내용에 대해 비밀 ID를 확인합니다. 필요한 경우 Azure Portal의 컨테이너 레지스트리로 이동하여 컨테이너 레지스트리의 사용자 이름과 암호를 가져오고 해당 값을 사용하여 GitHub에서 비밀을 업데이트할 수 있습니다.

az ad sp create-for-rbac 명령을 실행하여 서비스 주체를 설정하고 클라이언트 ID, 클라이언트 암호 및 테넌트 ID를 가져오는 경우 GitHub 리포지토리에 대한 GitHub Actions 비밀 섹션에서 클라이언트 ID 및 클라이언트 비밀을 비밀로 추가합니다. Azure Container App 인증에 대한 사용자 이름(앱의 클라이언트 ID) 및 암호(클라이언트 암호)의 형태로 Azure 로그인 자격 증명을 제공할 수 있습니다. 이렇게 하려면 Azure login 단계를 다음 코드로 바꿉다. 클라이언트 ID 및 클라이언트 암호에 대해 만든 고유한 GitHub 비밀 이름을 사용하고 동일한 명령의 출력에서 테넌트 ID를 사용합니다.

- name: Azure login
  uses: azure/CLI@v1
  with:
    inlineScript: |
      az login --service-principal -u ${{ secrets.GITHUB_SECRETID_FOR_USERNAME }} -p ${{ secrets.GITHUB_SECRETID_FOR_PASSWORD }} --tenant {your tenant ID}
      az account list

Dockerfile이 올바르게 작동하고 인증이 올바르고 워크플로에 여전히 문제가 있는 경우 다음 리소스를 고려합니다.

지원되는 프로젝트 유형은 무엇입니까?

  • ASP.NET Core
  • ASP.NET 5 이상
  • Azure Functions

지원되는 Azure 서비스는 무엇입니까?

  • Azure Web Apps
  • Azure Functions
  • Azure API Management