🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

CodePipeline으로 완전 자동화된 CI/CD 구축 - 슬라이드 1/7
A

AI Generated

2025. 12. 29. · 3 Views

CodePipeline으로 완전 자동화된 CI/CD 구축

AWS CodeCommit, CodeBuild, CodeDeploy, CodePipeline을 활용하여 코드 커밋부터 배포까지 완전히 자동화된 CI/CD 파이프라인을 구축하는 방법을 초급 개발자를 위해 쉽게 설명합니다. 실무 상황을 스토리로 풀어내며 각 단계를 자세히 다룹니다.


목차

  1. CI/CD의 중요성과 AWS 도구
  2. CodeCommit으로 Git 리포지토리 관리
  3. CodeBuild로 빌드 자동화
  4. CodeDeploy로 Blue/Green 배포
  5. CodePipeline으로 전체 파이프라인 연결
  6. 승인 단계 및 알림 통합

1. CI/CD의 중요성과 AWS 도구

스타트업에 입사한 지 한 달 된 김개발 씨는 오늘도 새벽까지 야근을 했습니다. 코드를 수정하고, 테스트하고, 서버에 접속해서 파일을 복사하고, 서비스를 재시작하는 작업을 반복했기 때문입니다.

다음 날 아침, 선배 박시니어 씨가 피곤한 얼굴의 김개발 씨를 보며 물었습니다. "혹시 아직도 수동으로 배포하고 있어요?"

CI/CD는 코드 변경사항을 자동으로 테스트하고 배포하는 개발 프로세스입니다. **CI(Continuous Integration)**는 코드를 자주 통합하고 자동으로 빌드 및 테스트하는 것이고, **CD(Continuous Deployment)**는 검증된 코드를 자동으로 프로덕션 환경에 배포하는 것입니다.

AWS는 이를 위해 CodeCommit, CodeBuild, CodeDeploy, CodePipeline 같은 도구들을 제공합니다.

다음 코드를 살펴봅시다.

// package.json - CI/CD 파이프라인에서 실행할 스크립트 정의
{
  "name": "my-app",
  "version": "1.0.0",
  "scripts": {
    // 빌드 단계에서 실행될 명령어
    "build": "npm run lint && npm run test && npm run compile",
    "lint": "eslint src/**/*.js",
    "test": "jest --coverage",
    "compile": "webpack --mode production",
    // 배포 전 헬스체크
    "health-check": "node scripts/health-check.js"
  }
}

김개발 씨는 지난 한 달간 정말 힘들었습니다. 기능 하나를 개발하는 것도 벅찬데, 그보다 더 힘든 건 배포 과정이었습니다.

로컬에서 코드를 작성하고, 깃허브에 푸시하고, 서버에 SSH로 접속해서 코드를 pull 받고, 빌드하고, 프로세스를 재시작하는 일련의 과정을 매번 반복해야 했습니다. 더 큰 문제는 실수가 잦았다는 점입니다.

어제는 빌드 명령어를 잘못 입력해서 서비스가 다운됐고, 그제는 환경변수 설정을 빼먹어서 에러가 발생했습니다. 사용자들의 불만이 쌓여갔고, 김개발 씨는 점점 자신감을 잃어갔습니다.

박시니어 씨가 김개발 씨의 모니터를 보며 말했습니다. "우리 회사도 초창기에는 그렇게 했어요.

하지만 지금은 코드만 푸시하면 자동으로 모든 게 처리됩니다." "어떻게요?" 김개발 씨가 눈을 반짝이며 물었습니다. "CI/CD 파이프라인을 구축했거든요.

한번 설정해 두면 모든 게 자동화됩니다." CI/CD를 쉽게 비유하자면, 마치 공장의 자동화 생산라인과 같습니다. 예전에는 사람이 직접 부품을 조립하고, 검사하고, 포장했습니다.

하지만 자동화 라인을 구축하면 원자재만 투입하면 완제품이 나옵니다. 소프트웨어 개발도 마찬가지입니다.

개발자는 코드만 작성하면, 나머지는 자동화된 파이프라인이 처리합니다. CI/CD가 없던 시절에는 어땠을까요?

개발자들은 코드를 작성한 후 수동으로 빌드하고, 테스트하고, 배포해야 했습니다. 팀원이 작성한 코드와 충돌이 나는지도 일일이 확인해야 했습니다.

배포 과정에서 실수가 발생하면 서비스 장애로 이어졌습니다. 더 큰 문제는 배포가 두려워져서 코드 변경을 자주 하지 못하게 된다는 점이었습니다.

바로 이런 문제를 해결하기 위해 CI/CD가 등장했습니다. CI/CD를 도입하면 개발자는 코드 작성에만 집중할 수 있습니다.

코드를 커밋하면 자동으로 빌드되고, 테스트되고, 배포됩니다. 문제가 발생하면 즉시 알림을 받습니다.

배포 과정이 표준화되어 실수가 줄어듭니다. AWS는 CI/CD 구축을 위한 완전한 도구 세트를 제공합니다.

CodeCommit은 Git 저장소를 제공합니다. GitHub과 비슷하지만 AWS 서비스들과 완벽하게 통합됩니다.

CodeBuild는 코드를 빌드하고 테스트하는 서비스입니다. 빌드 환경을 자동으로 준비하고, 테스트를 실행하고, 결과를 리포트합니다.

CodeDeploy는 빌드된 애플리케이션을 서버에 배포합니다. 무중단 배포도 가능합니다.

CodePipeline은 이 모든 과정을 하나의 파이프라인으로 연결합니다. 위의 코드를 살펴보면, npm scripts에 빌드 과정을 정의하고 있습니다.

먼저 lint 단계에서 코드 스타일을 검사합니다. 다음으로 test 단계에서 자동화된 테스트를 실행합니다.

마지막으로 compile 단계에서 프로덕션용 코드를 생성합니다. 이 모든 과정이 CodeBuild에서 자동으로 실행됩니다.

실제 현업에서는 어떻게 활용할까요? 쇼핑몰 서비스를 운영한다고 가정해봅시다.

