콘텐츠로 이동

CI/CD Basics

분류: Layer 5 - 플랫폼 엔지니어링 & 자동화 | 선수지식: Docker Basics

CI/CD는 코드 변경을 자동으로 빌드·테스트(CI)하고, 검증된 코드를 자동으로 서버에 배포(CD)하는 파이프라인이다.

BackOps에서 배포는 일상 업무다. “코드를 머지하면 서버에 반영되기까지 무슨 일이 일어나는지”를 모르면 배포 실패를 진단할 수 없고, 파이프라인 개선도 불가능하다. 플랫폼 엔지니어링의 핵심 축(개발자 경험/DX 개선) 중 배포 자동화가 가장 체감이 큰 영역이다.

CI (Continuous Integration)

코드를 공유 브랜치에 자주 머지하고, 머지할 때마다 자동으로 빌드·테스트를 실행하는 것.

  • PR을 올리면 자동으로 린트, 테스트, 빌드가 돌아감
  • 깨진 코드가 메인 브랜치에 들어가는 것을 방지

CD (Continuous Delivery / Deployment)

  • Continuous Delivery: 배포 가능한 상태까지 자동화. 실제 배포는 수동 승인.
  • Continuous Deployment: 배포까지 완전 자동화. 테스트 통과하면 바로 프로덕션.

파이프라인 기본 흐름

코드 Push/PR → 빌드 → 테스트 → Docker 이미지 생성 → 레지스트리 Push → 배포
CI 영역 CD 영역

CI/CD 파이프라인 일반 원칙 — 도구 독립적 사고 모델

GitHub Actions, GitLab CI, Jenkins, CircleCI 등 도구가 달라도 모든 CI/CD는 세 가지 불변 원칙을 공유한다:

  1. 격리된 환경에서 재현 가능한 빌드: 파이프라인은 매 실행마다 클린 상태에서 시작한다. “내 로컬에서는 됐는데”를 제거하는 것이 핵심 목적. Docker 컨테이너가 이 격리를 보장하는 표준 수단이다.
  2. 불변 아티팩트 원칙: 빌드 단계에서 생성된 이미지/바이너리는 이후 테스트·스테이징·프로덕션에서 동일한 아티팩트를 사용한다. 환경마다 다시 빌드하면 재현성이 깨진다. (예: my-app:$GITHUB_SHA 태그로 단 하나의 이미지가 모든 환경을 통과)
  3. 파이프라인 as Code: CI 설정 파일(.yml)을 앱 코드와 동일한 git 저장소에 보관한다. 파이프라인 변경도 PR 리뷰 대상이 되고, 롤백이 가능해진다.
# 도구별 동일 원칙 적용 비교
GitHub Actions: runs-on: ubuntu-latest → 매 실행 클린 VM
GitLab CI: image: node:20 → 매 Job 클린 컨테이너
Jenkins: docker.image('node:20').inside { ... } → 동일

GitHub Actions 내부 동작 원리

.github/workflows/deploy.yml 파일 하나를 올리면 알아서 돌아간다”는 사실 뒤에 이런 흐름이 있다:

  1. Event 감지: GitHub이 push, pull_request 등 이벤트를 감지
  2. Runner 할당: GitHub이 관리하는 Ubuntu VM(Runner)을 하나 할당
  3. Workflow 실행: YAML에 정의된 Jobs → Steps 순서대로 실행
  4. 결과 리포트: 성공/실패를 PR 체크 상태로 표시

Runner는 매 실행마다 새로 초기화되는 격리된 VM이다. 이전 실행의 파일/환경이 남아 있지 않아서 actions/checkout, npm ci 같은 준비 단계가 항상 필요하다.

Runner는 매 실행마다 새로 초기화되므로 이전 실행 결과가 남지 않는다. GitHub은 지속적으로 Runner 성능을 개선 중이며, 캐시를 잘 활용하면 빌드 시간을 크게 단축할 수 있다.

📖 더 보기: GitHub Actions CI/CD in 4 steps — GitHub 공식 블로그의 파이프라인 구축 가이드 (입문)

GitHub Actions — NestJS 배포 실제 예시

