🤖

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

⚠️

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

이미지 로딩 중...

CodeDeploy 배포 전략 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 12. 20. · 6 Views

CodeDeploy 배포 전략 완벽 가이드

AWS CodeDeploy의 다양한 배포 전략을 초급 개발자 눈높이에 맞춰 설명합니다. 블루/그린 배포, 롤링 배포부터 실전 appspec.yml 작성까지 실무에서 바로 쓸 수 있는 배포 노하우를 담았습니다.


목차

  1. CodeDeploy란?
  2. ECS 배포 유형
  3. 블루/그린 배포
  4. 롤링 배포
  5. appspec.yml 작성
  6. 배포 롤백

1. CodeDeploy란?

입사 6개월 차 김개발 씨는 처음으로 서비스 배포를 맡게 되었습니다. 선배 박시니어 씨가 말합니다.

"수동 배포는 위험해요. CodeDeploy를 사용해봅시다."

CodeDeploy는 AWS에서 제공하는 자동 배포 서비스입니다. 마치 택배 시스템이 물건을 안전하게 배송하듯이, 코드를 안전하게 서버에 배포해줍니다.

EC2, ECS, Lambda 등 다양한 환경을 지원하며, 자동 롤백 기능으로 안정성을 보장합니다.

다음 코드를 살펴봅시다.

// buildspec.yml - CodeBuild에서 빌드 후 CodeDeploy로 전달
version: 0.2
phases:
  install:
    runtime-versions:
      nodejs: 18
  build:
    commands:
      - npm install
      - npm run build
artifacts:
  files:
    - '**/*'  # 모든 파일을 아티팩트로 생성
  name: BuildArtifact

김개발 씨는 지금까지 서버에 접속해서 직접 코드를 업데이트했습니다. git pull을 실행하고, npm install을 돌리고, 서버를 재시작하는 작업을 매번 반복했습니다.

그런데 어느 날 실수로 잘못된 브랜치를 배포했고, 서비스가 30분 동안 다운되는 사고가 발생했습니다. 박시니어 씨가 사고 리포트를 보며 말합니다.

"이제는 자동화할 때가 됐네요. 수동 배포는 이런 위험이 항상 따라다니니까요." 그렇다면 CodeDeploy란 무엇일까요?

쉽게 비유하자면, CodeDeploy는 마치 택배 시스템과 같습니다. 온라인 쇼핑몰에서 물건을 주문하면 택배 기사가 안전하게 배송하고, 문제가 있으면 반품도 처리해주죠.

CodeDeploy도 마찬가지입니다. 개발자가 코드를 커밋하면, 자동으로 서버에 배포하고, 문제가 생기면 이전 버전으로 롤백해줍니다.

수동 배포의 문제점은 명확했습니다. 첫째, 사람이 직접 하다 보니 실수가 발생합니다.

잘못된 명령어를 입력하거나, 필요한 단계를 빠뜨리기 쉽습니다. 둘째, 배포 중 서버가 다운되는 시간이 발생합니다.

서비스를 중단하고 업데이트한 후 다시 시작해야 하니까요. 셋째, 여러 서버를 관리할 때 일관성을 유지하기 어렵습니다.

바로 이런 문제를 해결하기 위해 CodeDeploy가 등장했습니다. CodeDeploy를 사용하면 배포 프로세스를 완전히 자동화할 수 있습니다.

코드를 푸시하면 자동으로 빌드되고, 테스트를 거쳐, 서버에 배포됩니다. 또한 다양한 배포 전략을 선택할 수 있습니다.

한 번에 모든 서버를 업데이트할 수도 있고, 점진적으로 업데이트할 수도 있습니다. 무엇보다 자동 롤백 기능이 강력합니다.

배포 후 헬스체크에 실패하면 자동으로 이전 버전으로 되돌립니다. 김개발 씨처럼 잘못된 배포로 인한 서비스 중단을 방지할 수 있습니다.

위의 buildspec.yml 파일을 살펴보겠습니다. 먼저 version 항목은 buildspec의 버전을 지정합니다.

phases 섹션에서는 빌드 단계를 정의합니다. install 단계에서 Node.js 18을 설치하고, build 단계에서 의존성을 설치하고 빌드를 실행합니다.

마지막으로 artifacts 섹션에서 빌드 결과물을 지정합니다. 이 아티팩트가 CodeDeploy로 전달됩니다.

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