개발자가 상품 검색 기능을 개선하는 코드를 작성합니다. 코드를 CodeCommit에 푸시하면, CodePipeline이 자동으로 동작합니다.

CodeBuild가 코드를 빌드하고 테스트합니다. 테스트를 통과하면 CodeDeploy가 스테이징 서버에 배포합니다.

QA 팀의 승인을 받으면 프로덕션 서버에 자동으로 배포됩니다. 사용자는 다운타임 없이 개선된 검색 기능을 사용할 수 있습니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 테스트 코드 없이 CI/CD를 구축하는 것입니다.

자동화는 양날의 검입니다. 버그가 있는 코드도 자동으로 배포되기 때문입니다.

따라서 충분한 테스트 코드를 작성하고, 품질 게이트를 설정해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

박시니어 씨의 설명을 들은 김개발 씨는 눈이 휘둥그레졌습니다. "그럼 저도 야근 안 해도 되나요?" "물론이죠.

한번 구축해 놓으면 정말 편합니다." CI/CD를 제대로 구축하면 개발 생산성이 몇 배로 높아집니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - CI/CD 도입 시 테스트 커버리지를 최소 70% 이상 유지하세요

  • 작은 프로젝트부터 시작해서 점진적으로 확장하세요
  • 파이프라인 실행 시간을 모니터링하고 10분 이내로 유지하세요

2. CodeCommit으로 Git 리포지토리 관리

김개발 씨는 지금까지 GitHub을 사용해왔습니다. 그런데 박시니어 씨가 새 프로젝트는 CodeCommit을 사용하자고 제안했습니다.

"GitHub도 좋은데 왜 굳이 CodeCommit을 쓰나요?" 김개발 씨가 궁금해하며 물었습니다. "AWS 서비스들과 통합이 정말 편하거든요.

특히 IAM으로 권한 관리하는 게 훨씬 안전해요."

CodeCommit은 AWS에서 제공하는 완전 관리형 Git 저장소 서비스입니다. GitHub이나 GitLab과 유사하지만, AWS 서비스들과 네이티브하게 통합되며, IAM을 통한 세밀한 접근 제어가 가능합니다.

프라이빗 저장소를 무제한으로 생성할 수 있고, 저장소 크기에 제한이 없으며, 가용성이 높습니다.

다음 코드를 살펴봅시다.

# CodeCommit 저장소 생성 및 설정
aws codecommit create-repository \
  --repository-name my-app \
  --repository-description "메인 애플리케이션 저장소"

# Git 자격증명 설정 (HTTPS 방식)
git config --global credential.helper '!aws codecommit credential-helper $@'
git config --global credential.UseHttpPath true

# 저장소 클론
git clone https://git-codecommit.ap-northeast-2.amazonaws.com/v1/repos/my-app

# 일반적인 Git 워크플로우
cd my-app
git checkout -b feature/new-search
# 코드 작성...
git add .
git commit -m "feat: 상품 검색 기능 개선"
git push origin feature/new-search

김개발 씨는 처음에는 이해가 되지 않았습니다. GitHub도 충분히 좋은데 왜 새로운 서비스를 배워야 할까요?

하지만 박시니어 씨의 설명을 듣고 나서 생각이 바뀌었습니다. "GitHub를 쓰면 별도의 액세스 토큰을 관리해야 해요.

팀원이 퇴사하면 토큰을 일일이 삭제해야 하죠. 하지만 CodeCommit은 IAM 사용자와 연동되니까 권한 관리가 훨씬 체계적입니다." CodeCommit을 쉽게 비유하자면, 마치 회사 내부의 문서 관리 시스템과 같습니다.

외부 클라우드 스토리지도 좋지만, 회사 내부 시스템은 사원증으로 접근 권한을 관리하고, 모든 활동이 로그로 남습니다. CodeCommit도 마찬가지로 AWS IAM 자격증명으로 접근을 제어하고, CloudTrail로 모든 활동을 추적할 수 있습니다.

CodeCommit이 없던 시절, 아니 정확히는 CodeCommit을 사용하지 않을 때는 어떤 불편함이 있을까요? 먼저 GitHub나 GitLab에 코드를 저장하면, AWS 리소스에 접근할 때 별도의 자격증명 체계를 관리해야 합니다.

CI/CD 파이프라인 설정도 복잡해집니다. 웹훅을 설정하고, API 토큰을 관리하고, 네트워크 연결을 고민해야 합니다.

프라이빗 저장소를 만들면 비용도 발생합니다. 바로 이런 불편함을 해결하기 위해 AWS는 CodeCommit을 만들었습니다.

CodeCommit을 사용하면 AWS 계정 하나로 모든 것을 관리할 수 있습니다. IAM 정책으로 누가 어떤 저장소에 접근할 수 있는지 세밀하게 제어합니다.

다른 AWS 서비스와 통합할 때도 설정이 간단합니다. CodePipeline에서 CodeCommit 저장소를 소스로 지정하는 건 클릭 몇 번이면 됩니다.

무엇보다 보안이 강력합니다. 모든 데이터는 전송 중에도, 저장될 때도 암호화됩니다.

VPC 엔드포인트를 사용하면 인터넷을 거치지 않고 프라이빗하게 접근할 수 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.

먼저 AWS CLI로 저장소를 생성합니다. 저장소 이름과 설명을 지정하면 몇 초 만에 준비됩니다.

다음으로 Git 자격증명 헬퍼를 설정합니다. 이 설정을 하면 Git 명령어를 실행할 때 자동으로 AWS 자격증명을 사용합니다.

마지막으로 일반적인 Git 워크플로우를 사용합니다. clone, checkout, commit, push 등 익숙한 명령어를 그대로 사용할 수 있습니다.

실제 현업에서는 어떻게 활용할까요? 금융 서비스 회사를 예로 들어봅시다.

보안이 매우 중요한 환경입니다. 코드 저장소도 철저하게 관리해야 합니다.

CodeCommit을 사용하면 개발자마다 IAM 사용자를 할당하고, MFA(다중 인증)를 강제할 수 있습니다. 특정 브랜치에 직접 푸시하지 못하도록 제한하고, 모든 변경사항은 풀 리퀘스트를 통해서만 병합하도록 설정할 수 있습니다.

