SSM 기반 무중단 CI/CD

2025. 12. 14. 23:03·프로젝트/웹 성능 테스트

시작하며

웹 성능 테스트 플랫폼(Webtest) 프로젝트가 운영 배포를 앞두고 있습니다.
이번 프로젝트에서는 전통적인 SSH 방식이 아닌 AWS Systems Manager(SSM) 기반으로

무중단 SSH 배포 자동화 파이프라인을 구성했습니다.

CI/CD 구현을 준비하면서 어떤 선행 작업이 필요했는지 어떻게 배포 아키텍처를 설계했는지 정리해두고자 합니다.
특히 팀원 누구나 손쉽게 운영 환경에 반영할 수 있도록 명확한 절차와 구조 그리고 실제 운영 중 겪을 수 있는 포인트까지 담았습니다.

 


 

1. CI/CD 구축을 위한 선행 세팅: 체크리스트 중심 정리

A. GitHub 레포지토리 & 브랜치 전략

  • 레포: webtest
  • 브랜치 운영 규칙:
    • develop → 개발 작업 및 테스트
    • main → 운영 배포 트리거용 브랜치

권장 흐름

  • CI (빌드, 테스트, GHCR 이미지 푸시)
    → main, develop 모두에서 실행
  • CD (배포 실행)
    → main push에만 실행

B. 컨테이너 이미지 저장소: GHCR 설정

  • 이미지 네이밍 규칙:
    ghcr.io/<owner>/<image>:<tag>
    • <owner>는 반드시 소문자로 설정
    • 예: ghcr.io/eonseojiancasino/webtest-backend:latest
  • GHCR Pull을 위한 토큰 발급 (EC2에서 docker login용)
    • GitHub Settings → Developer Settings → Personal Access Token 생성
    • 필수 권한: read:packages
    • EC2 내부에 .env 또는 시크릿 파일로 저장

C. EC2 준비 (SSM 배포용)

  • Ubuntu 22.04 기반 EC2 생성 (퍼블릭 IP 필요)
  • 보안 그룹:
    • 80, 443만 오픈
    • 22(SSH)는 닫아도 됨 (SSM 사용 시 필요 없음)
  • 전달받아야 할 값:
    • EC2 Instance ID (SSM용)
    • 퍼블릭 IP (도메인 연결 시 사용)
    • EC2에 부착된 IAM Role 이름 (SSM Agent 등록용)

IAM Role (SSM Agent용) 설정

  • 권한: AmazonSSMManagedInstanceCore
  • EC2에 부착 → Systems Manager의 Managed Nodes에 등록되어야 정상

D. 배포용 IAM User (GitHub Actions → AWS 호출용)

  • 필요한 값:
    • AWS_ACCESS_KEY_ID
    • AWS_SECRET_ACCESS_KEY
    • AWS_REGION
    • SSM_INSTANCE_ID
  • 최소 권한 정책:
    • ssm:SendCommand, ssm:GetCommandInvocation

E. EC2 초기 세팅 (1회 수동 or SSM 명령)

  • 디렉터리 구성: /home/ubuntu/webtest
  • .env 파일 생성: 앱이 필요로 하는 시크릿 저장소
DB_USER=webtest_prod
DB_PASSWORD=...
GHCR_USER=...
GHCR_TOKEN=...
  • 필수 패키지 설치
    • docker, docker compose, certbot (HTTPS용)

 


 

2. CI/CD 전체 흐름 요약: git push → 운영 반영

A. 왜 EC2에서 직접 빌드하지 않는가?

  • 빌드 환경 버전 차이를 CI 서버로 통일할 수 있음
  • EC2는 가볍고 단순한 런타임 서버만 담당
  • 배포 단위는 이미지(GHCR) → 불변 산출물 추적 가능

B. docker compose pull의 의미

  • compose 파일에 정의된 이미지 태그를 기준으로
  • GHCR에서 새 이미지를 내려받음
  • 이후 up -d로 컨테이너 재기동

C. 운영에서 git pull이 필요한 경우

  • 앱 코드만 변경: pull && up -d면 충분
  • 아래 파일이 변경된 경우에는 git pull 필요:
    • docker-compose*.yml
    • nginx.conf, default.conf
    • prometheus.yml

 

3. GitHub Actions에서 SSM으로 배포: deploy.yml 구성

name: Deploy to EC2 via SSM

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: read

    steps:
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Deploy to EC2 via SSM
        run: |
          aws ssm send-command \
            --instance-ids "${{ secrets.SSM_INSTANCE_ID }}" \
            --document-name "AWS-RunShellScript" \
            --comment "webtest deploy" \
            --parameters 'commands=[
              "cd /home/ubuntu/webtest",
              "set -a && source ./.env && set +a",
              "echo $GHCR_TOKEN | docker login ghcr.io -u $GHCR_USER --password-stdin",
              "docker compose -f docker-compose.prod.yml pull",
              "docker compose -f docker-compose.prod.yml up -d",
              "docker compose -f docker-compose.monitoring.yml up -d || true"
            ]'
  • 핵심은 aws ssm send-command로 EC2에서 실제 배포 명령을 원격으로 실행하는 구조입니다.
  • .env는 배포 시크릿이 아닌 런타임 시크릿이므로 EC2 내에서만 존재합니다.

 


 