블랙프라이데이 같은 대규모 이벤트 기간에는 안정성이 매우 중요합니다. CodeDeploy를 사용하면 새 기능을 배포하면서도 서비스 중단 없이 운영할 수 있습니다.

배포 중에도 기존 서버가 계속 요청을 처리하고, 새 버전이 준비되면 트래픽을 전환합니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 IAM 권한 설정을 잘못하는 것입니다. CodeDeploy가 EC2나 ECS에 접근하려면 적절한 권한이 필요한데, 이를 빠뜨리면 배포가 실패합니다.

따라서 IAM 역할을 제대로 설정하고, 필요한 정책을 연결해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다. "아, 자동화하면 실수도 줄고 안전하게 배포할 수 있겠네요!" CodeDeploy를 제대로 이해하면 안전하고 효율적인 배포 프로세스를 구축할 수 있습니다.

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

실전 팁

💡 - IAM 역할에 AWSCodeDeployRole 정책을 반드시 연결하세요

  • 배포 실패 시 CloudWatch Logs를 확인하면 원인을 빠르게 파악할 수 있습니다
  • 처음에는 개발 환경에서 충분히 테스트한 후 프로덕션에 적용하세요

2. ECS 배포 유형

CodeDeploy를 도입하기로 결정한 김개발 씨는 ECS에서 사용할 배포 유형을 고민하게 됩니다. 선배가 물어봅니다.

"컨테이너 환경이니까 어떤 배포 방식이 좋을까요?"

ECS 배포 유형은 컨테이너 기반 서비스를 어떻게 업데이트할지 결정하는 전략입니다. 마치 건물을 리모델링할 때 전체를 한 번에 할지, 층별로 순차적으로 할지 선택하는 것과 같습니다.

블루/그린 배포와 롤링 배포가 대표적이며, 각각 장단점이 명확합니다.

다음 코드를 살펴봅시다.

// ECS 서비스 정의 - 블루/그린 배포 설정
{
  "deploymentController": {
    "type": "CODE_DEPLOY"  // CodeDeploy를 사용한 블루/그린 배포
  },
  "serviceName": "my-ecs-service",
  "taskDefinition": "my-task:1",
  "desiredCount": 3,
  "loadBalancers": [{
    "targetGroupArn": "arn:aws:elasticloadbalancing:...",
    "containerName": "web",
    "containerPort": 80
  }]
}

김개발 씨의 팀은 ECS에서 마이크로서비스를 운영하고 있습니다. 컨테이너 3개가 로드밸런서 뒤에서 트래픽을 분산 처리하고 있죠.

이제 새로운 기능을 배포해야 하는데, 어떤 방식으로 배포할지 결정해야 합니다. 박시니어 씨가 화이트보드에 두 가지 그림을 그리며 설명합니다.

"ECS에서는 크게 두 가지 배포 방식이 있어요. 블루/그린과 롤링입니다." ECS 배포 유형이란 무엇일까요?

쉽게 비유하자면, 건물 리모델링과 같습니다. 한 번에 전체를 새 건물로 교체하는 방법이 있고, 층별로 순차적으로 공사하는 방법이 있습니다.

전자는 빠르지만 비용이 많이 들고, 후자는 시간이 걸리지만 기존 공간을 계속 사용할 수 있죠. 배포도 마찬가지입니다.

롤링 배포를 먼저 사용하던 시절에는 어떤 문제가 있었을까요? 롤링 배포는 기존 컨테이너를 하나씩 교체합니다.

컨테이너 1을 내리고 새 버전을 올리고, 다음 컨테이너로 넘어갑니다. 리소스를 절약할 수 있지만, 배포 중에는 구버전과 신버전이 섞여서 동작합니다.

만약 API 스펙이 변경되었다면 문제가 발생할 수 있습니다. 반면 블루/그린 배포는 완전히 새로운 환경을 준비합니다.

블루/그린 배포에서는 기존 환경(블루)을 유지하면서 새 환경(그린)을 구축합니다. 새 환경이 완전히 준비되고 헬스체크를 통과하면, 트래픽을 한 번에 전환합니다.

문제가 생기면 즉시 블루로 되돌릴 수 있습니다. 안전성은 높지만, 리소스가 두 배로 필요합니다.

위의 ECS 서비스 정의를 살펴보겠습니다. 먼저 deploymentController의 type을 CODE_DEPLOY로 설정했습니다.

이것이 블루/그린 배포를 활성화하는 핵심입니다. desiredCount는 3으로 설정되어 있어서, 새 버전도 컨테이너 3개가 준비됩니다.

