Published on

GitHub Actions 배포 자동화 알아보기

Authors
  • avatar
    Name
    Indo Yoon
    Twitter

GitHub Actions 배포 자동화는 저장소 안의 워크플로 파일로 빌드와 테스트, 배포를 하나의 흐름으로 이어 붙이는 방식입니다. 별도의 CI 서버를 따로 세우지 않아도 되고, 코드 변경과 배포 이력이 같은 저장소에 남아 추적이 쉽습니다. 이 글은 서버 운영과 배포를 담당하는 백엔드 개발자를 기준으로 구성 요소, 단계별 절차, 상황별 선택 기준, 주의할 점을 차례로 정리합니다.

한눈에 보기

GitHub Actions의 배포 자동화는 "무엇이 일어났을 때(이벤트)", "무엇을 실행할지(잡과 스텝)", "어디서 실행할지(러너)", "어떤 권한과 값으로 실행할지(권한·시크릿·환경)"로 나눠 이해하면 정리가 됩니다.

  • 워크플로 파일: 저장소의 .github/workflows 디렉터리에 두는 YAML 파일입니다. 파일 하나가 자동화 단위 하나가 됩니다.
  • 이벤트: push, pull_request, workflow_dispatch, schedule, release 등이 있습니다. 배포는 보통 기본 브랜치 푸시나 태그 생성에 묶습니다.
  • 잡: 러너 한 곳에서 실행되는 스텝 묶음이며, 기본적으로 잡끼리는 병렬로 돕니다. needs로 실행 순서를 강제합니다.
  • 스텝: 셸 명령(run)이거나 재사용 가능한 액션(uses)입니다. 실패하면 기본적으로 뒤 스텝이 실행되지 않습니다.
  • 러너: GitHub가 제공하는 호스팅 러너 또는 직접 연결한 셀프 호스팅 러너입니다.
  • 환경: 배포 대상 단위입니다. 승인 규칙, 대기 시간, 환경 전용 시크릿을 붙일 수 있습니다.
  • 시크릿과 변수: 민감한 값은 시크릿으로, 공개되어도 되는 설정값은 변수로 나눠 둡니다.

배포 자동화를 설계할 때 가장 먼저 정할 것은 트리거와 환경 경계입니다. 트리거가 애매하면 의도하지 않은 시점에 배포가 나가고, 환경 경계가 없으면 스테이징용 자격 증명이 운영까지 그대로 흘러갑니다.

배포 파이프라인 구성 요소 비교

구성 요소역할정의 위치
워크플로자동화 전체 단위.github/workflows 아래 YAML 파일
트리거(on)워크플로 실행 조건워크플로의 on 블록
잡(job)러너에서 실행되는 작업 묶음jobs 아래
스텝(step)개별 명령 또는 액션 호출steps 아래
러너(runner)실제 실행 환경runs-on 값
환경(environment)배포 대상과 보호 규칙저장소 설정과 잡의 environment
시크릿(secret)자격 증명 저장소저장소·조직·환경 설정
동시성(concurrency)중복 실행 제어워크플로 또는 잡의 concurrency

표에서 눈여겨볼 지점은 환경과 시크릿이 저장소 설정과 워크플로 양쪽에 걸쳐 있다는 점입니다. 워크플로 파일만 읽어서는 어떤 자격 증명이 주입되는지 알 수 없으므로, 저장소 설정 화면까지 함께 관리 대상으로 봐야 합니다.

단계별로 배포 자동화 구성하기

첫 단계는 배포 대상과 트리거를 문장으로 적는 일입니다. "기본 브랜치에 병합되면 스테이징에 배포하고, 태그가 생성되면 운영에 배포한다"처럼 규칙을 먼저 정하면 워크플로 구조가 자연스럽게 따라옵니다.

두 번째는 워크플로 파일을 만들고 이름을 붙이는 일입니다. 파일 이름은 역할이 드러나게 짓고, 하나의 파일에 빌드와 배포를 모두 넣을지 분리할지도 이때 정합니다. 규모가 커지면 재사용 워크플로로 쪼개는 편이 유지보수에 유리합니다.

세 번째는 빌드와 테스트를 배포 앞단에 두는 일입니다. 배포 잡이 테스트 잡에 needs로 매달리게 하면, 테스트가 깨진 커밋이 서버까지 도달하는 일을 막을 수 있습니다.

name: deploy
on:
  push:
    branches: [main]
  workflow_dispatch:

concurrency:
  group: deploy-main
  cancel-in-progress: false

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: ./gradlew test

  deploy:
    needs: test
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      - run: ./scripts/deploy.sh
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}

네 번째는 환경을 만들고 보호 규칙을 붙이는 일입니다. 운영 환경에 필수 리뷰어를 지정하면 승인 없이는 배포 잡이 진행되지 않습니다. 대기 시간을 두면 배포 직후 문제를 알아챌 여유도 생깁니다.

다섯 번째는 시크릿을 환경 단위로 분리하는 일입니다. 스테이징과 운영의 자격 증명을 같은 이름으로 두면 워크플로가 어느 환경에 붙었는지에 따라 값이 자동으로 갈립니다. 이렇게 하면 배포 스크립트에 환경 분기 코드를 넣지 않아도 됩니다.

여섯 번째는 배포 스텝을 얇게 유지하는 일입니다. 워크플로 안에 배포 로직을 길게 늘어놓기보다, 저장소에 있는 스크립트를 호출하고 필요한 값만 환경 변수로 넘기는 편이 로컬 재현과 롤백에 유리합니다.