4. 시크릿 관리: 운영 안정성을 위한 2계층 원칙

구분  내용 저장 위치
런타임 시크릿 DB 계정, API 키 등 앱 실행에 필수 EC2 내부 .env
배포 시크릿 AWS 키, SSM 인스턴스 ID 등 GitHub Secrets

이렇게 계층을 나누면, CI/CD 보안 사고와 앱 구동 오류를 명확히 분리할 수 있습니다.

 


 

5. 도메인 연결 & HTTPS 구성 핵심

A. A 레코드 연결 이유

  • 도메인(example.com)을 EC2 퍼블릭 IP와 매핑하기 위해 필요
  • DNS 요청 시 EC2 IP를 알려주고, 브라우저는 해당 IP로 접속

B. nginx의 역할

  • 외부 포트(80, 443) 수신 → 내부 app:8080으로 리버스 프록시
  • TLS 종료, HTTP → HTTPS 리다이렉트, 헤더 정책 관리

C. certbot의 역할

  • Let’s Encrypt 인증서를 자동 발급/갱신
  • 보통 cron 또는 systemd timer로 갱신 자동화

D. 인증서 파일을 nginx에 마운트하는 이유

  • 인증서는 EC2 호스트의 /etc/letsencrypt에 저장
  • nginx 컨테이너가 이를 참조하려면 호스트 디렉터리 → 컨테이너 디렉터리 마운트가 필요

 


 

6. 운영 

운영 DB  전략

  • 운영용 DB 계정은 .env로 관리, 로컬/개발용과 분리
  • PostgreSQL은 컨테이너 기동 시 환경변수를 기준으로 DB 생성
  • 이후 변경은 수동 SQL 실행이 필요

실수하기 쉬운 포인트

  1. GHCR 이미지 네이밍은 소문자만 허용
    • 대문자 포함 시 Invalid image reference format 오류 발생
  2. 운영 DB는 외부 포트 제거
    • db: ports 삭제로 보안 강화
  3. compose/nginx 변경은 이미지로 반영되지 않음
    • Git pull 또는 파일 복사 배포 필요
  4. GHCR가 private일 경우 EC2에서 docker login 필수
  5. SSM 사용 시 필수 IAM 구성 정리
    • EC2에 SSM Role
    • GitHub에 최소 권한 IAM User

 


 

마치며

이번 웹 성능 테스트 프로젝트에서는 운영 서버에 접속하지 않고도 안전하게 배포할 수 있는 구조를 목표로 아키텍처를 설계했습니다.
CI 서버는 빌드와 이미지 푸시까지 담당하고 EC2는 단순히 이미지를 받아 실행하는 역할만 수행합니다.
덕분에 운영 서버의 복잡도는 줄고 팀원 누구나 명확한 절차에 따라 배포를 수행할 수 있게 되었습니다.

'프로젝트 > 웹 성능 테스트' 카테고리의 다른 글

싸피 백엔드 과정: Spring Security  (0) 2025.11.30
장애 대응을 위한 메트릭 모니터링 단 구축(1. Actuator + Micrometer)  (0) 2025.11.28
롱폴링 비동기 완료  (0) 2025.11.27
비동기 통신 방식 비교와 A/B 테스트 설계  (0) 2025.11.09
Nginx 도입 2편: 적용  (0) 2025.11.09
'프로젝트/웹 성능 테스트' 카테고리의 다른 글
  • 싸피 백엔드 과정: Spring Security
  • 장애 대응을 위한 메트릭 모니터링 단 구축(1. Actuator + Micrometer)
  • 롱폴링 비동기 완료
  • 비동기 통신 방식 비교와 A/B 테스트 설계
yoon4360
yoon4360
자바 백엔드 개발자 지망생입니다
  • yoon4360
    yoon4360님의 블로그
    yoon4360
  • 전체
    오늘
    어제
    • 분류 전체보기 (137)
      • 스프링 (17)
      • 프로젝트 (48)
        • 악취 포집기 앱 (4)
        • 기업 일정 관리 웹 (10)
        • 기술 면접 복습 플랫폼 (18)
        • 웹 성능 테스트 (16)
      • CS (9)
      • 자바 (14)
      • 독서 (1)
      • SQL (1)
      • SSAFY (14)
      • 알고리즘 (15)
      • 기술면접 (8)
      • 데이터베이스 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
yoon4360
SSM 기반 무중단 CI/CD
상단으로

티스토리툴바