loadBalancers 섹션에서 타겟 그룹을 지정하는데, 배포 시 새로운 타겟 그룹이 생성되고 트래픽이 전환됩니다. 실제 현업에서는 어떻게 선택할까요?

금융권 서비스처럼 안정성이 최우선인 경우 블루/그린 배포를 선택합니다. 배포 중 문제가 생겨도 즉시 롤백할 수 있고, 구버전과 신버전이 섞이지 않습니다.

반면 스타트업처럼 빠른 배포가 중요하고 리소스가 제한적인 경우 롤링 배포를 선택합니다. Netflix는 블루/그린 배포를 적극 활용합니다.

수천 개의 마이크로서비스를 운영하면서도 안정성을 유지하는 비결이죠. 반면 많은 스타트업은 초기에는 롤링 배포로 시작해서, 서비스가 성장하면 블루/그린으로 전환합니다.

주의할 점도 있습니다. 블루/그린 배포를 사용할 때 데이터베이스 마이그레이션은 신중하게 처리해야 합니다.

블루와 그린이 동시에 같은 데이터베이스를 바라보기 때문에, 스키마 변경이 양쪽 모두 호환되어야 합니다. 따라서 하위 호환성을 유지하는 방향으로 마이그레이션을 설계해야 합니다.

김개발 씨는 박시니어 씨의 설명을 듣고 이해했습니다. "우리 서비스는 안정성이 중요하니까 블루/그린이 맞겠네요!" 배포 유형을 제대로 선택하면 서비스 특성에 맞는 최적의 배포 전략을 구축할 수 있습니다.

여러분의 서비스는 어떤 방식이 적합한지 고민해 보세요.

실전 팁

💡 - 블루/그린은 안정성 우선, 롤링은 리소스 효율 우선

  • 데이터베이스 마이그레이션은 항상 하위 호환성을 고려하세요
  • 처음에는 롤링으로 시작해서 필요에 따라 블루/그린으로 전환하는 것도 좋은 전략입니다

3. 블루/그린 배포

김개발 씨는 블루/그린 배포를 직접 구현해보기로 했습니다. 설정 파일을 작성하던 중 궁금증이 생깁니다.

"트래픽 전환은 어떻게 제어하나요?"

블루/그린 배포는 기존 환경과 새 환경을 동시에 준비한 후, 트래픽을 한 번에 전환하는 배포 전략입니다. 마치 무대 뒤에서 새 세트를 준비한 후 막을 올리듯이, 안전하게 검증한 후 전환합니다.

즉시 롤백이 가능하여 위험을 최소화합니다.

다음 코드를 살펴봅시다.

{
  "version": 0.0,
  "Resources": [{
    "TargetService": {
      "Type": "AWS::ECS::Service",
      "Properties": {
        "TaskDefinition": "my-task-definition",
        "LoadBalancerInfo": {
          "ContainerName": "web",
          "ContainerPort": 80
        }
      }
    }
  }],
  "Hooks": [{
    "BeforeInstall": "LambdaFunctionToValidateBeforeInstall",
    "AfterInstall": "LambdaFunctionToValidateAfterInstall"
  }]
}

김개발 씨의 팀은 중요한 결제 API를 업데이트해야 합니다. 이 API는 하루에 수십만 건의 거래를 처리하기 때문에, 배포 중 문제가 생기면 큰 손실로 이어집니다.

박시니어 씨가 말합니다. "이럴 때 블루/그린 배포가 빛을 발하죠." 블루/그린 배포를 이해하려면 연극 무대를 떠올리면 됩니다.

공연 중간에 무대 세트를 바꿔야 한다고 생각해봅시다. 관객 앞에서 세트를 해체하고 새로 조립할 수는 없습니다.

대신 무대 뒤에서 새 세트를 완전히 준비한 후, 막을 내렸다가 새 세트로 바꿔서 다시 올립니다. 블루/그린 배포도 정확히 이런 방식입니다.

기존 방식의 문제점은 명확했습니다. 롤링 배포를 사용하면 배포 중에 구버전과 신버전이 섞여서 동작합니다.

만약 API 응답 형식이 바뀌었다면 어떻게 될까요? 클라이언트는 때로는 구버전 응답을, 때로는 신버전 응답을 받게 됩니다.

예측 불가능한 동작이 발생하죠. 또한 문제가 생겨도 일부 컨테이너는 이미 업데이트되어서 롤백이 복잡합니다.