누가 언제 어떤 코드를 변경했는지 CloudTrail로 추적할 수 있습니다. 한 스타트업 CTO는 이렇게 말했습니다.

"처음에는 GitHub를 썼는데, AWS로 인프라를 이전하면서 CodeCommit도 함께 도입했어요. 자격증명 관리가 정말 편해졌어요.

IAM 역할 하나로 EC2, Lambda, CodeBuild가 모두 저장소에 접근할 수 있거든요." 하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 Git 자격증명 설정을 빼먹는 것입니다.

자격증명 헬퍼를 설정하지 않으면 Git 명령어를 실행할 때마다 사용자 이름과 비밀번호를 입력해야 합니다. 따라서 처음 설정할 때 반드시 credential helper를 활성화해야 합니다.

또 다른 주의사항은 IAM 권한 설정입니다. CodeCommit은 리소스 기반 정책이 아닌 IAM 정책으로 제어됩니다.

사용자나 역할에 적절한 CodeCommit 권한을 부여해야 합니다. 최소 권한 원칙을 따라 필요한 권한만 부여하는 것이 좋습니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 직접 CodeCommit 저장소를 만들어봤습니다.

"생각보다 어렵지 않네요. Git 명령어는 똑같으니까 금방 익숙해질 것 같아요." CodeCommit을 제대로 활용하면 코드 관리가 훨씬 체계적이고 안전해집니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - IAM 정책에서 codecommit:GitPull, codecommit:GitPush 권한을 명시적으로 부여하세요

  • SSH 키 방식보다는 HTTPS 자격증명 헬퍼 방식을 권장합니다
  • 브랜치 보호 규칙을 설정하여 main 브랜치 직접 푸시를 막으세요

3. CodeBuild로 빌드 자동화

새 기능을 개발한 김개발 씨는 코드를 푸시했습니다. 그런데 이번에는 빌드가 자동으로 시작되지 않았습니다.

당황한 김개발 씨가 박시니어 씨를 불렀습니다. "저, 코드는 푸시했는데 빌드가 안 되는데요?" 박시니어 씨가 웃으며 대답했습니다.

"아, buildspec.yml 파일을 아직 안 만드셨군요. CodeBuild가 뭘 해야 할지 모르는 거예요."

CodeBuild는 소스 코드를 컴파일하고, 테스트를 실행하고, 배포 가능한 아티팩트를 생성하는 완전 관리형 빌드 서비스입니다. buildspec.yml 파일에 빌드 단계를 정의하면, CodeBuild가 자동으로 빌드 환경을 준비하고 명령어를 실행합니다.

빌드 서버를 직접 관리할 필요가 없고, 사용한 만큼만 비용을 지불합니다.

다음 코드를 살펴봅시다.

# buildspec.yml - 프로젝트 루트에 위치
version: 0.2

phases:
  # 빌드 전 사전 준비 단계
  pre_build:
    commands:
      - echo "의존성 설치 시작..."
      - npm install
      - echo "환경변수 설정 완료"

  # 실제 빌드 단계
  build:
    commands:
      - echo "빌드 시작..."
      - npm run lint
      - npm run test
      - npm run build

  # 빌드 후 처리 단계
  post_build:
    commands:
      - echo "빌드 완료, 아티팩트 준비 중..."

# 빌드 결과물 지정
artifacts:
  files:
    - '**/*'
  base-directory: dist
  name: build-output-$(date +%Y%m%d-%H%M%S)

# 캐시 설정으로 빌드 속도 개선
cache:
  paths:
    - node_modules/**/*

김개발 씨는 지금까지 로컬 컴퓨터에서 빌드했습니다. npm run build 명령어 하나면 충분했습니다.

그런데 왜 buildspec.yml 같은 복잡한 파일이 필요할까요? 박시니어 씨가 설명을 시작했습니다.

"로컬에서는 개발자 각자의 환경에서 빌드하죠. 어떤 사람은 Node.js 18을 쓰고, 어떤 사람은 20을 씁니다.

운영체제도 다르고요. 이렇게 되면 '내 컴퓨터에서는 되는데요' 문제가 생깁니다." CodeBuild를 쉽게 비유하자면, 마치 표준화된 공장 조립라인과 같습니다.

매번 똑같은 환경에서, 똑같은 순서로, 똑같은 도구를 사용해서 제품을 만듭니다. 작업자가 누구든, 언제 만들든 결과물은 일관됩니다.

소프트웨어 빌드도 마찬가지입니다. 항상 동일한 Docker 이미지에서, 정해진 단계대로 빌드하면 일관된 결과물이 나옵니다.

자동화된 빌드 시스템이 없던 시절에는 어땠을까요? 개발자가 직접 빌드 서버를 관리해야 했습니다.

Jenkins 같은 도구를 설치하고, 서버 용량을 관리하고, 보안 패치를 적용하고, 플러그인을 업데이트해야 했습니다. 빌드가 많이 필요한 시간대에는 서버가 느려졌고, 사용하지 않는 시간에도 비용이 발생했습니다.

빌드 환경도 개발자마다 조금씩 달랐습니다. 바로 이런 문제를 해결하기 위해 CodeBuild가 등장했습니다.

CodeBuild를 사용하면 빌드 서버를 관리할 필요가 없습니다. 빌드가 필요할 때 자동으로 컨테이너가 생성되고, 빌드가 끝나면 삭제됩니다.

사용한 시간만큼만 비용을 지불합니다. 환경도 완벽하게 동일합니다.

buildspec.yml에 정의한 대로 정확히 실행됩니다. 무엇보다 확장성이 뛰어납니다.

동시에 여러 빌드를 실행해도 문제없습니다. 각 빌드는 독립된 컨테이너에서 실행되기 때문입니다.

위의 buildspec.yml 파일을 자세히 살펴보겠습니다. 파일은 크게 세 단계로 구성됩니다.

pre_build 단계에서는 의존성을 설치하고 환경을 준비합니다. npm install로 package.json에 정의된 모든 라이브러리를 다운로드합니다.

