CI/CD — GitHub Actions 만으로 충분한 시점
결제·정산 자동화를 직접 운영하는 HEDVION이 GitHub Actions 단일 스택을 선택한 이유, 실제 워크플로우 구성, 비용 트레이드오프, 그리고 갈아탈 시점의 구체적 신호를 정리했다.
결제·정산 환경에서 CI/CD 도구 선택이 유독 예민한 이유
일반적인 웹 서비스라면 배포 파이프라인이 잠깐 멈춰도 "느리다"는 불편으로 끝난다. 결제·정산 시스템은 다르다. 배포 타이밍이 곧 운영 리스크다. 우리 팀은 매일 정해진 시간대에 정산 배치가 돌고, PG사 콜백이 실시간으로 들어오며, 자동화 스케줄러가 분 단위로 작업을 트리거한다. 여기서 CI/CD 파이프라인이 예기치 않게 긴 빌드를 걸거나, 배포 중 컨테이너가 수 초라도 비정상 상태에 놓이면 콜백 유실 또는 정산 누락으로 이어진다.
그래서 우리가 도구를 고를 때 가장 먼저 보는 건 "기능이 많은가"가 아니라 "이 도구가 예측 가능하게 동작하는가"다. Jenkins는 플러그인 생태계가 넓지만, 버전 충돌과 플러그인 업데이트 타이밍을 팀이 직접 관리해야 한다. ArgoCD는 Kubernetes GitOps에 최적화되어 있지만, 그 위에 올라가는 인프라 복잡도 자체가 현재 우리 팀 규모에서는 운영 부채가 된다. GitHub Actions는 GitHub에 통합되어 있어서 "파이프라인 서버가 다운됐다"는 장애 시나리오 자체가 거의 없다. 관리 포인트를 줄이는 것이 곧 결제 시스템 안정성에 기여한다는 판단이다.
GitHub Actions만으로 충분한 조건 — HEDVION 실전 기준
우리가 경험으로 정리한 기준은 세 가지다. 첫째, 저장소가 GitHub에 있다. 당연해 보이지만, 이게 핵심이다. Actions는 PR 오픈, 특정 브랜치 머지, 태그 푸시 같은 GitHub 이벤트를 추가 연동 없이 직접 트리거로 쓴다. 외부 CI 도구를 붙이면 Webhook 설정, 인증 토큰 관리, 네트워크 방화벽 예외 처리가 따라온다. 이 레이어 하나를 없애는 것만으로도 운영 복잡도가 눈에 띄게 줄어든다.
둘째, 하루 빌드 횟수가 50회 이하이고 단일 빌드가 10분 안쪽이다. GitHub Actions의 유료 플랜(Team: 월 $4/user)에서는 Linux runner 기준 월 3,000분이 포함된다. 우리 기준으로 하루 평균 빌드 30회, 빌드당 평균 6분이면 월 사용량은 약 5,400분이다. 초과분은 분당 $0.008, 월 2,400분 초과 시 약 $19 추가다. Jenkins 자체 서버를 t3.medium(월 ~$34)로 유지하는 비용과 비교하면, 서버 관리 공수 제로에 비용도 비슷하거나 낮다. 셋째, 배포 대상이 단일 서버 또는 소수의 인스턴스다. SSH 접속 후 이미지 교체 수준의 배포라면 Actions 내장 기능으로 충분하다.
우리가 실제로 쓰는 워크플로우 구성
메인 파이프라인은 세 잡(Job)으로 나뉜다. lint-and-test 잡에서 린트와 단위 테스트를 돌린다. 결제 로직처럼 엣지 케이스가 많은 코드는 여기서 걸러내는 게 배포 후 롤백보다 훨씬 저렴하다. 이 잡이 통과하면 build-and-push 잡이 Docker 이미지를 빌드해서 레지스트리에 올린다. 이미지 태그는 커밋 SHA를 그대로 쓴다. latest 태그만 쓰면 롤백 시 어떤 버전으로 돌아가는지 추적이 안 된다. SHA 태그를 기본으로 하면 롤백이 "특정 태그로 재배포"라는 명확한 작업이 된다.
마지막 deploy 잡은 build-and-push가 성공했을 때만 실행된다(needs: build-and-push). SSH로 배포 서버에 접속해서 새 이미지를 풀하고 컨테이너를 재시작한다. 정산 배치 서버는 별도 워크플로우로 분리해서, 메인 API 서버 배포와 타이밍이 겹치지 않도록 했다. 정산 배치가 실행 중일 때 배포가 트리거되면 트랜잭션이 중간에 끊길 수 있기 때문이다. 이걸 막기 위해 배포 잡 앞에 배치 실행 여부를 확인하는 간단한 스크립트를 넣었다. ArgoCD의 sync wave 같은 고급 기능 없이도 이 정도 순서 제어는 셸 스크립트 15줄로 처리된다.
수치로 보는 트레이드오프 — 비용만이 아니다
도구 전환 비용은 금전적 비용보다 학습 비용과 디버깅 비용이 더 크다. Jenkins를 처음 도입하면 파이프라인 DSL(Groovy 기반 Jenkinsfile) 학습, 플러그인 호환성 확인, 마스터 노드 고가용성 구성까지 팀원 1명 기준 최소 2~3주가 간다. CircleCI나 GitLab CI는 문법이 다르고, 사내 자체 호스팅 시 서버 유지 공수가 붙는다. 반면 GitHub Actions는 YAML 문법이 단순하고, 공식 문서와 Marketplace 액션이 잘 정리되어 있어서 새 팀원이 워크플로우 파일을 수정하는 데 하루면 충분하다.
실제로 우리가 겪은 케이스 하나를 예로 들면: 특정 PG사 연동 모듈을 분리 서비스로 쪼개면서 배포 파이프라인을 새로 구성해야 했다. 기존 Actions 워크플로우를 복사해서 레지스트리 경로와 배포 서버 주소만 바꿨더니 30분 만에 완료됐다. 만약 Jenkins였다면 새 파이프라인 등록, 자격증명 추가, 에이전트 노드 설정까지 반나절은 잡아야 했을 것이다. 작은 팀에서 반나절은 큰 비용이다.
갈아타야 할 시점 — 모호한 "복잡해지면"이 아니라 구체적인 신호
"서비스가 복잡해지면 바꾼다"는 말은 판단 기준이 아니다. 우리가 정한 전환 신호는 세 가지 구체적인 조건이다. 첫째, 배포 대상 환경이 Kubernetes 클러스터로 전환되고, 서비스가 5개 이상으로 늘어날 때다. 이 시점에는 이미지 교체가 아니라 매니페스트 동기화와 롤아웃 전략이 필요해지고, ArgoCD의 GitOps 모델이 진짜 값어치를 한다. 지금처럼 SSH 재시작으로는 카나리 배포나 블루그린 전환을 안전하게 할 수 없다.
둘째, 월 빌드 시간이 10,000분을 넘고 외부 의존성(대용량 Docker 레이어, 무거운 테스트 스위트)으로 빌드 시간이 15분 이상이 될 때다. 이 시점에 GitHub-hosted runner 비용이 자체 호스팅 러너(self-hosted runner)를 EC2에 올리는 비용보다 커진다. 자체 호스팅으로 전환하면 인스턴스 관리가 생기지만, 캐시 레이어를 로컬에 유지할 수 있어서 빌드 속도가 올라간다. 셋째, 보안 감사나 컴플라이언스 요구로 시크릿 접근 로그와 세밀한 권한 분리가 필요해질 때다. GitHub Secrets는 레포지토리 또는 조직 단위 관리밖에 안 되기 때문에, 이 수준이 되면 HashiCorp Vault나 AWS Secrets Manager와의 연동이 필요해진다.
지금 바로 써먹을 실행 지침
첫째, 워크플로우 파일에서 latest 태그 사용을 지금 당장 없애라. 커밋 SHA나 버전 태그를 이미지 태그로 쓰면 롤백이 한 줄 변경으로 끝난다. latest를 쓰면 롤백할 "이전 버전"이 어디 있는지 찾는 시간이 장애 시간에 더해진다.
둘째, 잡 간 의존 관계를 needs로 명시하고, 배포 잡은 반드시 빌드 성공 후에만 실행되도록 강제하라. 당연해 보이지만, 초기 파이프라인을 빠르게 구성하면서 이 부분을 빠뜨리는 경우가 많다. 테스트가 실패해도 배포가 트리거되는 구성은 결제 시스템에서 치명적이다.
셋째, 정산 배치나 스케줄 작업이 있다면 배포 워크플로우와 별도 파일로 분리하고, 배포 전 실행 중인 배치 여부를 체크하는 로직을 추가하라. 우리는 Redis에 배치 실행 플래그를 기록하고 배포 잡 앞에서 이를 확인하는 방식으로 10줄 이내에 구현했다. 배치 완료 전 배포로 인한 데이터 정합성 문제는 사후 복구가 복잡하다.
넷째, 지금 당장 Jenkins나 ArgoCD로 전환을 검토하고 있다면, 그 전에 현재 파이프라인의 병목부터 측정하라. Actions의 Usage 탭에서 최근 30일 빌드 시간과 실패율을 확인하고, 실제 문제가 도구의 한계인지 워크플로우 설계의 문제인지를 먼저 구분해야 한다. 도구 탓을 하기 전에 현재 도구를 제대로 쓰고 있는지 확인하는 것이 더 빠른 개선 경로다.
* 위 링크는 인프런 affiliate 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
* 위 추천 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.