블루/그린 배포는 이런 문제를 원천적으로 차단합니다. 먼저 기존 환경(블루)을 그대로 두고 새 환경(그린)을 구축합니다.

그린 환경에 새 컨테이너를 띄우고, 헬스체크를 수행합니다. 모든 컨테이너가 정상이면 로드밸런서의 타겟 그룹을 그린으로 전환합니다.

이 전환은 몇 초 안에 완료되며, 사용자는 거의 눈치채지 못합니다. 무엇보다 즉시 롤백이 가능합니다.

배포 후 모니터링하다가 에러율이 급증하면, 타겟 그룹을 다시 블루로 돌리면 됩니다. 클릭 한 번으로 이전 상태로 복구됩니다.

위의 appspec.json 파일을 분석해보겠습니다. Resources 섹션에서 TargetService를 정의합니다.

이것이 그린 환경으로 배포될 ECS 서비스입니다. LoadBalancerInfo는 어느 컨테이너의 어느 포트로 트래픽을 보낼지 지정합니다.

Hooks 섹션이 흥미로운데, 배포 전후로 Lambda 함수를 실행할 수 있습니다. 예를 들어 AfterInstall 훅에서 통합 테스트를 실행해서, 통과해야만 트래픽을 전환하도록 설정할 수 있습니다.

실제 현업에서는 어떻게 활용할까요? 핀테크 회사의 사례를 살펴봅시다.

이 회사는 하루에 100만 건 이상의 송금을 처리합니다. 블루/그린 배포를 도입한 후, 배포 중 장애가 제로에 가까워졌습니다.

새 버전을 그린 환경에 배포하고, 실제 프로덕션 트래픽의 10퍼센트를 보내서 검증합니다. 문제가 없으면 100퍼센트로 전환하고, 문제가 있으면 즉시 중단합니다.

또 다른 예로 게임 서버가 있습니다. 게임 업데이트는 모든 플레이어에게 동시에 적용되어야 합니다.

일부는 구버전, 일부는 신버전이면 매칭이나 아이템 거래에 문제가 생깁니다. 블루/그린 배포를 사용하면 점검 시간에 한 번에 전환할 수 있습니다.

하지만 주의할 점도 있습니다. 블루/그린 배포의 가장 큰 단점은 리소스 비용입니다.

배포 중에는 블루와 그린 환경이 모두 실행되기 때문에, 컴퓨팅 리소스가 두 배로 필요합니다. 따라서 Auto Scaling을 적절히 설정해서, 배포가 완료되면 블루 환경을 빠르게 종료해야 합니다.

또한 데이터베이스 마이그레이션은 신중하게 처리해야 합니다. 블루와 그린이 같은 데이터베이스를 공유하므로, 스키마 변경 시 양쪽 모두 정상 동작해야 합니다.

예를 들어 컬럼을 추가할 때는 nullable로 만들거나 기본값을 설정해서, 블루 환경도 계속 동작하도록 해야 합니다. 김개발 씨는 첫 블루/그린 배포를 성공적으로 마쳤습니다.

배포 중에도 서비스는 정상 동작했고, 새 기능이 안전하게 릴리스되었습니다. "이제 배포가 무섭지 않아요!" 블루/그린 배포를 제대로 활용하면 안정성과 신뢰성을 크게 향상시킬 수 있습니다.

특히 중요한 서비스일수록 블루/그린 배포의 가치가 빛납니다.

실전 팁

💡 - 배포 후 모니터링을 강화하여 문제를 빠르게 감지하세요

  • Auto Scaling으로 블루 환경을 자동 종료하여 비용을 절감하세요
  • 데이터베이스 마이그레이션은 항상 하위 호환성을 유지하세요

4. 롤링 배포

스타트업에 입사한 이개발 씨는 제한된 예산으로 배포 시스템을 구축해야 합니다. 선배가 조언합니다.

"우리 규모에서는 롤링 배포가 적합해요."

롤링 배포는 기존 인스턴스를 순차적으로 업데이트하는 배포 전략입니다. 마치 신호등이 차례대로 바뀌듯이, 서버를 하나씩 업데이트해서 리소스를 효율적으로 사용합니다.

비용은 절감되지만 배포 시간이 길어지고 즉시 롤백이 어렵습니다.

다음 코드를 살펴봅시다.

