학습 목표
- CI/CD의 기본 개념과 파이프라인 단계를 이해한다
- GitHub Actions로 FE 프로젝트의 린트·테스트·빌드·배포를 자동화할 수 있다
- 배포 전략(Blue/Green, Canary, Rolling, Feature Flag)과 FE 환경에서의 적용을 학습한다
- 프리뷰 배포·환경 분리·시크릿 관리·모니터링까지 실무 파이프라인을 조립할 수 있다
0. 배포부터 감 잡기 — 초심자용
0-1. "배포" 가 뭔데
내 노트북에서 잘 돌아가는 코드를 전 세계 사용자가 접근 가능한 서버에 올려서 작동하게 하는 일.
예시:
- 로컬:
npm run dev→localhost:3000 - 배포: GitHub push → 빌드 → 서버 업로드 →
myapp.com에서 누구나 접근
수동 배포 과정 (옛날 방식):
1. 내 컴퓨터에서 빌드
2. FTP 로 서버에 업로드
3. 서버 로그인
4. 구버전 폴더 백업
5. 신버전 덮어쓰기
6. 확인
매번 이걸 사람이 하면 반드시 실수한다. 그래서 자동화한다.
0-2. CI/CD = 배포 파이프라인 자동화
| 약어 | 뭐냐 |
|---|---|
| CI (Continuous Integration) | 코드 변경 시 자동으로 빌드·테스트 해서 통합 가능 상태인지 확인 |
| CD (Continuous Delivery) | 머지되면 언제든 배포 가능한 결과물 을 자동 생성. 배포는 수동 승인 |
| CD (Continuous Deployment) | 통과한 변경을 자동으로 프로덕션까지 배포 (더 성숙한 단계) |
0-3. 실제 CI/CD 파이프라인 예시
GitHub 에 push 하면 자동으로:
1. 의존성 설치 (npm install)
2. 코드 스타일 검사 (ESLint)
3. 타입 검사 (tsc)
4. 단위 테스트 (Vitest)
5. 빌드 (Vite build)
6. E2E 테스트 (Playwright)
7. 빌드 결과를 Vercel/S3 에 업로드
8. 배포 URL 코멘트로 PR에 붙임
개발자는 코드만 push 하면 된다. 그 뒤는 전부 자동.
0-4. 왜 이게 중요한가 — 수동 배포의 재앙
- 수동 체크리스트: 20개 항목 중 하나 빼먹으면 사고
- 배포 창 (deploy window): "새벽 2시에 배포하자" → 사람이 피로
- "작업 중이니 빌드 건드리지 마세요": 팀원 간 충돌
- 롤백 불가: 문제 생기면 수습 어려움
CI/CD 로 해결:
- 파이프라인 통과 없이는 배포 불가 → 강제된 품질 게이트
- 배포 시간이 줄어듦 → 하루에 여러 번 배포 가능
- 실패 시 자동 롤백
- 모든 배포가 기록 에 남음
0-5. 이 장에서 다루는 도구·개념
| 항목 | 한 줄 |
|---|---|
| GitHub Actions | GitHub에서 제공하는 CI/CD 엔진 |
| Vercel / Netlify | FE 프로젝트에 특화된 배포 플랫폼 |
| Blue/Green 배포 | 두 버전 동시 운영 후 한 방에 스위치 |
| Canary 배포 | 일부 사용자에게 먼저 배포해 모니터링 |
| Rolling 배포 | 서버를 조금씩 새 버전으로 교체 |
| Feature Flag | 배포는 했지만 기능을 on/off로 제어 |
| 프리뷰 배포 | PR 마다 임시 URL 생성해 리뷰 편의 |
| 모니터링 | 배포 후 성능·에러 추적 (Sentry, Datadog) |
0-6. FE에 특화된 배포 이슈
- CDN 캐시: 새 버전 배포했는데 사용자가 구버전 보는 문제 (2-9)
- 파일명 해싱:
app.abc123.js처럼 해시를 붙여 캐시 무효화 - 환경 변수: 클라이언트에 노출되는 변수와 숨겨야 할 변수 구분
- 정적 vs 동적: SSG 는 빌드 시, SSR 은 런타임 — 배포 방식이 다름 (5-5)
0-7. 선행 장 연결
- 2-9 캐싱과 CDN: 배포 후 캐시 무효화 전략
- 5-4 모듈 시스템과 번들러: 빌드 결과물을 어떻게 배포할지
- 5-5 렌더링 패턴: SSG/SSR/CSR 별 배포 전략
- 6-6 Git: 브랜칭 전략과 CI/CD 파이프라인 통합
- 6-5 테스팅: CI 에서 어떤 테스트를 돌릴지
0-8. 이 장을 마치면
- 하루에 수십 번 배포하는 성숙한 팀의 워크플로우를 설계할 수 있음
- PR 단위로 프리뷰 배포가 자동으로 떠서 리뷰어가 바로 확인
- 버그 배포 시 1분 내 롤백
- Canary/Feature Flag로 위험 없이 큰 변경을 출시
- 6단계, 나아가 전체 커리큘럼의 마지막 장 — 여기까지 이해하면 "혼자서도 서비스를 안정적으로 운영할 수 있는 FE 개발자" 가 된 것.
1. CI/CD가 뭔가
1-1. 용어 정리
- CI (Continuous Integration): 변경이 있을 때마다 자동으로 빌드·테스트해 통합 가능한 상태인지 검증.
- CD (Continuous Delivery): 머지되면 언제든 배포 가능한 아티팩트를 만드는 자동화. 배포 자체는 수동 승인.
- CD (Continuous Deployment): 통과한 변경을 자동으로 프로덕션까지 배포.
두 CD는 약자가 같아 혼동하지만 의도가 다르다. 팀 성숙도에 따라 Delivery → Deployment로 진화.
1-2. 왜 자동화해야 하나
- 수동 배포 = 실수 온상: 체크리스트, 배포 창, 사람 실수
- 속도: 아이디어 → 프로덕션까지 분 단위로 가능해야 경쟁력
- 신뢰: 자동화된 배포가 수십 번 성공하면 "배포가 두렵지 않다"
2. 전형적인 FE 파이프라인
Push/PR
│
▼
┌────────────────┐
│ 1. Install │ pnpm install (cache hit)
├────────────────┤
│ 2. Lint/Typecheck │ eslint, tsc --noEmit
├────────────────┤
│ 3. Unit Tests │ vitest
├────────────────┤
│ 4. Build │ vite build / next build
├────────────────┤
│ 5. E2E │ playwright (PR만 또는 main만)
├────────────────┤
│ 6. Deploy │ Vercel/Netlify/S3+CloudFront
├────────────────┤
│ 7. Post-deploy │ smoke test, Lighthouse, notify
└────────────────┘
각 단계의 목적
- Install: 의존성 고정(
pnpm-lock.yaml) 기반, 캐시로 시간 단축 - Lint/Typecheck: 스타일·TS 에러 차단
- Unit/Component Test: 빠르게 회귀 잡기 (수 분 이내)
- Build: 실제 배포 아티팩트 생성, 타입·임포트 에러 최종 검증
- E2E: 느리므로 병렬 + PR/main만
- Deploy: 환경별로 (staging → production)
- Post-deploy: 실패 시 즉시 자동 롤백
3. GitHub Actions 기본
3-1. 폴더 구조
.github/
└── workflows/
├── ci.yml
├── deploy-staging.yml
└── deploy-production.yml
3-2. 기본 예
# .github/workflows/ci.yml
name: CI
on:
pull_request:
push:
branches: [main]
jobs:
lint-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm typecheck
- run: pnpm test -- --run
- run: pnpm build
3-3. Matrix (여러 환경 병렬)
strategy:
matrix:
node: [18, 20, 22]
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
3-4. Concurrency (중복 실행 취소)
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
같은 PR에 여러 번 push하면 이전 실행을 자동 취소 → CI 비용 절감.
3-5. 캐싱
- uses: actions/cache@v4
with:
path: ~/.pnpm-store
key: pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
setup-node의 cache: pnpm은 위를 자동으로 해 준다. Turbo/Nx의 원격 캐시까지 엮으면 빌드 시간이 수십 배 단축.
4. 호스팅 플랫폼
4-1. Vercel / Netlify (FE SaaS)
장점:
- Git push만으로 자동 빌드·배포
- PR마다 Preview URL 자동 생성
- 전 세계 Edge CDN + ISR 기본 지원
- 환경변수·시크릿 UI
- Next.js 1st-party 지원 (Vercel)
단점:
- 비용이 트래픽 증가에 급격
- 벤더 락인 (ISR 동작, 엣지 함수 API)
4-2. AWS S3 + CloudFront
장점:
- 저렴, 스케일 무한
- 모든 설정 통제 가능
단점:
- 수동 설정 많음 (인증, 캐시 무효화, 리다이렉트)
- SSR 하려면 Lambda@Edge / Lambda 추가 필요
기본 구성:
브라우저 → CloudFront (CDN) → S3 (정적 파일)
│
└→ Lambda@Edge (SSR 또는 auth check)
4-3. Cloudflare Pages / Workers
- 글로벌 엣지 + Workers(서버리스) + D1(SQLite) 조합
- 가격·성능 면에서 신흥 강자
- Wrangler CLI로 배포
4-4. Docker + Kubernetes
대규모 조직. FE도 Next.js SSR을 컨테이너로 배포.
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN pnpm build
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
EXPOSE 3000
CMD ["node", "server.js"]
멀티 스테이지 빌드로 최종 이미지 크기 최소화.
5. 환경 분리
5-1. 환경 스테이지
| 환경 | 용도 | 배포 트리거 |
|---|---|---|
| Development | 로컬 | 개발자 머신 |
| Preview / PR | 리뷰용 | PR 생성/업데이트 |
| Staging | QA, 통합 테스트 | main 머지 |
| Production | 실사용자 | 태그 푸시 / 수동 승인 |
5-2. 환경변수 관리
.env.local은 절대 커밋 금지- CI/CD에는 Secret 저장소(GitHub Secrets, Vercel env, AWS Secrets Manager)
- 빌드 시점에 주입되는 값(
NEXT_PUBLIC_*)과 런타임에 주입되는 값을 구분
⚠️ NEXT_PUBLIC_ 접두사는 브라우저에 번들된다. 여기에 비밀키 넣지 말 것.
5-3. 12-Factor App의 Config 원칙
- 코드와 설정을 분리
- 환경 간 차이는 환경변수로만
- 같은 아티팩트를 모든 환경에 배포, 설정만 교체
6. 배포 전략
6-1. 즉시 전체 교체 (Naive)
v1 → v2 즉시 교체
- 문제 시 전체 영향
- 롤백은 이전 빌드 재배포
- 작은 조직은 충분하지만 안전장치 필요
6-2. Blue/Green
Blue (v1, 운영) ─────→ 사용자
Green (v2, 대기)
[스위치] → Green (v2, 운영) ─→ 사용자
Blue (v1, 대기 — 롤백용)
- 전환이 즉시, 롤백도 즉시 (로드밸런서 방향만 변경)
- 인프라 2세트 필요 → 비용
6-3. Rolling
서버 인스턴스를 하나씩 v2로 교체.
- 점진적 전환, 비용 적음
- 일부 사용자에게 중간에 v1/v2 섞여 보일 수 있음
- 쿠버네티스 기본 전략
6-4. Canary
사용자 5% ─→ v2 (새 버전)
사용자 95% ─→ v1
↓
메트릭 정상?
↓ Yes
사용자 50% ─→ v2 … 100%
- 점진적 노출 + 모니터링
- 문제 시 즉시 차단
- FE에서는 CDN Rule·엣지 함수·Feature Flag로 구현
6-5. Feature Flag (토글)
if (flags.newCheckoutUI) {
return <NewCheckout />;
}
return <OldCheckout />;
- 배포와 릴리스 분리 — 코드는 배포됐지만 기능은 꺼져 있음
- 사용자 세그먼트·%·지역별 토글
- 문제 시 코드 롤백 없이 플래그 off로 복구
- 도구: LaunchDarkly, Unleash, GrowthBook, Statsig
⚠️ Flag 빚: 제거 잊은 플래그가 쌓이면 조합 폭발 + 테스트 매트릭스 폭발. 라이프사이클(생성→제거) 관리 필수.
6-6. FE의 실용 전략 조합
- 정적 자산: 해시된 파일 + immutable 캐시 → 자동적으로 Blue/Green
- SSR 서버: 컨테이너 Rolling / Blue-Green
- 기능 노출: Feature Flag
- 민감 변경: Canary (유저 %로 점진 노출)
7. Preview 배포
7-1. 가치
- PR마다 실제 URL → 디자이너·PM·QA가 직접 확인
- 리뷰 속도 급상승
- 머지 전 실환경에 근접한 검증
7-2. Vercel/Netlify
자동 제공. 커밋마다 고유 URL 생성.
7-3. 자체 구축
- S3 prefix로 PR별 폴더 (
pr-42/) - Kubernetes + 임시 서브도메인
8. 모니터링·Observability
8-1. 3대 기둥
- Metrics: 숫자로 측정 (요청 수, p95 지연, 에러율)
- Logs: 이벤트 텍스트 기록
- Traces: 요청 하나의 여정 추적 (분산 시스템)
8-2. FE 특화
- Real User Monitoring (RUM): 실제 사용자 Core Web Vitals 수집 (web-vitals.js → Datadog/New Relic/Cloudflare)
- 에러 추적: Sentry가 사실상 표준 — JS 에러, 소스맵, Release, User 정보 연결
- 세션 리플레이: LogRocket, Datadog Session Replay — 사용자 화면 재현 (개인정보 마스킹 필수)
8-3. Release 통합
Sentry + Git 해시 연결 → "이 버전 배포 후 에러율 급증"을 자동 감지. Release health 모니터링.
8-4. 알림
- Slack/PagerDuty로 임계치 초과 시 알림
- 휴면 시간·담당자 로테이션 설정
9. 보안
9-1. Secret 관리
- 절대 커밋 금지 —
.env, API 키, 토큰 - Git 히스토리 누설 검사:
git-secrets, GitHub Advanced Security,gitleaks - 이미 누설 시: 즉시 rotate(키 폐기·재발급), Git 히스토리에서 제거(
git filter-repo) - Short-lived tokens 선호 (OIDC를 AWS·GCP 등에 신뢰)
9-2. OIDC로 AWS 접근
GitHub Actions → AWS 접근에 장기 Access Key 대신 OIDC 토큰 교환 사용.
permissions:
id-token: write
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::...:role/gh-deploy
aws-region: ap-northeast-2
→ 장기 비밀 없이 임시 자격 증명. 권장 표준.
9-3. SBOM과 의존성 스캐닝
- Dependabot / Renovate: 의존성 업데이트 PR 자동
- CodeQL: 보안 취약점 정적 분석
- npm audit /
pnpm audit: CI에 통합 - SBOM(Software Bill of Materials): 배포 아티팩트의 의존성 목록, SLSA 공급망 보안
9-4. CI 스크립트도 감시
pull_request_target+ secrets 조합의 공격 벡터 주의 (포크에서 악성 코드 실행 위험)pull_request이벤트는 secrets 접근 제한 — 포크 안전
10. 롤백·사고 대응
10-1. 빠른 롤백
- 정적 자산: 이전 배포를 즉시 다시 활성화 (Vercel/Netlify 클릭 한 번)
- SSR 서버: 이전 Docker 이미지로 교체 (k8s:
kubectl rollout undo) - Feature Flag: 코드 롤백 없이 플래그 off
10-2. 헬스체크 + 자동 롤백
배포 후 1-2분간 에러율·지연 모니터. 임계치 초과 시 자동 이전 버전으로 복구.
10-3. Post-mortem
장애 후 비난 없는 분석(blameless post-mortem):
- 타임라인
- 원인(기술적·프로세스적)
- 재발 방지 액션
- 배운 점
문서화해 팀 메모리에 남긴다. 사람을 탓하지 않고 시스템을 개선하는 문화가 핵심.
11. 실전 파이프라인 예
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
concurrency:
group: deploy-production
cancel-in-progress: false
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with: { node-version: 20, cache: pnpm }
- run: pnpm install --frozen-lockfile
- run: pnpm lint && pnpm typecheck && pnpm test -- --run
build:
needs: quality
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with: { node-version: 20, cache: pnpm }
- run: pnpm install --frozen-lockfile
- run: pnpm build
env:
NEXT_PUBLIC_API_URL: ${{ secrets.PROD_API_URL }}
- uses: actions/upload-artifact@v4
with:
name: dist
path: .next/
deploy:
needs: build
runs-on: ubuntu-latest
environment: production
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with: { name: dist, path: .next/ }
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::...:role/gh-deploy
aws-region: ap-northeast-2
- run: aws s3 sync .next/static s3://my-app/_next/static --cache-control "public, max-age=31536000, immutable"
- run: aws cloudfront create-invalidation --distribution-id XXX --paths "/*"
smoke-test:
needs: deploy
runs-on: ubuntu-latest
steps:
- run: curl -f https://app.example.com/healthz
notify:
needs: smoke-test
if: always()
runs-on: ubuntu-latest
steps:
- uses: slackapi/slack-github-action@v1
with:
payload: '{"text":"Deploy ${{ job.status }}"}'
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
12. 실무 체크리스트
- 모든 변경이 PR을 통해서만 main에 머지되는가 (branch protection)
- CI에서 lint/typecheck/test/build가 필수 통과해야 머지되는가
- 같은 빌드 아티팩트가 staging/production 모두에 배포되는가 (12-Factor)
- 시크릿이 Git에 커밋되어 있지 않은가 (gitleaks 스캔)
- Preview 배포로 PR마다 실환경 검증이 되는가
- Feature Flag로 배포와 릴리스가 분리되어 있는가
- 프로덕션 에러가 Sentry/에러 모니터링으로 실시간 수집되는가
- 롤백이 1분 이내에 가능한가
- Core Web Vitals·에러율이 배포 직후 자동 감시되는가
-
concurrency로 CI 중복 실행이 취소되는가
13. 연습 문제
Q1. Continuous Delivery와 Continuous Deployment의 차이를 설명하라.
정답
둘 다 CI의 연장선이지만:
- Continuous Delivery: 머지된 변경이 자동으로 배포 가능한 아티팩트로 만들어지고 staging까지는 자동 반영되지만, 프로덕션 배포는 수동 승인이 필요.
- Continuous Deployment: 테스트·빌드 통과한 변경이 자동으로 프로덕션까지 배포.
Delivery는 "언제든 배포할 준비"이고 Deployment는 "자동 배포까지". 팀의 테스트 자동화·모니터링 성숙도가 높을수록 Deployment로 이행 가능. 규제 산업(금융·의료)은 Delivery에 머무는 경우가 많다.
Q2. FE에서 Blue/Green과 Canary 배포를 구현할 때 각각 어떤 인프라 요소가 쓰이는가?
정답
- Blue/Green: 정적 자산이면 CDN Origin 전환(S3 두 버킷 또는 경로)으로 일거에 교체. SSR이면 로드밸런서/ALB의 타깃 그룹 전환. 또는 쿠버네티스 서비스 셀렉터 변경.
- Canary: CDN/엣지 함수의 트래픽 분할 규칙(Cloudflare Workers, Vercel Edge Config)으로 예: 5% → v2, 95% → v1. SSR이면 ALB weighted routing 또는 Istio VirtualService. Feature Flag 도구로도 비슷한 효과를 낼 수 있다.
두 전략 모두 메트릭 모니터링(Sentry, Datadog)과 자동 롤백 훅이 함께 있어야 안전.
Q3. NEXT_PUBLIC_* 환경변수에 비밀키를 넣으면 안 되는 이유를 설명하라.
정답
Next.js(또는 Vite의 VITE_*)는 NEXT_PUBLIC_ 접두사가 붙은 환경변수를 빌드 시점에 번들에 인라인한다. 결과적으로 브라우저가 받는 JS 파일에 평문으로 포함된다.
누구나 DevTools의 Sources 탭이나 번들 파일을 뜯어 값을 읽을 수 있으므로, API 시크릿·DB 비밀번호·결제 서버 키 등은 절대 넣으면 안 된다. 공개돼도 무방한 값(공용 API URL, 공개용 키, 분석 도구 ID)만 사용.
서버에서만 쓸 비밀은 NEXT_PUBLIC_가 붙지 않은 이름으로 두고, 서버 코드(Server Component, API Route, Server Action)에서만 참조한다.
Q4. Feature Flag가 "배포와 릴리스를 분리"한다는 말의 의미와 실무 이점을 설명하라.
정답
- 배포(Deploy): 코드가 프로덕션 서버에 올라감
- 릴리스(Release): 사용자가 실제로 새 기능을 사용하게 됨
Feature Flag를 쓰면, 새 기능 코드를 배포하되 플래그가 off라 아무도 못 쓴다. 이후 원하는 시점에 플래그를 켜서 릴리스한다.
이점:
- 점진적 노출: 1%→10%→50%→100%로 점진 공개. 문제 시 플래그만 off.
- 코드 롤백 불필요: 기능 꺼도 코드는 살아 있음. 재배포 없이 즉시 복구.
- A/B 테스트: 세그먼트별 기능 분기로 가설 검증.
- 리스크 분산: 배포 시점 ≠ 고객 영향 시점이라 배포일이 "위험한 날"이 아님.
- 협업: 백엔드 기능이 먼저 릴리스돼도 프런트는 개발·머지 중 상태 유지 가능.
단, 플래그 빚 관리가 핵심. 수명 짧게·삭제 일정 명확히.
Q5. CI에서 concurrency: cancel-in-progress: true를 쓰는 이유를 설명하라.
정답
개발자가 같은 PR에 여러 번 push하면 이전 커밋에 대한 CI 실행이 아직 끝나지 않은 상태로 새 실행이 시작된다. 최종적으로 관심 있는 건 최신 커밋의 결과뿐이다.
concurrency 그룹을 워크플로 + ref 단위로 묶고 cancel-in-progress: true를 주면, 새 실행이 시작될 때 동일 그룹의 이전 실행을 자동 취소한다.
이점:
- CI 시간·비용 절감 (무의미한 옛 커밋 검증 중단)
- 러너 점유 감소 → 다른 PR 빨리 돎
- 사용자에게 최신 상태 빠르게 반영
단, main/production 배포 작업은 cancel-in-progress: false로 둬야 한다. 동시 실행·중간 취소가 데이터 부정합이나 반쯤 끝난 배포를 만들 수 있다.
Q6. "같은 아티팩트를 모든 환경에 배포하라"는 12-Factor 원칙이 중요한 이유를 설명하라.
정답
staging과 production을 각각 다시 빌드하면, 빌드 환경·타임스탬프·의존성 해석 차이로 두 아티팩트가 미묘하게 달라질 수 있다. staging에서 검증된 그 파일이 아닌 것이 production에 가면, staging 테스트 결과의 보증이 깨진다.
한 번 빌드 → 모든 환경에 같은 파일 배포, 환경 차이는 오로지 환경변수로만 표현하면:
- 재현성: 프로덕션 버그를 staging에서 그대로 재현 가능.
- 속도: 환경마다 빌드 반복 불필요, 배포 시간 단축.
- 신뢰: "이 해시는 모든 환경에서 동일"이라는 SLSA 공급망 보안 속성과도 부합.
실무 구현: CI에서 빌드 → artifact 업로드 → deploy 잡에서 download 후 환경 변수만 바꿔 배포.
Q7. GitHub Actions에서 AWS 리소스에 접근할 때 "장기 Access Key" 대신 OIDC를 쓰는 이유를 설명하라.
정답
장기 Access Key를 GitHub Secrets에 저장하면:
- 키가 영구 유효해, 누설되면 즉시 폐기·재생성 필요
- 로테이션이 수작업·잊히기 쉬움
- 감사 시 "누가 언제 썼는지" 추적이 애매
OIDC:
- GitHub Actions가 **실행 시점에 서명된 JWT(OIDC 토큰)**를 발급 → AWS IAM이 검증 → 임시 자격 증명(STS) 반환
- 토큰은 수분 내 만료, 훔쳐도 오래 못 씀
- GitHub의
repo:org/repo:ref:refs/heads/main같은 subject claim으로 어떤 저장소·브랜치·환경에서 온 요청인지 IAM Role 신뢰 정책으로 제한 가능 → 스코프 최소화 - 장기 비밀이 저장소에 없으므로 관리 부담·누설 위험 감소
결과: 자격 증명 관리 자동화 + 보안 원칙(최소 권한·단명 토큰) 준수. AWS/GCP/Azure 모두 지원하며 실무 표준이 됐다.
14. 정리
- CI는 변경의 통합 가능성을, CD는 배포까지를 자동화한다. Delivery는 수동 승인, Deployment는 완전 자동.
- FE 파이프라인은 Install → Lint/Typecheck → Test → Build → (E2E) → Deploy → Post-deploy 순.
- GitHub Actions + Vercel/Netlify가 가장 생산적인 조합, 대규모는 S3+CloudFront 또는 K8s.
- 환경은 Dev → Preview → Staging → Production 단계로, 한 번 빌드 → 환경변수만 교체 원칙.
- 배포 전략은 Blue/Green · Rolling · Canary · Feature Flag를 조합. FE에선 Feature Flag가 배포↔릴리스 분리의 핵심.
- Sentry·RUM·Lighthouse CI로 배포 직후 품질 감시.
- OIDC + Short-lived Token · Dependabot · SBOM으로 공급망·시크릿 보안을 기본기로.
- 롤백은 1분, Post-mortem은 비난 없이.
이 단계까지 오면, "만들고 테스트하고 배포하고 운영하는" 전체 사이클을 한 사람이 리드할 수 있는 시니어 개발자의 기초가 갖춰진 것이다.