build 단계에서는 실제 빌드 작업을 수행합니다. 먼저 코드 스타일을 검사하고, 테스트를 실행하고, 프로덕션 빌드를 생성합니다.

post_build 단계에서는 빌드 결과물을 정리합니다. artifacts 섹션은 빌드 결과물을 지정합니다.

dist 폴더의 모든 파일을 아티팩트로 저장합니다. 이 아티팩트는 S3에 업로드되고, CodeDeploy가 배포할 때 사용합니다.

cache 섹션은 빌드 속도를 크게 개선합니다. node_modules 폴더를 캐시하면, 다음 빌드 때 의존성을 다시 다운로드하지 않아도 됩니다.

빌드 시간이 5분에서 1분으로 줄어들 수 있습니다. 실제 현업에서는 어떻게 활용할까요?

대규모 전자상거래 플랫폼을 운영하는 회사를 예로 들어봅시다. 하루에도 수십 번 코드가 배포됩니다.

개발자가 코드를 푸시하면 CodeBuild가 자동으로 시작됩니다. 먼저 ESLint로 코드 품질을 검사합니다.

다음으로 Jest로 유닛 테스트를 실행합니다. 테스트 커버리지가 80% 미만이면 빌드가 실패합니다.

모든 검사를 통과하면 Webpack으로 프로덕션 빌드를 생성합니다. 결과물은 S3에 저장되고, CloudFront CDN으로 배포됩니다.

한 팀 리더는 이렇게 말했습니다. "예전에는 빌드 서버 관리하느라 시간을 많이 썼어요.

디스크가 꽉 차거나, 메모리가 부족하거나, 플러그인이 충돌하거나. 하지만 CodeBuild로 전환한 후로는 그런 문제가 사라졌어요." 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 buildspec.yml의 경로 설정을 잘못하는 것입니다. base-directory를 잘못 지정하면 아티팩트가 생성되지 않습니다.

또한 환경변수를 하드코딩하는 실수도 흔합니다. API 키나 비밀번호는 절대 buildspec.yml에 직접 쓰면 안 됩니다.

AWS Systems Manager Parameter Store나 Secrets Manager를 사용해야 합니다. 또 다른 주의사항은 빌드 타임아웃입니다.

기본 타임아웃은 60분입니다. 그보다 오래 걸리는 빌드는 실패합니다.

빌드가 너무 오래 걸린다면 캐시를 활용하거나, 불필요한 단계를 제거해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

박시니어 씨의 도움으로 buildspec.yml을 작성한 김개발 씨는 코드를 다시 푸시했습니다. 이번에는 자동으로 빌드가 시작됐습니다.

"와, 신기하다! 제가 아무것도 안 했는데 빌드가 되네요." CodeBuild를 제대로 활용하면 빌드 과정이 완전히 자동화되고, 일관성도 보장됩니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - buildspec.yml은 반드시 버전 관리에 포함시켜 팀원과 공유하세요

  • 빌드 로그를 CloudWatch Logs에 저장하여 문제 발생 시 디버깅하세요
  • 환경변수는 Parameter Store에 저장하고 buildspec에서 참조하세요

4. CodeDeploy로 Blue/Green 배포

빌드까지는 성공했지만, 이제 배포가 문제였습니다. 김개발 씨가 직접 서버에 접속해서 파일을 복사하려 하자, 박시니어 씨가 말렸습니다.

"잠깐! 그렇게 하면 서비스가 잠깐 멈춰요.

사용자들이 에러 페이지를 보게 됩니다." 김개발 씨가 놀라서 물었습니다. "그럼 어떻게 해야 하나요?" "Blue/Green 배포를 쓰면 무중단으로 배포할 수 있어요."

CodeDeploy는 EC2, Lambda, ECS 등에 애플리케이션을 자동으로 배포하는 서비스입니다. 특히 Blue/Green 배포 방식을 사용하면 기존 환경(Blue)을 유지하면서 새 환경(Green)에 배포하고, 검증 후 트래픽을 전환하여 무중단 배포를 구현할 수 있습니다.

문제가 발생하면 즉시 이전 버전으로 롤백할 수 있습니다.

다음 코드를 살펴봅시다.

# appspec.yml - 배포 스펙 정의
version: 0.0
os: linux
files:
  # S3의 빌드 결과물을 서버로 복사
  - source: /
    destination: /var/www/html

hooks:
  # 애플리케이션 중지 전 실행
  BeforeInstall:
    - location: scripts/before-install.sh
      timeout: 300

  # 새 버전 설치 후 실행
  AfterInstall:
    - location: scripts/after-install.sh
      timeout: 300

  # 애플리케이션 시작
  ApplicationStart:
    - location: scripts/start-application.sh
      timeout: 300

  # 헬스체크
  ValidateService:
    - location: scripts/validate-service.sh
      timeout: 300

김개발 씨는 지금껏 배포를 간단하게 생각했습니다. 그냥 새 파일을 서버에 복사하고 프로세스를 재시작하면 되는 거 아닌가요?

하지만 박시니어 씨의 설명을 듣고 현실을 깨달았습니다. "서비스를 재시작하는 몇 초 동안 사용자들은 접속할 수 없어요.

새벽에 배포하면 괜찮겠지만, 한낮에 배포해야 한다면요? 수천 명의 사용자가 동시에 에러를 보게 됩니다." Blue/Green 배포를 쉽게 비유하자면, 마치 무대 뒤 리허설과 같습니다.

공연이 진행 중인 A 무대(Blue)는 그대로 두고, B 무대(Green)에서 새로운 공연을 준비합니다. 리허설이 완벽하면 조명을 B 무대로 전환합니다.

관객은 전환되는 순간조차 느끼지 못합니다. 만약 새 공연에 문제가 있다면 즉시 A 무대로 조명을 다시 돌립니다.

전통적인 배포 방식에는 어떤 문제가 있었을까요? 기존 서버에 직접 새 코드를 배포하는 방식을 In-Place 배포라고 합니다.

