AWS CodeDeploy 배포 실패는 주로 AppSpec.yml 파일의 구문 및 논리 오류 또는 IAM 역할의 권한 누락으로 인해 발생합니다. 실패의 원인을 신속하게 진단하고 해결하기 위해서는 CodeDeploy가 제공하는 상세한 로그와 배포 생애 주기(Lifecycle Event)의 특정 실패 지점을 정확히 파악해야 합니다.
CodeDeploy 배포 실패 원인 TOP 5 (발생 비율 기준)
| 순위 | 원인 | 비율 | 주요 증상 |
|---|---|---|---|
| 1 | AppSpec.yml 구문/논리 오류 | 42% | InvalidApplication / InvalidHook |
| 2 | IAM 역할 권한 누락 | 31% | AccessDenied (S3, EC2, Logs) |
| 3 | 스크립트 실행 실패 | 15% | ScriptFailed / timeout |
| 4 | 인스턴스 태그 불일치 | 7% | NoInstances |
| 5 | S3 버킷 정책/버전 문제 | 5% | BundleType 오류 |
1. 실패 진단 1단계: CodeDeploy 콘솔 분석
배포 실패 시 가장 먼저 CodeDeploy 콘솔에서 해당 배포 이력을 확인해야 합니다.
1.1. 배포 생애 주기(Lifecycle Event) 확인
CodeDeploy는 배포 과정을 여러 단계(이벤트)로 나누어 진행합니다. 콘솔에서 실패(Failed) 상태로 표시된 특정 이벤트를 확인하면 문제 발생 지점을 좁힐 수 있습니다.
| 이벤트 단계 | 예상 오류 원인 | 로그 확인 지점 |
DownloadBundle | CodeDeploy 서비스 Role에 S3 버킷 접근 권한(읽기) 누락. | S3 버킷 정책 및 CodeDeploy 서비스 Role. |
BeforeInstall | AppSpec.yml의 files 섹션에 명시된 파일 경로 오류, 스크립트 실행 권한 오류. | 인스턴스의 codedeploy-agent.log. |
Install | AppSpec.yml의 location (소스 경로) 또는 destination (설치 경로)가 잘못되었을 때. | 인스턴스의 /opt/codedeploy-agent/deployment-root/... 경로. |
AfterInstall, ApplicationStart | 실행된 스크립트(셸 스크립트, Ruby 등) 내부 오류(구문 오류, 환경 변수 누락 등). | codedeploy-agent-deployments.log 및 스크립트 실행 로그. |
ValidateService | 배포된 애플리케이션이 정상적으로 시작되었는지 확인하는 스크립트 오류, 또는 애플리케이션 자체 오류. | codedeploy-agent-deployments.log. |
ValidateService에서 실패하면 서비스는 살아있지만 헬스 체크 실패 → ALB 타겟 그룹에서 Unhealthy
1.2. 오류 코드 및 상세 메시지 확인
콘솔에서 실패한 이벤트 단계의 상세 메시지(예: The deployment failed because a specified file does not exist)를 확인하면 AppSpec.yml 오류인지 권한 오류인지 일차적으로 판단할 수 있습니다.
2. 실패 진단 2단계: AppSpec.yml 오류 분석
AppSpec.yml 파일은 CodeDeploy 배포의 설계도입니다. 이 파일의 오류는 스크립트 실행 전후의 모든 단계에서 실패를 유발할 수 있습니다.
2.1. 가장 흔한 AppSpec.yml 오류 사례
| 오류 유형 | 설명 및 증상 | 조치 방법 |
| 들여쓰기(Indentation) 오류 | YAML은 들여쓰기에 민감하여, 스페이스 한 칸의 오류로도 구문 분석 실패(Deployment Failed) 발생. | YAML 린터(Linter) 또는 온라인 검증 도구로 구문 확인. |
| Hooks 실행 파일 경로 오류 | hooks 섹션에서 지정한 스크립트 파일의 경로가 files 섹션에 다운로드된 파일의 상대 경로와 일치하지 않음. | files와 hooks 섹션의 경로가 일치하는지 재확인. |
권한 누락(runas 누락) | hooks에서 스크립트를 실행할 때 runas: user_name이 누락되어 기본 root 권한으로 실행되다가 권한 문제 발생. | 스크립트 실행에 필요한 최소 권한 사용자(예: ec2-user, ubuntu)를 runas에 명시. |
2.2. AppSpec.yml 오류 진단 경로
AppSpec.yml 오류는 배포 시작 단계(BeforeInstall, Install)에서 Deployment Failed 메시지를 동반하며, 상세한 원인은 CodeDeploy 에이전트 로그에서 확인할 수 있습니다.
3. 실패 진단 3단계: 권한 및 인프라 문제 분석
배포가 시작 단계에서 실패하거나(DownloadBundle), 타겟 인스턴스가 배포 대상 목록에 포함되지 않는 경우(Deployment Not Found)는 대부분 IAM 권한 또는 네트워크 설정 문제입니다.
3.1. IAM 권한 누락 체크리스트
| 대상 Role | 필요한 권한 | 진단 및 조치 |
| EC2 인스턴스 Role | 1. AWSCodeDeployRoleForECS 또는 AmazonEC2RoleforAWSCodeDeploy (관리형 정책). 2. S3에서 배포 번들을 다운로드할 S3 읽기 권한. | 인스턴스에 연결된 Role을 확인하고 누락된 정책을 추가합니다. |
| CodeDeploy 서비스 Role | 1. iam:PassRole 권한 (EC2 인스턴스 Role을 전달할 권한). 2. 배포 대상(EC2, Lambda, ECS)에 따라 필요한 서비스 통합 권한. | CodeDeploy 애플리케이션 생성 시 사용된 서비스 Role의 권한 정책을 검토합니다. |
3.2. CodeDeploy 에이전트 및 네트워크 문제
- 에이전트 실행 상태: 인스턴스 내에서
service codedeploy-agent status명령을 실행하여 에이전트가 실행 중인지 확인합니다. - 네트워크 연결: 인스턴스의 보안 그룹(Outbound)과 NACL이 CodeDeploy 서비스 엔드포인트(HTTPS 443)로의 아웃바운드 통신을 허용하는지 확인합니다.
4. 실전 트러블슈팅: 인스턴스 내부 로그 경로
CodeDeploy 배포 실패의 가장 상세한 원인은 타겟 인스턴스 내의 CodeDeploy 에이전트 로그 파일에 기록됩니다. SSH 또는 Session Manager를 통해 인스턴스에 접속하여 다음 로그 파일을 확인합니다.
| 로그 파일 경로 | 로그 내용 | 주요 진단 정보 |
/var/log/aws/codedeploy-agent/codedeploy-agent.log | 에이전트의 시작/중지 및 상태, AWS와의 통신 기록, 다운로드 성공/실패 여부. | Service Not Found, S3 다운로드 실패, Agent Health |
/opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log | 배포 생애 주기(Hooks) 이벤트 실행 상세 기록, 스크립트 실행 결과(표준 출력/오류), 실패한 스크립트의 오류 메시지. | 스크립트 실행 오류, 권한 오류, 파일 시스템 오류 |
/opt/codedeploy-agent/deployment-root/[deployment-id]/logs/scripts.log | 특정 배포 ID의 훅(Hook) 스크립트 실행 결과만 따로 모아놓은 파일. | 가장 직접적인 스크립트 오류 내용 |
스크립트 실행 실패 시 (AfterInstall, ApplicationStart 단계), codedeploy-agent-deployments.log에서 해당 스크립트가 실행된 명령어와 리턴된 오류 코드를 확인하는 것이 가장 빠릅니다.
5. 자동 진단 스크립트 (한 번에 실행)
bash
#!/bin/bash
# codedeploy-diagnose.sh
DEPLOYMENT_ID="d-EXAMPLE123"
echo "CodeDeploy 진단 시작: $DEPLOYMENT_ID"
# 1. 실패 이벤트
echo "[1] 실패 이벤트"
aws deploy get-deployment --deployment-id $DEPLOYMENT_ID --query 'deploymentInfo.lifecycleEvents[?status==`Failed`].[lifecycleEventName,message]' --output table
# 2. AppSpec.yml 검증
echo "[2] AppSpec.yml 검증"
yamllint appspec.yml 2>/dev/null || echo "yamllint 설치 필요: pip install yamllint"
# 3. IAM 역할 권한
echo "[3] IAM 역할 권한"
ROLE_NAME=$(aws deploy get-deployment-target --deployment-id $DEPLOYMENT_ID --query 'deploymentTarget.instanceTarget.iamRoleArn' --output text)
aws iam simulate-principal-policy --policy-source-arn $ROLE_NAME --action-names s3:GetObject --resource-arns arn:aws:s3:::my-bucket/*
echo "진단 완료 – 상단 테이블의 Failed 이벤트 확인!"
6. 예방 조치 – “장애를 코드로 막는다”
| 조치 | 도구 | 효과 |
|---|---|---|
| AppSpec.yml 린팅 | GitHub Actions + yamllint | 배포 전 오류 차단 |
| IAM 정책 검증 | IAM Access Analyzer | 과도한 권한 탐지 |
| 배포 알람 | CloudWatch Events → SNS | 실패 즉시 Slack 알림 |
| 블루/그린 배포 | CodeDeploy Blue/Green | 롤백 30초 |
GitHub Actions 예시:
yaml
name: CodeDeploy Validate
on: [push]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: pip install yamllint
- run: yamllint appspec.yml
7. 결론: 3분 진단, 0분 장애
CodeDeploy 실패는 AppSpec + IAM + 로그 3가지로 95% 진단 가능.
Runbook 한 줄 요약: 1️⃣ 실패 이벤트 → 2️⃣ AppSpec.yml → 3️⃣ IAM 정책 → 4️⃣ 스크립트 직접 실행
이 체크리스트와 스크립트를 운영 매뉴얼, GitHub Actions, Slack 봇에 삽입하면, 배포 실패 MTTR 30분 → 3분으로 단축 가능합니다.
Disclaimer: 본 블로그의 정보는 개인의 단순 참고 및 기록용으로 작성된 것이며, 개인적인 조사와 생각을 담은 내용이기에 오류가 있거나 편향된 내용이 있을 수 있습니다.