$ yh.log
[DOP-C02] Domain 1 - SDLC Automation (Part 2)

[DOP-C02] Domain 1 - SDLC Automation (Part 2)

AWSDOP-C02DevOpsCI/CDCodeDeploy

작성자 : 오예환 | 작성일 : 2026-02-16 | 수정일 : 2026-02-16 | 조회수 :

CI/CD: CodeDeploy


5. AWS CodeDeploy

🤔 CodeDeploy가 뭔가요?

비유로 이해하기: CodeDeploy는 배포 자동화 로봇입니다.

  • EC2, Lambda, ECS에 자동 배포
  • 점진적 배포 (Canary, Linear)
  • 실패 시 자동 롤백

CodeDeploy 지원 플랫폼

플랫폼배포 방식Agent 필요
EC2/On-premisesIn-place, Blue/Green
LambdaBlue/Green (Alias)
ECSBlue/Green (Task Definition)

EC2 In-place 배포

┌─────────────────────────────────────────────────────────────────┐
                    In-place Deployment

  기존 인스턴스에서 애플리케이션 업데이트

  초기 상태:
  [v1] [v1] [v1] [v1]                                           │

  HalfAtATime (절반씩):                                          │
  [v2] [v2] [v1] [v1]  →  [v2] [v2] [v2] [v2]                   │

   업데이트                  완료

  배포 속도 옵션:
 AllAtOnce: 모두 동시 (다운타임 최대)                         │
 HalfAtATime: 절반씩 (50% 용량 유지)                         │
 OneAtATime: 하나씩 (가장 느림, 가장 안전)                   │
 Custom: 사용자 정의 %

└─────────────────────────────────────────────────────────────────┘

EC2 Blue/Green 배포

┌─────────────────────────────────────────────────────────────────┐
                    Blue/Green Deployment

 인스턴스 그룹(Green) 생성 트래픽 전환

  Step 1: 초기 상태
  ┌─────────────────────────────────────────────────────────┐
       ALB

 100%
  ┌───────────┐
 ASG Blue  [v1] [v1] [v1]                         │   │
  └───────────┘
  └─────────────────────────────────────────────────────────┘

  Step 2: Green 그룹 생성 + 배포
  ┌─────────────────────────────────────────────────────────┐
       ALB

 100%
  ┌───────────┐
 ASG Blue  [v1] [v1] [v1]                         │   │
  └───────────┘
  ┌───────────┐
 ASG Green  [v2] [v2] [v2] ← 새로 생성              │   │
  └───────────┘
  └─────────────────────────────────────────────────────────┘

  Step 3: 트래픽 전환
  ┌─────────────────────────────────────────────────────────┐
       ALB

 100%
  ┌───────────┐
 ASG Green  [v2] [v2] [v2]                         │   │
  └───────────┘
  ┌───────────┐
 ASG Blue  [v1] [v1] [v1] ← 삭제 또는 유지        │   │
  └───────────┘
  └─────────────────────────────────────────────────────────┘

  ⚠️ Blue/Green에는 Load Balancer 필수!

└─────────────────────────────────────────────────────────────────┘

Blue/Green 프로비저닝 모드

┌─────────────────────────────────────────────────────────────────┐
                    프로비저닝 모드

  1️⃣ 수동(Manual) 모드:
  ┌─────────────────────────────────────────────────────────┐
 Blue/Green 인스턴스를 태그로 식별
 v1, v2 인스턴스를 수동으로 미리 프로비저닝
 트래픽을 번에 또는 점진적으로 v2로 이동
  └─────────────────────────────────────────────────────────┘

  2️⃣ 자동(Automatic) 모드 - ASG 사용:
  ┌─────────────────────────────────────────────────────────┐
 기존 ASG를 참조하기만 하면
 CodeDeploy가 자동으로 ASG 생성
 동일한 설정, 동일한 용량 복사
 ASG에 인스턴스 추가되면 ALB가 v1→v2 리디렉션
  └─────────────────────────────────────────────────────────┘

  💡 자동 모드가 편리하고 권장됨!

└─────────────────────────────────────────────────────────────────┘

Blue 인스턴스 종료 옵션