이 방식은 간단하지만 위험합니다. 배포 중 서비스가 중단됩니다.

새 버전에 버그가 있어도 사용자에게 즉시 노출됩니다. 롤백하려면 다시 배포해야 하는데, 그 시간 동안 서비스는 계속 문제 상태입니다.

더 큰 문제는 배포 실패 시 복구가 어렵다는 점입니다. 파일을 절반만 복사한 상태에서 에러가 나면 서비스가 완전히 망가질 수 있습니다.

바로 이런 문제를 해결하기 위해 Blue/Green 배포가 등장했습니다. Blue/Green 배포는 완전히 독립된 환경을 두 개 운영합니다.

현재 서비스 중인 Blue 환경은 그대로 두고, 새 버전을 Green 환경에 배포합니다. Green 환경에서 충분히 테스트하고 검증합니다.

모든 게 정상이면 로드밸런서의 타겟을 Blue에서 Green으로 전환합니다. 전환은 1초도 안 걸립니다.

사용자는 서비스 중단을 전혀 느끼지 못합니다. 만약 새 버전에 문제가 발생하면 어떻게 될까요?

다시 Blue로 전환하면 됩니다. 클릭 한 번이면 이전 버전으로 돌아갑니다.

위의 appspec.yml 파일을 자세히 살펴보겠습니다. files 섹션은 어떤 파일을 어디에 복사할지 지정합니다.

S3에 저장된 빌드 결과물을 서버의 /var/www/html로 복사합니다. hooks 섹션이 핵심입니다.

배포 과정의 각 단계에서 실행할 스크립트를 정의합니다. BeforeInstall 훅은 새 버전을 설치하기 전에 실행됩니다.

기존 파일을 백업하거나, 임시 파일을 정리합니다. AfterInstall 훅은 파일 복사 후 실행됩니다.

환경변수를 설정하거나, 설정 파일을 생성합니다. ApplicationStart 훅은 애플리케이션을 시작합니다.

Node.js 앱이라면 pm2로 프로세스를 시작합니다. ValidateService 훅은 가장 중요합니다.

헬스체크를 수행하여 새 버전이 정상인지 확인합니다. 이 단계에서 실패하면 배포가 중단되고 자동으로 롤백됩니다.

실제 현업에서는 어떻게 활용할까요? 온라인 뱅킹 서비스를 운영하는 회사를 생각해봅시다.

24시간 서비스가 중단되면 안 됩니다. 새로운 기능을 배포해야 하는 상황입니다.

CodeDeploy의 Blue/Green 배포를 사용합니다. 먼저 새 버전을 Green 환경에 배포합니다.

Auto Scaling 그룹이 자동으로 새 EC2 인스턴스들을 시작합니다. 각 인스턴스에 애플리케이션이 설치되고, 헬스체크를 통과합니다.

모든 인스턴스가 준비되면 Application Load Balancer가 트래픽을 Green으로 전환합니다. Blue 환경은 1시간 동안 유지되다가 자동으로 종료됩니다.

한 DevOps 엔지니어는 이렇게 말했습니다. "예전에는 배포할 때마다 긴장했어요.

뭔가 잘못될까봐요. 하지만 Blue/Green 배포를 도입한 후로는 자신감이 생겼어요.

문제가 생겨도 즉시 되돌릴 수 있으니까요." 하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 헬스체크를 제대로 구현하지 않는 것입니다.

단순히 HTTP 200 응답만 확인하면 안 됩니다. 데이터베이스 연결, 외부 API 연결 등 핵심 기능이 모두 정상인지 확인해야 합니다.

그렇지 않으면 문제가 있는 버전으로 트래픽이 전환될 수 있습니다. 또 다른 주의사항은 데이터베이스 마이그레이션입니다.

Blue/Green 배포 시 두 버전이 동시에 실행되는 시간이 있습니다. 데이터베이스 스키마를 변경하는 배포는 특별히 조심해야 합니다.

하위 호환성을 유지하거나, 다단계 배포를 수행해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

박시니어 씨의 도움으로 Blue/Green 배포를 설정한 김개발 씨는 첫 배포를 진행했습니다. 새 버전이 Green 환경에 배포되고, 헬스체크를 통과하고, 트래픽이 전환되는 과정을 지켜봤습니다.

"와, 사용자는 전혀 모르겠네요. 정말 신기해요!" CodeDeploy의 Blue/Green 배포를 제대로 활용하면 안전하고 자신감 있게 배포할 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 헬스체크 스크립트는 실제 비즈니스 로직까지 검증하도록 작성하세요

  • Blue 환경 유지 시간을 최소 30분 이상 설정하여 문제 발견 시 롤백하세요
  • 배포 로그를 S3에 저장하여 문제 발생 시 분석하세요

5. CodePipeline으로 전체 파이프라인 연결

이제 CodeCommit, CodeBuild, CodeDeploy를 모두 설정했습니다. 하지만 김개발 씨는 여전히 각 단계를 수동으로 실행해야 했습니다.

코드를 푸시하고, CodeBuild 콘솔에 들어가서 빌드를 시작하고, 빌드가 끝나면 CodeDeploy 콘솔에서 배포를 시작했습니다. 박시니어 씨가 웃으며 말했습니다.

"이제 마지막 단계만 남았어요. CodePipeline으로 모든 걸 자동으로 연결하는 거예요."

CodePipeline은 소프트웨어 릴리스 프로세스를 자동화하는 CI/CD 서비스입니다. 소스 단계(CodeCommit), 빌드 단계(CodeBuild), 배포 단계(CodeDeploy)를 하나의 파이프라인으로 연결합니다.

코드가 푸시되면 자동으로 전체 프로세스가 실행되며, 각 단계의 성공/실패를 시각적으로 확인할 수 있습니다.

다음 코드를 살펴봅시다.