{
  "deploymentConfiguration": {
    "deploymentConfigName": "CodeDeployDefault.ECSRolling",
    "minimumHealthyPercent": 50,  // 최소 50%는 항상 healthy 유지
    "maximumPercent": 200  // 최대 200%까지 인스턴스 증가 허용
  },
  "updateConfig": {
    "maxBatchSize": 1,  // 한 번에 1개씩 업데이트
    "pauseTime": "PT5M"  // 각 배치 사이 5분 대기
  }
}

이개발 씨의 스타트업은 EC2 인스턴스 4대로 API 서버를 운영합니다. AWS 비용을 최소화해야 하는 상황에서, 블루/그린처럼 서버를 두 배로 늘릴 여유가 없습니다.

CTO가 말합니다. "롤링 배포로 하나씩 업데이트하면서 서비스를 유지합시다." 롤링 배포를 이해하려면 엘리베이터를 떠올리면 됩니다.

건물에 엘리베이터가 4대 있는데 정비를 해야 한다고 가정해봅시다. 4대를 모두 세울 수는 없습니다.

대신 1대씩 순차적으로 정비합니다. 1호기를 세우고 정비하는 동안 2, 3, 4호기가 운영됩니다.

1호기 정비가 끝나면 2호기를 세웁니다. 이렇게 하면 서비스 중단 없이 모든 엘리베이터를 업데이트할 수 있습니다.

롤링 배포가 필요한 이유는 명확합니다. 모든 서버를 한 번에 내리면 서비스가 중단됩니다.

그렇다고 블루/그린처럼 서버를 두 배로 늘리면 비용이 감당 안 됩니다. 특히 스타트업이나 중소기업은 예산 제약이 큽니다.

롤링 배포는 이 두 가지 문제를 동시에 해결합니다. 롤링 배포의 핵심은 배치 크기와 헬스체크입니다.

먼저 배치 크기를 결정합니다. 한 번에 몇 대를 업데이트할지 정하는 것이죠.

위의 설정에서는 maxBatchSize를 1로 설정했습니다. 4대 중 1대씩 순차적으로 업데이트하겠다는 의미입니다.

만약 2로 설정하면 2대씩 업데이트합니다. 배치 크기가 클수록 배포는 빨라지지만, 한 번에 많은 서버가 내려가므로 위험도 커집니다.

다음으로 minimumHealthyPercent를 확인합니다. 이것은 배포 중에도 최소한 유지해야 할 정상 인스턴스 비율입니다.

50으로 설정하면 항상 50퍼센트 이상은 정상 동작해야 합니다. 4대 중 2대는 항상 살아있어야 한다는 뜻이죠.

maximumPercent는 배포 중 최대 인스턴스 비율입니다. 200으로 설정하면 4대의 200퍼센트, 즉 8대까지 동시에 실행될 수 있습니다.

새 버전을 띄우고 헬스체크를 통과한 후에 구버전을 내리는 방식으로 무중단 배포를 구현합니다. pauseTime은 각 배치 사이의 대기 시간입니다.

PT5M은 5분을 의미합니다. 1대를 업데이트하고 5분 동안 모니터링합니다.

에러가 없으면 다음 서버로 넘어가고, 문제가 있으면 배포를 중단합니다. 실제 현업에서는 어떻게 활용할까요?

한 스타트업의 사례를 살펴봅시다. 이 회사는 초기에 EC2 인스턴스 6대로 서비스를 운영했습니다.

롤링 배포를 도입하면서 배치 크기를 2로 설정했습니다. 2대씩 업데이트하면서도 최소 4대는 항상 정상 동작하도록 설정했죠.

배포 시간은 15분 정도 걸렸지만, 추가 비용 없이 무중단 배포를 구현했습니다. 또 다른 예로 게임 서버가 있습니다.

피크 타임에는 서버 10대가 모두 필요하지만, 새벽에는 5대만 있어도 충분합니다. 새벽 시간대에 롤링 배포를 진행하면 트래픽 부담이 적어서 안전합니다.

하지만 주의할 점도 있습니다. 롤링 배포의 가장 큰 문제는 롤백이 복잡하다는 점입니다.

블루/그린처럼 클릭 한 번으로 되돌릴 수 없습니다. 일부 서버는 이미 신버전으로 업데이트되었기 때문에, 롤백도 롤링 방식으로 진행해야 합니다.

따라서 배포 전 충분한 테스트가 필수입니다. 또한 배포 중에는 구버전과 신버전이 섞여서 동작합니다.

API 호환성을 반드시 유지해야 합니다. 예를 들어 응답 JSON 형식을 변경한다면, 구버전 클라이언트도 신버전 응답을 처리할 수 있어야 합니다.