┌─────────────────────────────────────────────────────────────────┐
                    인스턴스 종료 옵션

  배포 완료 Blue(v1) 인스턴스 처리 방법:

  1️⃣ 자동 종료 (대기 시간 설정):                                  │
  ┌─────────────────────────────────────────────────────────┐
 종료 대기 시간 설정 가능 (최대 2일)                  │   │
 대기 시간 동안 문제 발견 롤백 가능
 대기 시간 경과 Blue 인스턴스 자동 종료

  예: 1시간 설정 1시간 동안 모니터링 종료
  └─────────────────────────────────────────────────────────┘

  2️⃣ 인스턴스 유지 (Keep Alive):                                  │
  ┌─────────────────────────────────────────────────────────┐
 가장 안전하지만 가장 비용이 많이 드는 옵션
 인스턴스가 자동 종료되지 않음
 직접 수동으로 종료해야
  └─────────────────────────────────────────────────────────┘

└─────────────────────────────────────────────────────────────────┘

Blue/Green Hook 실행 순서

┌─────────────────────────────────────────────────────────────────┐
                    Blue/Green Hook 실행 순서

  💡 In-place와 Hook은 동일하지만 실행 순서와 위치가 다름!

  🟢 Green(v2) 인스턴스에서 실행:
  ┌─────────────────────────────────────────────────────────┐
  1. ApplicationStop
  2. BeforeInstall
  3. Install CodeDeploy 예약
  4. AfterInstall
  5. ApplicationStart
  6. ValidateService
  7. BeforeAllowTraffic
  8. AllowTraffic CodeDeploy 예약 (ELB  v2 트래픽)    │   │
  9. AfterAllowTraffic
  └─────────────────────────────────────────────────────────┘

  🔵 Blue(v1) 인스턴스에서 실행:
  ┌─────────────────────────────────────────────────────────┐
  1. BeforeBlockTraffic
  2. BlockTraffic CodeDeploy 예약 (ELB에서 v1 제거)    │   │
  3. AfterBlockTraffic

  ⚠️ 이후 인스턴스 종료되므로 나머지 Hook 실행 함!
  └─────────────────────────────────────────────────────────┘

  흐름:
  v2에 설치 v2로 트래픽 허용 v1에서 트래픽 차단 v1 종료│

└─────────────────────────────────────────────────────────────────┘

배포 구성 (Deployment Configuration)

구성설명가동 중단 시간
AllAtOnce한 번에 최대한 많은 인스턴스에 배포최대
HalfAtATime한 번에 절반의 인스턴스에 배포중간
OneAtATime한 번에 하나씩 배포최소
Custom사용자 정의 배포 비율 설정설정에 따름

SNS 알림

┌─────────────────────────────────────────────────────────────────┐
                    CodeDeploy SNS 알림

  CodeDeploy가 배포 이벤트를 SNS 주제로 전송 가능

  CodeDeploy ──event──→ SNS Topic ──→ Email/Lambda/etc.

  전송 가능한 이벤트:
  ┌─────────────────────────────────────────────────────────┐
 DeploymentSuccess: 배포 성공
 DeploymentFailure: 배포 실패
 InstanceFailure: 개별 인스턴스 배포 실패
 DeploymentStart: 배포 시작
 DeploymentStop: 배포 중단
  └─────────────────────────────────────────────────────────┘

  사용 예:
  인스턴스 1개 실패 InstanceFailure SNS 이메일 알림

└─────────────────────────────────────────────────────────────────┘

CodeDeploy Agent

EC2/On-premises에서 필요:
 
 EC2 인스턴스에 설치되어야
 Systems Manager로 자동 설치/업데이트 가능
 S3에서 배포 번들 다운로드 권한 필요 (IAM)
 
EC2 Instance Profile:
{
  "Effect": "Allow",
  "Action": [
    "s3:Get*",
    "s3:List*"
  ],
  "Resource": [
    "arn:aws:s3:::bucket-name/*"
  ]
}

appspec.yml (EC2/On-premises)

# appspec.yml
 
version: 0.0
os: linux
 
files:
  - source: /
    destination: /var/www/html
 