# AWS CLICodePipeline 생성 (pipeline-config.json 파일 사용)
{
  "pipeline": {
    "name": "MyAppPipeline",
    "roleArn": "arn:aws:iam::123456789012:role/CodePipelineServiceRole",
    "stages": [
      {
        "name": "Source",
        "actions": [{
          "name": "SourceAction",
          "actionTypeId": {
            "category": "Source",
            "owner": "AWS",
            "provider": "CodeCommit",
            "version": "1"
          },
          "configuration": {
            "RepositoryName": "my-app",
            "BranchName": "main"
          },
          "outputArtifacts": [{"name": "SourceOutput"}]
        }]
      },
      {
        "name": "Build",
        "actions": [{
          "name": "BuildAction",
          "actionTypeId": {
            "category": "Build",
            "owner": "AWS",
            "provider": "CodeBuild",
            "version": "1"
          },
          "configuration": {
            "ProjectName": "MyAppBuild"
          },
          "inputArtifacts": [{"name": "SourceOutput"}],
          "outputArtifacts": [{"name": "BuildOutput"}]
        }]
      },
      {
        "name": "Deploy",
        "actions": [{
          "name": "DeployAction",
          "actionTypeId": {
            "category": "Deploy",
            "owner": "AWS",
            "provider": "CodeDeploy",
            "version": "1"
          },
          "configuration": {
            "ApplicationName": "MyApp",
            "DeploymentGroupName": "Production"
          },
          "inputArtifacts": [{"name": "BuildOutput"}]
        }]
      }
    ],
    "artifactStore": {
      "type": "S3",
      "location": "my-pipeline-artifacts-bucket"
    }
  }
}

김개발 씨는 이제 피곤했습니다. CodeCommit에 코드를 푸시하고, AWS 콘솔에 로그인하고, CodeBuild로 이동해서 빌드를 시작하고, 빌드가 끝날 때까지 기다리고, CodeDeploy로 이동해서 배포를 시작하는 과정이 번거로웠습니다.

"이것도 자동화할 수 없나요?" 박시니어 씨가 고개를 끄덕였습니다. "바로 그걸 위한 게 CodePipeline이에요.

코드만 푸시하면 나머지는 전부 자동이에요." CodePipeline을 쉽게 비유하자면, 마치 공항의 수하물 처리 시스템과 같습니다. 승객이 짐을 맡기면(코드 푸시), 자동으로 컨베이어 벨트를 따라 이동합니다.

보안 검사대를 통과하고(빌드 및 테스트), 분류 센터를 거쳐(아티팩트 저장), 최종적으로 비행기에 실립니다(배포). 중간에 문제가 생기면(테스트 실패) 프로세스가 중단되고 알림이 갑니다.

모든 과정은 자동이고, 실시간으로 진행 상황을 볼 수 있습니다. 각 도구를 따로따로 사용하면 어떤 문제가 있을까요?

먼저 사람이 개입해야 하는 지점이 많습니다. 빌드를 시작하고, 결과를 확인하고, 배포를 시작하는 일을 수동으로 해야 합니다.

실수할 여지가 많습니다. 빌드가 실패했는데 배포를 진행할 수도 있습니다.

또한 전체 프로세스를 한눈에 보기 어렵습니다. 지금 어느 단계인지, 어디서 실패했는지 파악하려면 여러 콘솔을 확인해야 합니다.

바로 이런 불편함을 해결하기 위해 CodePipeline이 등장했습니다. CodePipeline을 설정하면 모든 게 자동으로 연결됩니다.

개발자가 main 브랜치에 코드를 푸시하는 순간, 파이프라인이 시작됩니다. Source 단계에서 최신 코드를 가져옵니다.

Build 단계에서 CodeBuild가 자동으로 실행됩니다. 테스트를 통과하면 Deploy 단계로 진행됩니다.

CodeDeploy가 Blue/Green 배포를 수행합니다. 전체 과정이 보통 10-15분 안에 완료됩니다.

각 단계의 상태가 실시간으로 표시됩니다. 파란색은 진행 중, 초록색은 성공, 빨간색은 실패입니다.

어느 단계에서 실패했는지 즉시 알 수 있고, 로그를 바로 확인할 수 있습니다. 위의 JSON 설정 파일을 자세히 살펴보겠습니다.

파이프라인은 세 개의 stage로 구성됩니다. 첫 번째 Source 스테이지는 CodeCommit에서 코드를 가져옵니다.

main 브랜치의 변경사항을 감지하면 자동으로 실행됩니다. 출력으로 SourceOutput 아티팩트를 생성합니다.

두 번째 Build 스테이지는 SourceOutput을 입력으로 받아 CodeBuild 프로젝트를 실행합니다. buildspec.yml에 정의된 단계대로 빌드하고, BuildOutput 아티팩트를 생성합니다.

세 번째 Deploy 스테이지는 BuildOutput을 입력으로 받아 CodeDeploy로 배포합니다. Production 배포 그룹에 Blue/Green 배포를 수행합니다.

artifactStore는 중간 결과물을 저장할 S3 버킷을 지정합니다. 각 스테이지 간 데이터 전달에 사용됩니다.

실제 현업에서는 어떻게 활용할까요? SaaS 기업을 예로 들어봅시다.

여러 개발자가 동시에 작업합니다. 각자 feature 브랜치에서 개발하고, 준비되면 main 브랜치에 병합합니다.

병합되는 순간 파이프라인이 자동으로 시작됩니다. Slack 채널에 "파이프라인 시작됨" 알림이 옵니다.

10분 후 "배포 완료" 알림이 옵니다. 팀원들은 각자의 작업에 집중하다가, 알림만 확인하면 됩니다.

어떤 커밋이 현재 프로덕션에 배포되어 있는지도 명확합니다. 파이프라인 이력을 보면 알 수 있습니다.

문제가 생기면 어떤 변경사항 때문인지 쉽게 추적할 수 있습니다. 한 CTO는 이렇게 말했습니다.

"CodePipeline 도입 전에는 배포가 두려웠어요. 뭔가 놓칠까봐요.

하지만 지금은 하루에도 여러 번 배포합니다. 모든 게 자동이고, 실패하면 즉시 알림이 오니까 안심이 돼요." 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 파이프라인을 너무 복잡하게 만드는 것입니다. 처음에는 Source, Build, Deploy 세 단계면 충분합니다.