.github/workflows/deploy.yml
name: Deploy NestJS to ECS
on:
push:
branches: [main]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: Install & Test
run: |
npm ci
npm test
- name: Build Docker image & Push to ECR
run: |
aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_REGISTRY
docker build -t $ECR_REGISTRY/my-app:$GITHUB_SHA .
docker push $ECR_REGISTRY/my-app:$GITHUB_SHA
env:
ECR_REGISTRY: ${{ secrets.ECR_REGISTRY }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Deploy to ECS
run: |
aws ecs update-service \
--cluster prod \
--service my-app \
--force-new-deployment
# GitHub Actions 탭에서 보이는 실행 결과 예시
✅ Setup Node.js 3s
✅ Install & Test 45s
✅ Build Docker image 1m 20s
✅ Push to ECR 30s
✅ Deploy to ECS 5s
총 소요 시간: 2m 43s

OIDC 인증 — AWS 자격증명 없이 배포하는 방법

비유하자면, OIDC는 “GitHub Actions가 AWS에게 ‘나 GitHub이야, 이 Repository에서 실행된 워크플로야’라고 신분증을 보여주면, AWS가 임시 통행증을 발급해주는 것”이다. 영구적인 AWS_ACCESS_KEY를 저장하지 않아도 된다.

장기 자격증명(Access Key/Secret Key)을 GitHub Secrets에 저장하면 키 유출 시 무기한으로 악용될 수 있다. OIDC를 사용하면 워크플로 실행마다 수명이 매우 짧은 임시 자격증명이 발급되어, 만료 후에는 자동으로 무효화된다.

# OIDC 기반 AWS 인증 (Access Key 없이 배포)
name: Deploy with OIDC
on:
push:
branches: [main]
permissions:
id-token: write # OIDC 토큰 발급 권한
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS Credentials via OIDC
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/GitHubActionsRole
aws-region: ap-northeast-2
- name: Push to ECR & Deploy to ECS
run: |
aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_REGISTRY
docker build -t $ECR_REGISTRY/my-app:$GITHUB_SHA .
docker push $ECR_REGISTRY/my-app:$GITHUB_SHA
aws ecs update-service --cluster prod --service my-app --force-new-deployment
# OIDC vs 정적 키 비교
정적 AWS 키: GitHub Secrets에 저장 → 유출 시 무기한 악용 가능
OIDC 임시 키: 워크플로 실행 시 발급 → 실행 완료 후 자동 만료

IAM 신뢰 정책에 특정 Repository와 브랜치만 역할 가정이 가능하도록 제한하면 보안이 더욱 강화된다.

OIDC 임시 자격증명 — 클라우드 공통 패턴

GitHub→AWS OIDC는 특정 도구 조합이 아니라 OIDC Workload Identity Federation이라는 범용 패턴의 구현이다. 세 클라우드 모두 동일한 교환 흐름을 따른다:

[CI 러너] → GitHub OIDC 토큰 발급 (https://token.actions.githubusercontent.com)
→ 클라우드 STS에 제시
→ 클라우드가 신뢰 정책 검증 후 단기 자격증명 발급 (보통 1시간 TTL)
클라우드메커니즘GitHub Actions 설정
AWSIAM OIDC Identity Provider + 역할 신뢰 정책aws-actions/configure-aws-credentials
GCPWorkload Identity Pool + Provider 구성google-github-actions/auth
AzureEntra ID Federated Credentials (서비스 주체)azure/login with client-id + federated-credential

공통 보안 원칙: 세 클라우드 모두 subject 클레임(예: repo:org/repo:ref:refs/heads/main)으로 특정 저장소·브랜치만 신뢰하도록 제한할 수 있다. 장기 자격증명 없이 CI/CD를 구성하는 것이 2024년 이후 모범 사례다.

파이프라인 속도 최적화 — npm 캐시와 Docker 레이어 캐시

CI 파이프라인이 느리면 개발자 경험이 나빠진다. 두 가지 캐시가 핵심이다:

  1. npm 캐시: package-lock.json이 변경되지 않으면 node_modules를 재설치하지 않음
  2. Docker 레이어 캐시: package.json이 변경되지 않으면 npm install 레이어를 재실행하지 않음
# npm 캐시 활용 (actions/setup-node에 내장)
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm" # package-lock.json 기반 캐시 키 자동 생성
# Docker 레이어 캐시 활용 (GitHub Actions Cache)
- name: Build with cache
uses: docker/build-push-action@v5
with:
cache-from: type=gha # GitHub Actions 캐시에서 이전 레이어 로드
cache-to: type=gha,mode=max
tags: $ECR_REGISTRY/my-app:$GITHUB_SHA
push: true
# 캐시 적용 전후 비교 (실제 NestJS 프로젝트 기준)
npm install (캐시 미적용): 1분 45초
npm install (캐시 적용): 8초 ← 93% 단축
Docker build (캐시 미적용): 2분 30초
Docker build (캐시 적용): 40초 ← 73% 단축

배포 전략

  • Rolling: 인스턴스를 하나씩 교체. 가장 기본.
  • Blue-Green: 새 버전을 별도 환경에 띄우고, 트래픽을 한 번에 전환. 롤백이 빠름.
  • Canary: 새 버전에 트래픽 일부만 먼저 보내서 검증 후 전체 전환.

배포 전략 선택 매트릭스

“어떤 전략을 쓸지”는 팀 규모·SLA·인프라 비용 세 축으로 판단한다. DORA 연구에 따르면 배포 전략이 Change Failure Rate와 MTTR(복구 시간) 양쪽에 직접 영향을 미친다.

기준RollingBlue-GreenCanary
허용 다운타임없음 (순차 교체)없음 (순간 전환)없음 (점진적 이동)
롤백 속도느림 (재배포 필요)빠름 < 1분 (트래픽 전환)중간 (가중치 복구)
인프라 비용낮음 (추가 자원 불필요)높음 (2배 환경 필요)중간 (일부 추가)
적합 팀 규모중 (210명)중~대 (10명+)대 (전담 옵저버빌리티)
SLA 요건99.9% 이하99.95%+99.99% 목표
적합 서비스내부 도구, 배치결제·인증 (즉시 롤백 필수)사용자 facing A/B

판단 기준: 롤백 1분 이내가 SLA 조건이면 Blue-Green이 강제된다. 인프라 예산이 제한적이면 Rolling이 기본. 새 기능의 비즈니스 임팩트를 실데이터로 검증해야 할 때 Canary가 유일한 선택이다.

배포 전략 심화 — ECS에서 각 전략이 어떻게 동작하는가

비유하자면, Rolling은 “버스를 달리는 중에 좌석을 하나씩 교체”하는 것이고, Blue-Green은 “새 버스를 준비해두고 신호등 바꾸듯 한 번에 전환”하는 것이며, Canary는 “탄광에 새 가스 탐지 카나리아를 먼저 보내보는 것”이다.

ECS Rolling 배포 동작:
- maximumPercent: 200, minimumHealthyPercent: 100 설정
- 현재 2개 태스크 실행 중 → 신버전 2개 추가 (총 4개)
- 신버전 헬스체크 통과 → 구버전 2개 종료
- 배포 중 구버전과 신버전이 동시에 트래픽 처리
Blue-Green (AWS CodeDeploy 통합):
- ECS 서비스에 CodeDeploy AppSpec 연동
- 신버전 태스크셋 생성 → 테스트 리스너(8080)로 검증
- 검증 후 프로덕션 리스너(443) 전환
- 구버전은 설정한 시간(예: 1시간) 후 자동 삭제
- 롤백: 구버전으로 트래픽 전환이 1분 이내 완료
Canary (ALB 가중치 기반):
- ALB Target Group 2개 (v1: 90%, v2: 10%)
- CloudWatch 지표 이상 감지 시 자동 롤백 트리거
- 단계적 증가: 10% → 25% → 50% → 100%
Terminal window
# ECS 배포 설정 확인 — 현재 전략이 뭔지 파악
aws ecs describe-services \
--cluster prod \
--services my-app \
--query 'services[0].deploymentConfiguration'
# 예상 출력 (Rolling 배포):
# {
# "maximumPercent": 200,
# "minimumHealthyPercent": 100,
# "deploymentCircuitBreaker": {
# "enable": true, ← 배포 실패 시 자동 롤백 활성화
# "rollback": true
# }
# }

Deployment Circuit Breaker — 배포 중 장애를 자동으로 롤백하는 방법

ECS의 Deployment Circuit Breaker를 활성화하면, 신버전 태스크가 연속으로 헬스체크에 실패할 때 ECS가 자동으로 이전 버전으로 롤백한다. 사람이 모니터링하지 않아도 배포 실패를 자동 감지하고 서비스를 보호한다.

Terminal window
# Terraform으로 Circuit Breaker 활성화
resource "aws_ecs_service" "my_app" {
name = "my-app"
cluster = aws_ecs_cluster.prod.id
task_definition = aws_ecs_task_definition.my_app.arn
deployment_circuit_breaker {
enable = true # 배포 실패 감지 활성화
rollback = true # 실패 시 이전 버전으로 자동 롤백
}
}

⚠️ 시크릿 관리 주의

CI/CD 파이프라인에서 AWS 자격증명, API Key 등은 절대 코드에 직접 넣지 않는다. GitHub Secrets, AWS Secrets Manager 등을 통해 환경변수로 주입해야 한다.

Action 버전도 주의가 필요하다. uses: actions/checkout@main처럼 브랜치를 지정하면 외부 의존성에 보안 위협이 생길 수 있다. 반드시 @v4처럼 특정 버전 태그 또는 커밋 SHA를 고정해서 사용해야 한다.

GitHub Environments — 스테이징/프로덕션 배포 분리

GitHub Environments를 사용하면 스테이징과 프로덕션 배포를 안전하게 분리할 수 있다. 환경별로 다른 Secrets, 보호 규칙(Required Reviewers), 배포 조건을 설정할 수 있다.

# .github/workflows/deploy.yml — 환경별 배포 분리
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment: staging # staging 환경 Secrets 사용
steps:
- name: Deploy to Staging ECS
run: |
aws ecs update-service --cluster staging --service my-app --force-new-deployment
env:
AWS_REGION: ${{ secrets.AWS_REGION }} # staging 환경 Secrets
ECR_REGISTRY: ${{ secrets.ECR_REGISTRY }}
deploy-production:
runs-on: ubuntu-latest
needs: deploy-staging # staging 완료 후 실행
environment: production # production 환경 Secrets + 수동 승인 규칙 적용
steps:
- name: Deploy to Production ECS
run: |
aws ecs update-service --cluster prod --service my-app --force-new-deployment
# GitHub 환경 보호 규칙 예시 (production 환경)
Required reviewers: 2명 승인 필요
Wait timer: 5분 대기 후 배포 진행
Deployment branch: main 브랜치만 허용

이미지 보안 취약점 스캔 — Trivy로 자동화

프로덕션에 취약한 패키지가 포함된 이미지가 배포되는 것을 방지하기 위해 CI 파이프라인에 이미지 스캔을 추가한다.

# CI 파이프라인에 Trivy 이미지 스캔 추가
- name: Build Docker image
run: docker build -t my-app:${{ github.sha }} .
- name: Scan image with Trivy
uses: aquasecurity/trivy-action@master
with:
image-ref: my-app:${{ github.sha }}
format: table
exit-code: "1" # CRITICAL 취약점 발견 시 파이프라인 실패
severity: "CRITICAL,HIGH" # CRITICAL, HIGH만 검사
# Trivy 스캔 결과 예시
┌───────────────┬────────────────┬──────────┬───────────────────┐
│ Library │ Vulnerability │ Severity │ Fixed Version │
├───────────────┼────────────────┼──────────┼───────────────────┤
│ node │ CVE-2023-XXXXX │ CRITICAL │ 20.11.1 │
│ express │ CVE-2024-XXXXX │ HIGH │ 4.19.2 │
└───────────────┴────────────────┴──────────┴───────────────────┘
CRITICAL 취약점 1건 발견 → 파이프라인 중단
  • PR 머지 시 자동 배포 (main 브랜치 → 프로덕션)
  • PR 생성 시 자동 테스트/린트 실행
  • Docker 이미지 빌드 → ECR Push → ECS 배포 자동화
  • 스테이징/프로덕션 환경 분리 배포
  • 배포 파이프라인이 실패했을 때 어느 단계에서 실패했는지 진단해야 함
  • 새 서비스 추가 시 CI/CD 파이프라인을 설정해야 함
  • 배포 속도 개선 (Docker 레이어 캐시, 병렬 테스트 등)
  • 팀의 배포 프로세스를 표준화하는 것이 플랫폼 엔지니어링의 시작
개념 A개념 B차이점
CICDCI는 빌드·테스트 자동화, CD는 배포 자동화
Continuous DeliveryContinuous DeploymentDelivery는 배포 전 수동 승인 필요, Deployment는 완전 자동
RollingBlue-GreenRolling은 점진적 교체, Blue-Green은 한 번에 전환 (롤백이 빠름)
GitHub ActionsJenkinsActions는 GitHub 네이티브(SaaS), Jenkins는 자체 호스팅(유연하지만 관리 필요)
정적 AWS 키OIDC 임시 자격증명정적 키는 유출 위험, OIDC는 워크플로 실행마다 임시 발급 (만료 후 자동 무효화)

🔧 워크플로가 실행 안 됨 — 트리거 조건 불일치

섹션 제목: “🔧 워크플로가 실행 안 됨 — 트리거 조건 불일치”

증상: 코드를 push했는데 GitHub Actions 탭에 아무것도 안 뜸

원인: on: 트리거 설정이 실제 동작과 불일치. 예: branches: [main]인데 master에 push했거나, 워크플로 파일이 .github/workflows/ 하위에 없음

해결:

# ❌ 잘못된 예: main 브랜치 push에만 반응
on:
push:
branches: [main]
# ✅ PR과 main push 모두 반응하도록 수정
on:
push:
branches: [main]
pull_request:
branches: [main]

파일 위치도 반드시 .github/workflows/deploy.yml 이어야 한다. workflows 폴더 밖에 있으면 무시된다.


🔧 “Error: npm ci” 실패 — package-lock.json 충돌

섹션 제목: “🔧 “Error: npm ci” 실패 — package-lock.json 충돌”

증상: CI에서 npm ci 실행 시 에러. 로컬에서는 잘 되는데 Actions에서만 실패

원인: package.jsonpackage-lock.json이 싱크가 맞지 않거나, package-lock.json.gitignore에 포함되어 커밋이 안 된 경우

해결:

Terminal window
# 로컬에서 lock 파일 재생성 후 커밋
rm package-lock.json
npm install
git add package-lock.json
git commit -m "chore: regenerate package-lock.json"

npm cipackage-lock.json을 기준으로 설치하므로 lock 파일이 반드시 커밋되어 있어야 한다.


🔧 Docker 이미지 빌드는 성공인데 ECS 배포 후 502

섹션 제목: “🔧 Docker 이미지 빌드는 성공인데 ECS 배포 후 502”

증상: GitHub Actions에서 모든 단계가 초록불인데, 배포 후 서비스에 502 응답

원인: 새 태스크 정의가 올바른 이미지 태그를 참조하지 않거나, ECS 서비스의 헬스체크가 새 컨테이너를 비정상으로 판단해서 롤백됨

해결:

  1. AWS ECS 콘솔 → 해당 서비스 → Events 탭에서 배포 이벤트 확인
  2. 태스크가 RUNNING 상태인지 확인 (→ STOPPED이면 컨테이너 자체 에러)
  3. 멈춘 태스크 클릭 → Stopped Reason 확인 (헬스체크 실패 or OOM 등)
  4. NestJS 앱에 /health 엔드포인트가 없으면 추가
// NestJS 헬스체크 엔드포인트 (ECS ALB 헬스체크 대응)
@Controller("health")
export class HealthController {
@Get()
check() {
return { status: "ok" };
}
}

🔧 GitHub Actions Secrets가 워크플로에서 빈 값으로 처리됨

섹션 제목: “🔧 GitHub Actions Secrets가 워크플로에서 빈 값으로 처리됨”

증상: 워크플로에서 ${{ secrets.AWS_ACCESS_KEY_ID }}를 사용했는데 빈 문자열로 처리되어 AWS 인증 실패

원인 3가지:

  1. Repository Secrets에 등록하지 않고 Environment Secrets에만 등록한 경우 (environment 지정 없이는 참조 불가)
  2. Fork된 PR에서 실행하는 경우 — 보안상 외부 기여자의 PR에는 Secrets가 노출되지 않음
  3. Secrets 이름에 오타 (대소문자 구분 있음)

해결:

# Secrets 디버깅 (값은 마스킹되지만 비어있는지 확인 가능)
- name: Check secrets
run: |
echo "AWS key is set: ${{ secrets.AWS_ACCESS_KEY_ID != '' }}"
# 예상 출력: AWS key is set: true (설정된 경우)
# 예상 출력: AWS key is set: false (미설정 또는 빈 값)
# Environment Secrets 사용 시 environment 명시 필요
jobs:
deploy:
runs-on: ubuntu-latest
environment: production # ← Environment Secrets 사용 시 반드시 명시

🔧 CI 파이프라인이 너무 느림 — 매 실행마다 5분 이상 소요

섹션 제목: “🔧 CI 파이프라인이 너무 느림 — 매 실행마다 5분 이상 소요”

증상: PR을 올릴 때마다 CI가 5~10분이 걸려 개발 속도가 느려짐. npm install이 매번 전체 재실행됨

원인: npm 캐시와 Docker 레이어 캐시가 설정되지 않아 매 실행마다 전체 의존성을 새로 설치하고 이미지를 처음부터 빌드함

해결:

# npm 캐시 활성화
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm" # ← 이 한 줄로 npm install 90% 단축
# Docker 레이어 캐시 활성화
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v5
with:
cache-from: type=gha
cache-to: type=gha,mode=max
push: true
tags: ${{ env.ECR_REGISTRY }}/my-app:${{ github.sha }}
# 예상 결과:
# 캐시 적용 전: 총 6분 30초
# 캐시 적용 후: 총 1분 15초 (80% 단축)
  • CI와 CD의 차이를 설명할 수 있다
  • 코드 Push부터 서버 배포까지의 파이프라인 흐름을 설명할 수 있다
  • Rolling, Blue-Green, Canary 배포 전략의 차이를 설명할 수 있다
  • GitHub Actions 워크플로 파일의 기본 구조를 읽을 수 있다
  • 배포 실패 시 어느 단계를 확인해야 하는지 안다
  • OIDC가 정적 AWS 키보다 왜 안전한지 설명할 수 있다

GitHub Actions, ArgoCD, GitOps, Docker 멀티스테이지 빌드, ECR, 배포 롤백, Feature Flag, Trunk-Based Development, OIDC 인증(GitHub → AWS), Trivy 이미지 스캔, GitHub Environments

  • 팀 서비스의 .github/workflows/ 폴더를 열어보고 파이프라인 흐름 파악
Terminal window
# 워크플로 파일 목록 확인
ls -la .github/workflows/
# 예상 출력:
# -rw-r--r-- 1 user group 1.2K Apr 1 09:00 deploy.yml
# -rw-r--r-- 1 user group 890 Apr 1 09:00 test.yml
  • GitHub Actions 탭에서 최근 배포 로그 확인 (어떤 단계를 거치는지)
Terminal window
# GitHub CLI로 최근 워크플로 실행 상태 확인
gh run list --limit 5
# 예상 출력:
# STATUS TITLE WORKFLOW BRANCH EVENT ID ELAPSED AGE
# ✓ feat: add health check Deploy to ECS main push 12345678 2m43s 2h
# ✓ fix: cors config Deploy to ECS main push 12345677 1m55s 5h
# ✗ feat: new endpoint Deploy to ECS main push 12345676 45s 1d
# 실패한 워크플로 로그 확인
gh run view 12345676 --log-failed
  • 배포 실패 이력이 있다면 어느 단계에서 실패했는지 확인
  • 팀의 배포 전략이 Rolling인지 Blue-Green인지 확인
Terminal window
# AWS CLI로 ECS 서비스 배포 설정 확인
aws ecs describe-services \
--cluster prod \
--services my-app \
--query 'services[0].deploymentConfiguration'
# 예상 출력:
# {
# "maximumPercent": 200,
# "minimumHealthyPercent": 100
# }
# → maximumPercent: 200, minimumHealthyPercent: 100 이면 Rolling 배포
Terminal window
# 워크플로에서 OIDC 사용 여부 확인 (팀 파이프라인 분석)
grep -r "id-token" .github/workflows/
# 출력이 있으면 OIDC 사용 중
# 출력이 없으면 정적 AWS 키 사용 중 → 보안 개선 포인트

10. 요약 — 이것만 기억해도 된다

섹션 제목: “10. 요약 — 이것만 기억해도 된다”
파이프라인이 실패했다
├── GitHub Actions 탭이 빨간색
│ ├── 어느 Step에서 실패했는지 확인
│ ├── npm ci 실패 → package-lock.json 싱크 맞는지 확인
│ ├── docker build 실패 → Dockerfile 문법/경로 확인
│ └── AWS 인증 실패 → Secrets 등록 여부 확인
└── 파이프라인은 초록색인데 서비스가 안 됨
├── ECS 콘솔 → Services → Events 탭 확인
├── 태스크 STOPPED → Stopped Reason 확인
└── /health 엔드포인트 응답 여부 확인
  1. CI는 코드 변경 시 자동 빌드·테스트, CD는 자동 배포이다
  2. 파이프라인: 코드 Push → 빌드 → 테스트 → 이미지 생성 → 배포
  3. 배포 전략(Rolling, Blue-Green, Canary)에 따라 안정성과 속도가 달라진다
  4. 시크릿은 코드에 넣지 말고 환경변수로 주입해야 하며, OIDC로 정적 키 없이 AWS 인증이 가능하다
  5. 배포 자동화는 플랫폼 엔지니어링에서 개발자 경험 개선의 핵심이다

최종 수정: 2026-04-01