hooks:
  BeforeInstall:
    - location: scripts/before_install.sh
      timeout: 300
      runas: root
 
  AfterInstall:
    - location: scripts/after_install.sh
      timeout: 300
      runas: root
 
  ApplicationStart:
    - location: scripts/start_server.sh
      timeout: 300
      runas: root
 
  ValidateService:
    - location: scripts/validate_service.sh
      timeout: 300
      runas: root

EC2 Deployment Hooks

┌─────────────────────────────────────────────────────────────────┐
                    Deployment Hooks 순서

  로드밸런서 사용 시:

  Start

  BeforeBlockTraffic 스크립트 실행 가능

  BlockTraffic (LB에서 트래픽 차단) ← CodeDeploy 예약            │

  AfterBlockTraffic 스크립트 실행 가능

  ApplicationStop 스크립트 실행 가능

  DownloadBundle CodeDeploy 예약

  BeforeInstall 스크립트 실행 가능 (파일 복호화, 백업)        │

  Install CodeDeploy 예약

  AfterInstall 스크립트 실행 가능 (설정, 권한 변경)           │

  ApplicationStart 스크립트 실행 가능 (서비스 시작)           │

  ValidateService 스크립트 실행 가능 (헬스체크)               │

  BeforeAllowTraffic 스크립트 실행 가능

  AllowTraffic (LB에서 트래픽 허용) ← CodeDeploy 예약           │

  AfterAllowTraffic 스크립트 실행 가능

  End

└─────────────────────────────────────────────────────────────────┘

Hook 실행 주체 구분

┌─────────────────────────────────────────────────────────────────┐
                    Hook 실행 주체

  🔷 CodeDeploy 예약 단계 (사용자 스크립트 실행 불가):           │
  ┌─────────────────────────────────────────────────────────┐
 BlockTraffic: LB에서 트래픽 차단
 DownloadBundle: S3에서 애플리케이션 번들 다운로드
 Install: 파일 복사 설치
 AllowTraffic: LB로부터 트래픽 허용
  └─────────────────────────────────────────────────────────┘

  🔶 사용자 스크립트 실행 가능 단계:
  ┌─────────────────────────────────────────────────────────┐
 BeforeBlockTraffic, AfterBlockTraffic
 ApplicationStop
 BeforeInstall, AfterInstall
 ApplicationStart
 ValidateService
 BeforeAllowTraffic, AfterAllowTraffic
  └─────────────────────────────────────────────────────────┘

  💡 로드 밸런서 사용 흐름:
  트래픽 차단 번들 다운로드/설치 트래픽 허용

└─────────────────────────────────────────────────────────────────┘

CodeDeploy Agent의 스크립트 실행 방식

┌─────────────────────────────────────────────────────────────────┐
                    스크립트 실행 흐름

  1. CodeDeploy Agent가 배포 번들 다운로드
     (appspec.yml + 스크립트 파일 포함)                          │

  2. appspec.yml의 hooks 섹션 읽기
     ┌─────────────────────────────────────────────────────┐
  hooks:
    AfterInstall:
      - location: scripts/RunResourceTests.sh
        timeout: 300
        runas: root
     └─────────────────────────────────────────────────────┘

  3. 해당 단계에서 지정된 스크립트 실행
     예: AfterInstall 단계 RunResourceTests.sh 실행

  4. 스크립트 결과에 따라 배포 성공/실패 결정

└─────────────────────────────────────────────────────────────────┘

CodeDeploy 환경 변수

┌─────────────────────────────────────────────────────────────────┐
                    스크립트에서 사용 가능한 환경 변수

  CodeDeploy Agent가 스크립트 실행 환경 변수 주입:

  변수명 설명
  ─────────────────────────────┼────────────────────────────────│
  DEPLOYMENT_ID 배포 ID
  DEPLOYMENT_GROUP_NAME 배포 그룹 이름
  DEPLOYMENT_GROUP_ID 배포 그룹 ID
  APPLICATION_NAME 애플리케이션 이름
  LIFECYCLE_EVENT 현재 실행 중인 후크 이름

  스크립트 예시:
  ┌─────────────────────────────────────────────────────────┐
  #!/bin/bash                                            │   │
  echo "배포 그룹: $DEPLOYMENT_GROUP_NAME"
  echo "배포 ID: $DEPLOYMENT_ID"

  if [ "$DEPLOYMENT_GROUP_NAME" == "Production" ]; then
    # 프로덕션 전용 작업                                 │   │
  fi
  └─────────────────────────────────────────────────────────┘