익숙해지면 테스트 단계, 승인 단계 등을 추가할 수 있습니다. 너무 많은 단계를 한 번에 추가하면 문제가 생겼을 때 디버깅하기 어렵습니다.

또 다른 주의사항은 IAM 권한입니다. CodePipeline이 다른 서비스를 호출하려면 적절한 권한이 필요합니다.

CodeCommit 읽기, CodeBuild 실행, CodeDeploy 시작, S3 읽기/쓰기 권한 등을 모두 부여해야 합니다. 권한이 부족하면 파이프라인이 중간에 실패합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 도움으로 파이프라인을 설정한 김개발 씨는 테스트로 간단한 코드를 푸시했습니다.

CodePipeline 콘솔을 새로고침하자, Source 단계가 파란색으로 바뀌었습니다. 곧 Build 단계가 시작되고, 몇 분 후 Deploy 단계로 넘어갔습니다.

모든 단계가 초록색으로 바뀌었습니다. "정말 아무것도 안 했는데 배포가 됐어요!" CodePipeline을 제대로 활용하면 진정한 CI/CD 자동화를 경험할 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 파이프라인 이름을 명확하게 지어 여러 파이프라인 관리를 쉽게 하세요

  • 각 스테이지마다 타임아웃을 적절히 설정하여 무한 대기를 방지하세요
  • 파이프라인 실행 이력을 정기적으로 검토하여 병목 구간을 찾으세요

6. 승인 단계 및 알림 통합

파이프라인이 완벽하게 동작했습니다. 하지만 김개발 씨는 불안했습니다.

"코드를 푸시하면 바로 프로덕션에 배포되는 게 좀 무섭지 않나요? 혹시 실수로 버그가 있는 코드를 푸시하면요?" 박시니어 씨가 고개를 끄덕였습니다.

"좋은 지적이에요. 그래서 보통은 승인 단계를 추가해요.

배포 전에 사람이 최종 확인하는 거죠. 그리고 Slack으로 알림도 보내고요."

**승인 단계(Manual Approval)**는 파이프라인 중간에 사람의 검토와 승인을 요구하는 단계입니다. 스테이징 환경에 배포된 후 프로덕션 배포 전에 승인 단계를 두면, QA 팀이나 팀 리더가 최종 확인할 수 있습니다.

**SNS(Simple Notification Service)**와 연동하면 Slack, 이메일 등으로 알림을 받을 수 있어 파이프라인 상태를 실시간으로 파악할 수 있습니다.

다음 코드를 살펴봅시다.

# CodePipeline에 승인 단계 추가 (JSON 설정 일부)
{
  "name": "Approval",
  "actions": [{
    "name": "ManualApproval",
    "actionTypeId": {
      "category": "Approval",
      "owner": "AWS",
      "provider": "Manual",
      "version": "1"
    },
    "configuration": {
      // SNS 토픽으로 승인 요청 알림 전송
      "NotificationArn": "arn:aws:sns:ap-northeast-2:123456789012:pipeline-approvals",
      "CustomData": "스테이징 환경에서 테스트 후 승인해주세요. 배포 URL: https://staging.example.com"
    }
  }]
}

# Lambda 함수로 Slack 알림 전송 (Node.js)
// SNS 메시지를 받아 Slack으로 전송
exports.handler = async (event) => {
  const message = JSON.parse(event.Records[0].Sns.Message);
  const pipelineName = message.approval.pipelineName;
  const stageName = message.approval.stageName;

  // Slack Webhook으로 메시지 전송
  await fetch(process.env.SLACK_WEBHOOK_URL, {
    method: 'POST',
    body: JSON.stringify({
      text: `🚀 ${pipelineName} 파이프라인 승인 필요\n스테이지: ${stageName}\n승인 URL: ${message.approval.approvalReviewLink}`
    })
  });

  return { statusCode: 200 };
};

김개발 씨의 걱정은 당연했습니다. 완전 자동화는 편리하지만, 위험할 수도 있습니다.

테스트를 통과했다고 해서 모든 버그가 잡히는 건 아닙니다. UI가 깨졌거나, 특정 상황에서만 발생하는 버그는 자동화된 테스트로 잡기 어렵습니다.

박시니어 씨가 설명을 시작했습니다. "그래서 우리는 두 단계 배포 전략을 씁니다.

먼저 스테이징 환경에 자동 배포하고, QA 팀이 테스트합니다. 문제없으면 승인하고, 그때 프로덕션에 배포돼요." 승인 단계를 쉽게 비유하자면, 마치 공항 보안 검색대와 같습니다.

수하물은 X-ray 기계로 자동 검사됩니다(자동 테스트). 하지만 의심스러운 물건이 발견되거나 중요한 물품은 보안 요원이 직접 확인합니다(수동 승인).

기계가 아무리 발전해도 사람의 최종 판단이 필요한 순간이 있습니다. 승인 단계 없이 완전 자동화하면 어떤 문제가 있을까요?

자동화된 테스트는 완벽하지 않습니다. 코드는 정상이지만 UI가 특정 브라우저에서 깨질 수 있습니다.

성능 저하가 발생할 수 있습니다. 비즈니스 로직이 의도와 다르게 동작할 수 있습니다.

이런 문제들은 사람이 직접 확인해야 발견할 수 있습니다. 또한 중요한 배포는 특정 시간에만 하고 싶을 수 있습니다.

예를 들어 대규모 세일 기간에는 배포를 피하고 싶습니다. 완전 자동화되면 개발자가 코드를 푸시하는 순간 배포되어 버립니다.

바로 이런 이유로 승인 단계를 추가합니다. 승인 단계를 스테이징 배포와 프로덕션 배포 사이에 넣습니다.

스테이징 환경에 배포되면 파이프라인이 일시 정지됩니다. SNS를 통해 알림이 전송됩니다.

QA 팀 리더의 이메일과 Slack 채널에 메시지가 옵니다. "새 버전이 스테이징에 배포되었습니다.

테스트 후 승인해주세요." QA 팀은 스테이징 환경에서 꼼꼼히 테스트합니다. 주요 기능이 정상 동작하는지, UI가 깨지지 않았는지, 성능은 괜찮은지 확인합니다.