일곱 번째는 동시성 설정으로 중복 배포를 막는 일입니다. 같은 그룹 이름을 쓰는 워크플로는 동시에 실행되지 않으므로, 짧은 간격으로 푸시가 몰려도 배포가 겹치지 않습니다. 진행 중인 배포를 취소할지 기다릴지는 서비스 특성에 맞게 고릅니다.

마지막으로 실패 알림과 롤백 경로를 정해 둡니다. 배포 잡이 실패했을 때 누가 어떤 채널로 통보받는지, 직전 리비전으로 되돌리는 절차가 무엇인지 문서로 남겨 두면 장애 대응 속도가 달라집니다.

상황별 선택 기준

어떤 기능을 쓸지는 운영 환경의 제약에서 출발하는 편이 정확합니다.

  • 호스팅 러너와 셀프 호스팅 러너: 외부 네트워크에서 접근할 수 없는 사설 데이터베이스나 내부망 서버에 배포해야 한다면 셀프 호스팅 러너가 필요합니다. 그렇지 않다면 관리 부담이 적은 호스팅 러너로 시작하는 편이 낫습니다.
  • 정적 시크릿과 단기 자격 증명: 클라우드 공급자를 쓴다면 OIDC 연동으로 워크플로 실행 시점에만 유효한 자격 증명을 받는 방식이 안전합니다. 그렇지 않은 대상은 시크릿에 장기 키를 보관하고 교체 주기를 정해 관리합니다.
  • 환경 보호 규칙과 브랜치 전략: 운영 배포에 사람의 승인이 필요하면 환경 보호 규칙을 씁니다. 승인 없이 자동 배포해도 되는 단계라면 브랜치 규칙만으로 충분합니다.
  • 재사용 워크플로와 복합 액션: 여러 저장소가 같은 배포 절차를 공유하면 재사용 워크플로가 적합합니다. 단일 저장소 안에서 스텝 묶음을 재사용하려면 복합 액션이 가볍습니다.

선택 기준을 정리할 때 비용도 함께 봐야 합니다. 호스팅 러너는 실행 시간에 따라 과금될 수 있으므로, 캐시와 조건부 실행으로 불필요한 잡을 줄이는 것이 운영 비용 관리로 이어집니다.

주의할 점

첫째, 포크에서 올라온 풀 리퀘스트에는 시크릿이 주입되지 않는다는 점을 기억해야 합니다. 외부 기여자의 코드를 신뢰하지 않는 기본 동작이므로, 배포가 필요한 검증은 별도 워크플로로 분리해야 합니다.

둘째, GITHUB_TOKEN 권한은 최소로 두는 편이 안전합니다. 워크플로 상단에서 permissions를 명시하지 않으면 기본 권한이 넓게 열릴 수 있으므로, 필요한 범위만 선언하는 습관이 좋습니다.

셋째, 서드파티 액션은 태그 대신 커밋 해시로 고정하는 편이 안전합니다. 태그는 이동할 수 있어 같은 워크플로가 어느 날 다른 코드를 실행할 여지가 있습니다.

넷째, 로그에 민감값이 찍히지 않도록 주의해야 합니다. 시크릿은 자동으로 마스킹되지만, 가공된 형태로 출력하면 마스킹을 피해 갈 수 있으므로 디버그 출력은 배포 잡에서 특히 조심합니다.

다섯째, 배포 잡에서 마이그레이션과 애플리케이션 배포를 한 스텝에 섞지 않는 편이 좋습니다. 문제가 생겼을 때 어느 단계에서 실패했는지 로그만으로 판별하기 어려워집니다.

자주 묻는 질문

배포 자동화를 붙이면 서버에 직접 접속하지 않아도 되나요?

대부분의 반복 작업은 접속 없이 처리할 수 있습니다. 다만 장애 상황에서의 긴급 조치는 여전히 수동 접근이 필요할 수 있으므로, 비상 절차와 접근 권한 관리는 별도로 유지해야 합니다.

시크릿은 저장소와 환경 중 어디에 두는 게 좋나요?

배포 대상이 나뉘어 있다면 환경 시크릿을 권장합니다. 같은 이름으로 스테이징과 운영 값을 따로 두면 워크플로가 환경에 따라 알맞은 값을 받고, 접근 범위도 좁힐 수 있습니다.

셀프 호스팅 러너는 언제 도입해야 하나요?

호스팅 러너에서 사설망 대상에 접근할 수 없거나, 특정 하드웨어와 런타임이 필요할 때 도입합니다. 다만 러너 자체의 패치와 확장, 격리 관리가 운영 부담으로 돌아온다는 점을 감안해야 합니다.

배포가 실패하면 자동으로 되돌릴 수 있나요?

워크플로에 롤백 스텝을 넣어 직전 리비전으로 되돌리는 구성이 가능합니다. 다만 데이터 마이그레이션이 포함된 배포는 자동 롤백이 위험할 수 있으므로, 되돌릴 수 있는 범위를 미리 정해 두는 것이 안전합니다.

출처

배포 자동화는 파이프라인을 만드는 일에서 끝나지 않고, 전환 방식과 롤백, 관측 가능성까지 함께 설계해야 완성됩니다. 무중단 전환과 롤백 전략은 무중단 배포 방식 비교하기, 배포 후 상태 확인은 서버 모니터링 기본 구성 글에서 이어서 확인하실 수 있습니다.