└─────────────────────────────────────────────────────────────────┘

Hook별 사용 목적

Hook주요 용도
BeforeInstall파일 복호화, 구 버전 백업 생성
AfterInstall애플리케이션 설정, 파일 권한 변경
ApplicationStartApplicationStop에서 중단된 서비스 재시작
ValidateService배포 성공 여부 확인 (헬스체크, 테스트)
BeforeAllowTrafficLB 트래픽 수신 전 최종 상태 확인 (헬스체크)

Lambda 배포

┌─────────────────────────────────────────────────────────────────┐
                    Lambda Deployment

  CodeDeploy가 Lambda Alias의 트래픽을 점진적으로 전환

  Lambda Function
  ├── Version 1 (현재)                                          │
  ├── Version 2 (새로운)                                         │
  └── Prod Alias Version 1 (100%) + Version 2 (0%)            │

  배포 진행:
  V1: 100% 90% 80% ... 0%
  V2:   0% 10% 20% ... 100%

  배포 옵션:
 LambdaCanary10Percent5Minutes
 10% 전환, 5분 대기, 문제 없으면 100%
 LambdaLinear10PercentEvery3Minutes
 3분마다 10%씩 증가
 LambdaAllAtOnce
 즉시 100% 전환

  ⚠️ CodeDeploy Agent 불필요!

└─────────────────────────────────────────────────────────────────┘

appspec.yml (Lambda)

# appspec.yml for Lambda
 
version: 0.0
 
Resources:
  - MyLambdaFunction:
      Type: AWS::Lambda::Function
      Properties:
        Name: "my-function"
        Alias: "prod"
        CurrentVersion: "1"
        TargetVersion: "2"
 
Hooks:
  - BeforeAllowTraffic: "CodeDeployHook_BeforeAllowTraffic"
  - AfterAllowTraffic: "CodeDeployHook_AfterAllowTraffic"

ECS 배포

┌─────────────────────────────────────────────────────────────────┐
                    ECS Deployment (Blue/Green)                  │

 Task Definition으로 Task Set 생성 트래픽 전환

           ALB

     ┌──────┴──────┐

  Target Group  Target Group
   (Blue)        (Green)                                        │


  [v1][v1]      [v2][v2]                                        │

  100% - X%       X% X가 점진적으로 100%까지

  배포 옵션:
 ECSCanary10Percent5Minutes
 ECSLinear10PercentEvery3Minutes
 ECSAllAtOnce

  ⚠️ ALB 필수!
  ⚠️ CodeDeploy Agent 불필요!
  ⚠️ Task Definition + Container Image 미리 생성 필요

└─────────────────────────────────────────────────────────────────┘

Rollback

롤백 조건:
 배포 실패 자동 롤백
 CloudWatch Alarm 임계값 초과 자동 롤백
 수동 롤백
 
롤백 동작:
 이전 버전을 "새 배포"로 다시 배포
 이전 버전으로 "복원"하는 아님!

CodeDeploy 트러블슈팅

┌─────────────────────────────────────────────────────────────────┐
                    CodeDeploy 트러블슈팅

  1. InvalidSignatureException
     원인: EC2 시간이 맞지 않음
     해결: NTP로 시간 동기화

  2. "Too few healthy instances"
     원인:
 CodeDeploy Agent 미설치/미실행
 IAM 권한 부족
 HTTP Proxy 설정 필요
 시간 동기화 문제

  3. ASG 스케일아웃 배포
     문제: 인스턴스에 이전 버전 배포됨
     해결: CodeDeploy가 자동으로 follow-on 배포 실행

  4. AllowTraffic 실패 (에러 로그 없음)                          │
     원인: ELB 헬스체크 설정 오류
     해결: 헬스체크 경로/포트 확인

└─────────────────────────────────────────────────────────────────┘