이개발 씨는 첫 롤링 배포를 성공적으로 마쳤습니다. 배포 시간은 20분 걸렸지만, 추가 비용 없이 무중단 배포를 구현했습니다.

"우리 규모에는 이게 딱이네요!" 롤링 배포를 제대로 활용하면 제한된 리소스로도 안정적인 배포를 구현할 수 있습니다. 특히 비용에 민감한 스타트업에게 적합한 전략입니다.

실전 팁

💡 - 배치 크기는 작게 시작해서 점진적으로 늘리세요

  • 새벽 등 트래픽이 적은 시간대에 배포하면 더 안전합니다
  • 배포 전 스테이징 환경에서 충분히 테스트하세요

5. appspec.yml 작성

김개발 씨는 CodeDeploy 설정을 완료했지만, appspec.yml 파일을 어떻게 작성해야 할지 막막합니다. 선배가 예제를 보여줍니다.

"이 파일이 배포의 모든 것을 정의해요."

appspec.yml은 CodeDeploy가 애플리케이션을 어떻게 배포할지 정의하는 설정 파일입니다. 마치 요리 레시피가 조리 순서를 알려주듯이, 배포 순서와 실행할 스크립트를 명시합니다.

라이프사이클 훅을 통해 각 단계마다 원하는 작업을 수행할 수 있습니다.

다음 코드를 살펴봅시다.

version: 0.0
os: linux
files:
  - source: /
    destination: /var/www/app
hooks:
  BeforeInstall:
    - location: scripts/before_install.sh
      timeout: 300  # 5분 타임아웃
  AfterInstall:
    - location: scripts/after_install.sh
      timeout: 300
  ApplicationStart:
    - location: scripts/start_server.sh
      timeout: 300
  ApplicationStop:
    - location: scripts/stop_server.sh
      timeout: 300

김개발 씨는 CodeDeploy 콘솔에서 배포를 시작했습니다. 그런데 에러가 발생했습니다.

"appspec.yml 파일을 찾을 수 없습니다." 박시니어 씨가 말합니다. "appspec.yml이 없으면 CodeDeploy는 무엇을 어떻게 배포할지 모르죠." appspec.yml을 이해하려면 요리 레시피를 떠올리면 됩니다.

요리책을 보면 재료 목록과 조리 순서가 나옵니다. 먼저 야채를 씻고, 썰고, 볶고, 양념을 넣고, 불을 조절하는 식이죠.

appspec.yml도 마찬가지입니다. 파일을 어디에 복사하고, 어떤 스크립트를 실행하고, 서버를 어떻게 재시작할지 단계별로 정의합니다.

appspec.yml이 없던 초기에는 어땠을까요? 개발자들은 배포 스크립트를 각자 만들었습니다.

누구는 Bash 스크립트를, 누구는 Python 스크립트를 사용했죠. 팀원이 바뀌면 배포 방법을 다시 배워야 했고, 실수로 단계를 빠뜨리면 배포가 실패했습니다.

표준화가 절실했습니다. appspec.yml은 배포 프로세스를 표준화합니다.

파일 구조를 살펴보겠습니다. 먼저 version은 appspec 스펙 버전입니다.

현재는 0.0만 지원됩니다. os는 운영체제를 지정합니다.

linux, windows 등을 선택할 수 있습니다. files 섹션이 중요합니다.

source는 소스 파일 위치이고, destination은 대상 서버의 배포 경로입니다. 위의 예제에서는 루트의 모든 파일을 /var/www/app으로 복사합니다.

특정 파일만 복사하거나, 여러 위치에 복사할 수도 있습니다. hooks 섹션이 appspec.yml의 핵심입니다.

hooks는 배포 라이프사이클의 각 단계에서 실행할 스크립트를 정의합니다. ApplicationStop, BeforeInstall, AfterInstall, ApplicationStart 순서로 실행됩니다.

ApplicationStop에서는 기존 서버를 중단합니다. stop_server.sh 스크립트가 nginx나 node 프로세스를 종료합니다.

BeforeInstall에서는 배포 전 준비 작업을 수행합니다. 예를 들어 오래된 파일을 삭제하거나, 디렉토리 권한을 설정합니다.

AfterInstall에서는 배포 후 작업을 수행합니다. npm install로 의존성을 설치하거나, 환경 변수 파일을 복사합니다.

ApplicationStart에서는 새 버전을 시작합니다. start_server.sh가 서버를 실행하고 헬스체크를 확인합니다.