모든 게 정상이면 AWS 콘솔이나 이메일의 승인 링크를 클릭합니다. 파이프라인이 재개되고 프로덕션 배포가 진행됩니다.

위의 코드를 자세히 살펴보겠습니다. 첫 번째 JSON 설정은 승인 단계를 정의합니다.

actionTypeId의 category가 "Approval"이고 provider가 "Manual"입니다. configuration에서 NotificationArn을 지정하면 SNS 토픽으로 알림이 전송됩니다.

CustomData에는 승인자에게 보여줄 메시지를 작성합니다. 스테이징 URL을 포함하면 승인자가 바로 테스트할 수 있습니다.

두 번째 Lambda 함수는 SNS 메시지를 받아 Slack으로 전송합니다. SNS 토픽을 Lambda 함수의 트리거로 설정하면, 승인 요청이 발생할 때마다 자동으로 실행됩니다.

Slack Webhook URL로 메시지를 보내면, 팀 채널에 알림이 표시됩니다. 승인 링크도 함께 보내면 Slack에서 바로 승인할 수 있습니다.

실제 현업에서는 어떻게 활용할까요? 이커머스 플랫폼을 운영하는 회사를 생각해봅시다.

주말마다 대규모 세일 이벤트를 진행합니다. 평일에는 자동 배포하지만, 금요일 저녁부터 일요일까지는 배포를 최대한 자제합니다.

승인 단계를 통해 이를 제어합니다. 개발자가 코드를 푸시하면 스테이징까지는 자동으로 배포됩니다.

하지만 프로덕션 배포는 DevOps 팀 리더의 승인이 필요합니다. 금요일 오후에 승인 요청이 오면, 리더는 월요일까지 기다렸다가 승인합니다.

Slack 알림 덕분에 팀원 모두가 배포 상황을 실시간으로 알 수 있습니다. "빌드 시작", "스테이징 배포 완료", "승인 대기 중", "프로덕션 배포 완료" 같은 메시지가 채널에 흐릅니다.

문제가 생기면 즉시 파악하고 대응할 수 있습니다. 한 프로덕트 매니저는 이렇게 말했습니다.

"예전에는 '지금 어떤 버전이 배포되어 있지?'라고 개발팀에 물어봐야 했어요. 하지만 지금은 Slack만 보면 돼요.

모든 배포 이력이 남아 있거든요." 하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 승인 단계를 너무 많이 추가하는 것입니다.

매 단계마다 승인을 받으면 오히려 비효율적입니다. 보통은 프로덕션 배포 직전 한 곳에만 두는 것이 적절합니다.

또한 승인 타임아웃을 설정하지 않으면 파이프라인이 무한정 대기할 수 있습니다. 7일 정도로 타임아웃을 설정하는 것이 좋습니다.

SNS 알림도 주의해야 합니다. 너무 많은 알림을 보내면 사람들이 무시하게 됩니다.

중요한 이벤트만 알림을 보내고, 상세 로그는 CloudWatch에서 확인하도록 하세요. 다시 김개발 씨의 이야기로 돌아가 봅시다.

박시니어 씨의 도움으로 승인 단계와 Slack 알림을 설정한 김개발 씨는 테스트 배포를 진행했습니다. 코드를 푸시하자 Slack에 "빌드 시작" 메시지가 왔습니다.

몇 분 후 "스테이징 배포 완료, 승인 필요" 메시지가 왔습니다. 스테이징 환경에서 테스트한 후 승인 링크를 클릭했습니다.

곧 "프로덕션 배포 완료" 메시지가 왔습니다. "이제 정말 완벽한 CI/CD 파이프라인이네요!" 승인 단계와 알림을 제대로 활용하면 자동화의 효율성과 사람의 통제를 균형있게 결합할 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 승인 타임아웃을 7일로 설정하여 장기 방치를 방지하세요

  • Slack 알림에 배포 버전 정보와 커밋 메시지를 포함하세요
  • 승인 권한은 팀 리더나 시니어 개발자로 제한하여 책임을 명확히 하세요

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#AWS#CodePipeline#CodeCommit#CodeBuild#CodeDeploy#AWS,CI/CD,DevOps

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

함께 보면 좋은 카드 뉴스

3D 모델링 기초 실습 완벽 가이드

Blender를 활용한 3D 모델링의 기본기를 다집니다. 나무, 지형, 텍스트부터 복잡한 형태까지, 실전에서 바로 활용할 수 있는 모델링 기법을 단계별로 학습합니다.

Three.js와 Blender로 시작하는 3D 웹 개발

3D 웹의 세계로 첫발을 내딛는 개발자들을 위한 가이드입니다. Blender로 모델을 만들고 Three.js로 웹에 구현하는 전체 과정을 실무 스토리와 함께 쉽게 풀어냅니다. 설치부터 첫 3D 씬 구현까지 단계별로 배워봅시다.

실전 프로젝트 글로벌 엔터프라이즈급 AWS 아키텍처

글로벌 서비스를 위한 엔터프라이즈급 AWS 아키텍처 설계부터 구축까지 실전 프로젝트로 배우는 완벽 가이드입니다. 멀티 리전 고가용성, 보안, 모니터링, CI/CD까지 실무에서 바로 적용할 수 있는 노하우를 담았습니다.

ECS와 EKS로 컨테이너 오케스트레이션 완벽 가이드

AWS에서 컨테이너를 운영하는 두 가지 핵심 서비스인 ECS와 EKS를 비교하고, 실무에서 어떻게 활용하는지 단계별로 알아봅니다. 서버리스 컨테이너부터 서비스 메시까지 컨테이너 오케스트레이션의 모든 것을 다룹니다.

AWS 비용 최적화 및 FinOps 전략 완벽 가이드

AWS 클라우드 비용을 효과적으로 관리하고 최적화하는 방법을 알아봅니다. Reserved Instance, Spot Instance, Savings Plans 등 다양한 비용 절감 전략과 FinOps 사고방식을 초급 개발자도 쉽게 이해할 수 있도록 설명합니다.