SideImpact 개선기 1편: 번거로운 수동 배포 자동화

L-cloud·2025년 9월 16일
0

sideimpact

목록 보기
1/2
post-thumbnail

본 글은 개발 환경의 배포 자동화에 대한 가벼운 경험을 공유하는 글입니다. 복잡한 롤백 전략이나 Blue/Green, 카나리 배포 등을 다루고 있지 않습니다.

새로운 역할

2025년 2분기부터 sideimpact.io의 백엔드 개발과 운영을 맡게 되었습니다.

기존에 잘 동작하던 서비스이지만, 서비스 기획과 비즈니스 요구 사항 변화에 더욱 잘 대응 하기 위해 내부적으로 많은 개선 작업을 시도하고 있습니다. 앞으로 몇 개의 글에 걸쳐 이 개선기들을 하나씩 공유해보고자 합니다.

그 첫 번째 이야기는 바로 개발(Dev) 환경의 CI/CD 개선기입니다.

개발 환경은 AWS EC2와 ALB를 사용하는, 비교적 간단한 구조입니다. 물론 운영(Production) 환경은 ECS, CodeBuild, CodeDeploy를 사용해 배포 중단이나 롤백이 가능한, 비교적 안정적인 CI/CD 파이프라인이 구축되어 있습니다.

그런데 개발 환경은 상황이 좀 달랐습니다.

기존의 수동 배포 방식

새로운 코드를 개발 환경에 배포하려면 아래와 같은 과정을 거쳐야 했습니다.

  1. 내 로컬 컴퓨터에서 개발 서버 EC2로 SSH 접속
  2. 서버에서 최신 코드를 받기 위해 git pull
  3. tmux 세션에 들어가 기존에 돌고 있던 도커 컨테이너를 내리고, 다시 docker buildup으로 실행

어떠신가요? 과정이 복잡하진 않지만, 매우 번거롭습니다.
사소한 수정 사항을 반영할 때마다 매번 이 과정을 반복해야 했죠. 심지어 보안을 위해 SSH 접속 IP를 제한해 두었기 때문에, 외부에서 작업할 땐 IP를 등록해야 하는 관리 포인트까지 존재했습니다.

개선 목표: 최소한의 수정과 무비용

반복적인 수동 작업을 좋아하는 개발자는 없겠죠. 하지만 다른 기능 개발도 쌓여 있는 상황에서, 개발 환경 배포를 자동화하자고 거창한 시스템을 도입하는 건 너무 비효율적이라고 생각했습니다. 이번 작업에서 중요한 것은 정교함이 아니라 실용성이라고 생각하여 거창한 파이프라인 대신, 몇 가지 단순하고 실용적인 목표를 세웠습니다.

  • 첫째, 기존 docker build up 구조는 그대로 유지한다.
  • 둘째, 새로운 서비스를 도입해 관리 포인트를 늘리지 않는다.
  • 셋째, 비용을 쓰지 않는다.

이 조건들을 만족시킬 조합을 고민하다, 두 가지 도구를 떠올렸습니다. 바로 GitHub ActionsAWS Systems Manager(SSM)입니다.

  • GitHub Actions: GitHub 저장소(repository)를 기반으로 테스트, 빌드, 배포 등 다양한 작업을 자동화하는 워크플로우 도구입니다. Free 플랜 사용자에게 매달 2,000분의 넉넉한 무료 사용 시간을 제공합니다.
  • AWS SSM: SSH 접속 없이 EC2에 원격 명령을 내리게 해주는 AWS의 무료 기능입니다. 덕분에 보안 포트를 열거나 IP를 관리할 필요가 없어집니다.

Dev 브랜치에 코드를 푸시하면, GitHub Actions가 이 SSM Run Command를 호출해서 EC2에 배포 스크립트를 실행시키는 그림이 그려지지 않나요?

하지만 여기서 중요한 질문이 하나 생깁니다. "GitHub Actions가 어떻게 내 EC2에 명령을 내리도록 허락할 수 있을까?"

아무런 인증/인가 절차가 없다면, 누구나 내 서버에 마음대로 명령을 내릴 수 있겠죠. 가장 단순한 방법은 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY를 GitHub Actions의 Secret에 저장하는 것이지만 장기 자격 증명을 외부에 저장해야 한다는 점이 내키지 않았습니다.

OIDC (Open ID Connect)

OIDC는 GitHub Actions가 AWS에 직접 키를 저장하지 않고도, 필요한 작업 수행을 위한 임시 자격 증명을 안전하게 발급받을 수 있게 해주는 표준 프로토콜입니다.

AWS IAM에서 특정 GitHub 저장소 및 브랜치만 신뢰하도록 역할을 설정하고, GitHub Actions 워크플로우에서는 그 역할을 사용하겠다고 선언만 해주면 됩니다. 덕분에 더 이상 민감한 키를 코드나 설정에 보관할 필요가 없어집니다.

자세한 설정 방법은 AWS와 GitHub 양쪽에 약간의 설정이 필요한데, 이 글에 정말 잘 설명되어 있습니다.

저는 아래 처럼 GitHub Actions 마켓플레이스에 있는 다양한 기능들을 자유롭게 조합하여 워크플로우를 구성했습니다.


jobs:
  deploy-dev:
    # ... (생략) ...
    permissions: # OIDC 사용을 위해 GitHub에 토큰 발급 권한 부여
      id-token: write
      contents: read

    steps:
      - name: Configure AWS credentials with OIDC
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam:: ... # AWS OIDC 역할 ARN
          
      - name: Send Command to EC2
        id: send_command
        run: | # docker build, up 하는 스크립트 실행
          COMMAND_ID=$(aws ssm send-command ...)
          echo "COMMAND_ID=$COMMAND_ID" >> $GITHUB_OUTPUT

      - name: Wait for command to finish
        run: | # 위에서 보낸 명령이 끝날 때까지 대기
          aws ssm wait command-executed \
            --command-id ${{ steps.send_command.outputs.COMMAND_ID }} \
            --instance-id ${{ secrets.EC2_INSTANCE_ID_DEV }}
      
      # ... (이후 테스트 및 Slack 알림 로직 생략)
  1. 명령 전송: aws ssm send-command를 통해 EC2에 배포 스크립트(docker build, up)를 실행하라는 명령을 보냅니다.

  2. 실행 대기 및 테스트: aws ssm send-command가 완전히 끝날 때까지 기다린 후, 서비스가 정말 잘 실행되었는지 curl 같은 명령으로 간단한 테스트(ping)를 진행합니다.

  3. 결과 알림: 마지막으로, 이 테스트 결과를 바탕으로 배포의 성공 또는 실패 여부를 Slack으로 알림을 보냅니다.

결론

이 방식이 모든 상황에 맞는 완벽한 해결책은 당연히 아닙니다.

만약 배포에 실패한다면 어떻게 될까요? 네, 결국 AWS 콘솔에 접속해서 SSM의 명령 기록(Command history)을 보고 로그를 직접 확인해야 합니다. 상황에 따라서는 다시 EC2에 SSH로 접속해 수동으로 재배포를 해야 할 수도 있죠.

하지만 개발 환경에서는 이 정도의 단점은 충분히 감수할 만했습니다.

무엇보다 확실한 것은, 이전보다 비교할 수 없이 편해졌다는 사실입니다.

롤백 전략까지는 필요 없는 개발 환경에서, 비용 없이 간편하게 CI/CD를 구성해보고 싶다면 GitHub Actions와 SSM 조합을 고려해 볼 만합니다.

긴 글 읽어주셔서 감사합니다 :)

profile
내가 배운 것 정리

0개의 댓글