timeout은 각 스크립트의 최대 실행 시간입니다. 300초, 즉 5분으로 설정했습니다.

타임아웃을 초과하면 배포가 실패합니다. 실제 현업에서는 어떻게 작성할까요?

Node.js 애플리케이션을 예로 들어봅시다. before_install.sh에서는 Node.js와 npm이 설치되어 있는지 확인합니다.

after_install.sh에서는 npm install을 실행하고, 프로덕션 빌드를 수행합니다. start_server.sh에서는 PM2로 서버를 시작하고, 헬스체크 엔드포인트를 호출해서 정상 동작을 확인합니다.

또 다른 예로 Python Django 애플리케이션이 있습니다. after_install.sh에서 pip install -r requirements.txt를 실행하고, python manage.py migrate로 데이터베이스 마이그레이션을 수행합니다.

python manage.py collectstatic으로 정적 파일을 모으고, gunicorn으로 서버를 시작합니다. 주의할 점도 있습니다.

스크립트는 반드시 실행 권한이 있어야 합니다. chmod +x scripts/*.sh로 권한을 부여하세요.

또한 스크립트가 실패하면 배포 전체가 실패하므로, 에러 처리를 철저히 해야 합니다. set -e로 에러 발생 시 즉시 중단하도록 설정하는 것이 좋습니다.

환경 변수는 별도로 관리하세요. appspec.yml에 직접 넣으면 보안 문제가 발생합니다.

AWS Systems Manager Parameter Store나 Secrets Manager를 활용해서 안전하게 관리하세요. 김개발 씨는 appspec.yml을 작성하고 배포를 다시 시작했습니다.

이번에는 성공입니다. 각 훅이 순서대로 실행되고, 새 버전이 정상적으로 배포되었습니다.

"이제 배포 과정이 명확하게 보이네요!" appspec.yml을 제대로 작성하면 일관되고 예측 가능한 배포를 구현할 수 있습니다. 한 번 잘 작성해두면 팀 전체가 동일한 방식으로 배포할 수 있습니다.

실전 팁

💡 - 스크립트에는 항상 실행 권한을 부여하세요

  • 에러 처리를 철저히 해서 배포 실패를 방지하세요
  • 환경 변수는 Parameter Store나 Secrets Manager로 관리하세요

6. 배포 롤백

김개발 씨의 배포가 성공했지만, 30분 후 에러율이 급증합니다. 모니터링 담당자가 알람을 받고 달려옵니다.

"즉시 롤백해야 합니다!"

배포 롤백은 문제가 발생한 배포를 이전 버전으로 되돌리는 작업입니다. 마치 게임에서 세이브 포인트로 돌아가듯이, 안정적이었던 이전 상태로 복구합니다.

자동 롤백과 수동 롤백을 지원하며, 빠른 복구가 서비스 안정성의 핵심입니다.

다음 코드를 살펴봅시다.

{
  "deploymentGroupName": "my-deployment-group",
  "autoRollbackConfiguration": {
    "enabled": true,
    "events": [
      "DEPLOYMENT_FAILURE",  // 배포 실패 시 자동 롤백
      "DEPLOYMENT_STOP_ON_ALARM"  // CloudWatch 알람 시 자동 롤백
    ]
  },
  "alarmConfiguration": {
    "enabled": true,
    "alarms": [
      {"name": "HighErrorRate"},  // 에러율 알람
      {"name": "HighLatency"}  // 레이턴시 알람
    ]
  }
}

김개발 씨는 새 기능을 배포한 후 뿌듯해했습니다. 하지만 30분 후 상황이 급변했습니다.

CloudWatch 대시보드에 빨간 알람이 가득합니다. API 에러율이 평소 0.1퍼센트에서 5퍼센트로 급증했습니다.

박시니어 씨가 달려와 외칩니다. "롤백하세요!" 배포 롤백을 이해하려면 게임의 세이브 포인트를 떠올리면 됩니다.

게임을 하다가 어려운 보스를 만나면 먼저 세이브를 합니다. 도전했다가 실패하면 세이브 포인트로 돌아가서 다시 시도합니다.

배포도 마찬가지입니다. 새 버전을 배포하기 전 상태를 기억해두었다가, 문제가 생기면 그 상태로 되돌립니다.

롤백 기능이 없던 시절에는 어땠을까요? 배포 후 문제가 발생하면 개발자들은 패닉 상태가 되었습니다.

빠르게 버그를 찾아서 핫픽스를 만들고, 다시 배포해야 했습니다. 이 과정에서 30분, 1시간이 걸리기도 했죠.

그동안 서비스는 계속 오류를 내보내고, 사용자들은 불만을 쏟아냈습니다. 자동 롤백은 이런 문제를 즉시 해결합니다.

위의 설정에서 autoRollbackConfiguration을 enabled: true로 설정했습니다. events 배열에는 어떤 상황에서 롤백할지 정의합니다.

DEPLOYMENT_FAILURE는 배포 자체가 실패한 경우입니다. 예를 들어 헬스체크를 통과하지 못하면 자동으로 롤백됩니다.

DEPLOYMENT_STOP_ON_ALARM은 CloudWatch 알람이 발생한 경우입니다. alarmConfiguration에서 모니터링할 알람을 지정합니다.

HighErrorRate 알람은 에러율이 임계값을 초과하면 발동합니다. HighLatency 알람은 응답 시간이 지나치게 느려지면 발동합니다.

롤백의 동작 방식을 살펴보겠습니다. 블루/그린 배포에서 롤백은 매우 간단합니다.

로드밸런서의 타겟 그룹을 그린에서 블루로 다시 전환하기만 하면 됩니다. 몇 초 안에 완료되며, 즉시 이전 버전으로 돌아갑니다.

그린 환경은 일정 시간 유지했다가 삭제합니다. 롤링 배포에서 롤백은 조금 복잡합니다.

이미 업데이트된 인스턴스들을 다시 이전 버전으로 교체해야 하기 때문입니다. CodeDeploy는 이전 배포의 아티팩트를 보관하고 있다가, 롤백 시 해당 아티팩트로 다시 롤링 배포를 수행합니다.

수동 롤백도 가능합니다. CodeDeploy 콘솔에서 이전 배포를 선택하고 "Redeploy" 버튼을 클릭하면 됩니다.

또는 AWS CLI로 aws deploy create-deployment 명령어에 이전 리비전 ID를 지정해서 롤백할 수 있습니다. 실제 현업에서는 어떻게 활용할까요?

한 이커머스 회사의 사례입니다. 블랙프라이데이 세일 당일 새 결제 기능을 배포했는데, 특정 카드사 결제가 실패하는 버그가 발견되었습니다.

자동 롤백이 설정되어 있어서, HighErrorRate 알람이 발동하고 3분 안에 자동으로 이전 버전으로 롤백되었습니다. 고객 영향을 최소화할 수 있었습니다.

또 다른 예로 소셜 미디어 서비스가 있습니다. 새 피드 알고리즘을 배포했는데, 데이터베이스 쿼리가 비효율적이어서 응답 속도가 느려졌습니다.

HighLatency 알람이 발동하고 즉시 롤백되었습니다. 엔지니어들은 여유롭게 문제를 분석하고 수정한 후 다시 배포했습니다.

주의할 점도 있습니다. 롤백했다고 해서 끝이 아닙니다.

근본 원인을 반드시 찾아서 수정해야 합니다. 롤백은 임시 조치일 뿐입니다.

포스트모템 회의를 열어서 무엇이 잘못되었는지 분석하고, 재발 방지책을 마련하세요. 데이터베이스 마이그레이션은 롤백이 어렵습니다.

스키마를 변경하거나 데이터를 마이그레이션한 경우, 코드만 롤백해서는 해결되지 않습니다. 따라서 데이터베이스 변경은 항상 하위 호환성을 유지하도록 설계하세요.

컬럼 추가는 nullable로, 컬럼 삭제는 여러 단계로 나눠서 진행하세요. 김개발 씨는 롤백 후 버그를 분석했습니다.

NULL 체크를 빠뜨린 것이 원인이었습니다. 수정하고 테스트를 추가한 후 다시 배포했고, 이번에는 성공했습니다.

"롤백 덕분에 빠르게 복구할 수 있었어요!" 배포 롤백을 제대로 구성하면 배포에 대한 두려움을 크게 줄일 수 있습니다. 실수는 누구나 하지만, 빠르게 복구하는 것이 중요합니다.

실전 팁

💡 - 자동 롤백을 반드시 활성화하고 CloudWatch 알람을 설정하세요

  • 롤백 후에는 포스트모템으로 근본 원인을 분석하세요
  • 데이터베이스 변경은 항상 하위 호환성을 고려하세요

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

#AWS#CodeDeploy#BlueGreen#RollingDeploy#AppSpec

댓글 (0)

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