CI CD 파이프라인 재설계 - 100-hours-a-week/KTB4-4th-wiki GitHub Wiki

1. 개요

Need U V2에서는 ECS 기반 인프라 전환에 맞춰 애플리케이션 CI/CD 구조를 재구성한다.

V1에서는 main 기준 이미지 빌드와 EC2 + SSM 기반 배포를 사용했지만, V2에서는 Dev 환경을 추가하고 ECS Rolling Update 기반으로 배포한다.

CI/CD의 핵심 목표는 다음과 같다.

  • Dev에서 검증한 동일한 Docker Image를 Prod에 배포한다.
  • CI와 CD의 역할 및 AWS 권한을 분리한다.
  • Dev 환경은 항상 dev 브랜치의 최신 상태를 유지한다.
  • Production 배포는 승인 절차를 거친다.
  • 배포 성공 여부를 명확하게 기록한다.
  • Dev / Prod / Rollback이 동일한 배포 절차를 사용한다.
  • 환경별 설정값은 Docker Image가 아닌 런타임에 주입한다.

Build Once, Deploy Many


2. 핵심 원칙

2.1 Docker Image

Docker Image는 dev에 Merge될 때 한 번만 생성한다.

feature/*
    │
    ▼
PR → dev
    │
    ▼
CI
    │
    ├── Test
    ├── Build
    └── Docker Image Build
            │
            ▼
           ECR
      <Git Commit SHA>

Dev에서 검증한 Image를 Production에서도 그대로 사용한다.

ECR
└── need-u/<service>:<SHA>
          │
          ├── Dev
          │
          └── Prod

Prod 배포 과정에서는 Docker Image를 다시 Build하지 않는다.


2.2 Dev 배포

dev Branch에 Merge되면 다음 과정이 자동으로 수행된다.

dev Push
   │
   ▼
CI
   │
   ├── Test
   ├── Docker Build
   └── ECR Push
          │
          ▼
      Dev Deploy
          │
          ▼
       Dev ECS

따라서 Dev 환경은 항상 dev Branch의 최신 상태를 유지한다.


2.3 Production 배포

Production 배포는 dev → main Merge를 기준으로 시작한다.

Dev 검증 완료
      │
      ▼
dev → main PR
      │
      ▼
배포 판단 Review
      │
      ▼
Merge
      │
      ▼
Production 승인
      │
      ▼
배포 전 검증
      │
      ▼
Prod ECS 배포
      │
      ▼
prod- Tag 생성

dev → main PR은 단순 코드 Merge가 아니라 Production 배포 여부를 판단하는 단계로 사용한다.


2.4 배포 기록

기록 의미
main Production에 배포하기로 결정한 코드
prod- Tag Production에 실제로 배포가 성공한 코드

Production 배포가 성공한 경우에만 다음 형식의 Git Tag를 생성한다.

prod-YYYYMMDD-N

prod- Tag는 Production에 실제 배포된 Dev Commit SHA를 가리킨다. Merge Commit 자체가 아니라 Docker Image에 사용한 SHA를 기준으로 기록한다.

Rollback은 prod- Tag가 존재하는 SHA만 허용한다.


2.5 CI / CD 권한 분리

Application PR 검증 과정에서는 AWS 권한을 사용하지 않는다.

Terraform PR은 Plan을 위해 AWS를 조회해야 하므로, Cloud 팀 승인 후 읽기 전용 Plan Role로만 접근한다.

AWS 권한은 실제 Image Push, Deployment, Plan, Apply가 필요한 Job에만 부여한다.

Application PR
└── AWS 권한 없음

Terraform PR
└── Plan Role (Cloud 팀 승인 후, Read Only)

dev Push
├── CI Role
└── Dev CD Role

Production
└── Prod CD Role

Terraform Apply
├── Dev Role (dev)
└── Prod Role (prod, shared)

3. 전체 CI/CD 흐름

단계 자동 실행 사람이 수행
feature → dev PR 테스트, 통합 테스트, Docker Build 검사 Code Review
dev Merge Image Build → ECR Push → Dev 자동 배포 Dev 검증
Dev 검증 - 기능 및 서비스 동작 확인
dev → main PR 기본 CI 검사 Prod 배포 판단
dev → main Merge 배포 SHA 추출 Production 승인
승인 완료 SHA 검증 → Prod 배포 -
배포 성공 prod- Tag 생성 -

전체 흐름은 다음과 같다.

feature/*
   │
   ▼
PR → dev
   │
   ├── Unit Test
   ├── Integration Test
   ├── Lint / Format
   └── Docker Build Check
   │
   ▼
dev Merge
   │
   ├── Docker Build
   ├── ECR Push
   └── Dev 자동 배포
   │
   ▼
Dev 검증
   │
   ▼
dev → main PR
   │
   ▼
Merge
   │
   ▼
Production 승인
   │
   ├── Dev 실행 SHA 확인
   ├── ECR Image 확인
   └── Prod Deploy
   │
   ▼
prod- Tag

Dev 검증이 진행되는 동안에는 새로운 변경사항을 dev에 Merge하지 않는다.


4. Repository별 Workflow 구성

4.1 Frontend

Frontend
└── .github/workflows/
    ├── ci.yml
    ├── deploy.yml
    ├── prod-deploy.yml
    └── rollback.yml

4.2 Backend

Backend
└── .github/workflows/
    ├── ci.yml
    ├── deploy.yml
    ├── prod-deploy.yml
    └── rollback.yml

4.3 AI

AI
└── .github/workflows/
    ├── ci.yml
    ├── deploy.yml
    ├── prod-deploy.yml
    ├── rollback.yml
    ├── catalog-sync.yml
    └── catalog-import.yml

4.4 Cloud

Cloud
└── .github/workflows/
    ├── terraform-pr.yml        # fmt, validate, plan (shared / dev / prod)
    └── terraform-apply.yml     # shared apply, dev apply → prod apply

bootstrap/은 Terraform Role 자체를 만들기 때문에 파이프라인에 포함하지 않고 Cloud 팀이 로컬에서 적용한다.

deploy.yml은 재사용 Workflow로 사용한다. Dev, Prod, Rollback 모두 동일한 배포 절차를 사용하며 환경과 Image SHA만 다르게 전달한다.


5. GitHub Environment

5.1 Application Repository

Environment 용도 승인
dev Dev 배포 없음
production Prod 배포 및 Prod AI Catalog 실행 Cloud 팀

5.2 Cloud Repository

Environment 용도 승인
terraform-plan Terraform Plan (shared / dev / prod) Cloud 팀
dev Dev Terraform Apply 없음
production Shared 및 Prod Terraform Apply Cloud 팀

Shared는 Dev·Prod 모두에 영향을 주므로 production Environment를 사용해 Prod와 같은 승인을 거친다.

승인이 필요한 Environment를 사용하는 Job은 승인이 완료되기 전까지 실행되지 않는다.


6. GitHub Variables

6.1 Application Repository Variables

변수 값
AWS_CI_ROLE_ARN V2 CI Role ARN
AWS_ECR_REPOSITORY_URI <account>.dkr.ecr.ap-northeast-2.amazonaws.com/need-u/<service>

6.2 Environment Variables

변수 Dev Production
AWS_CD_ROLE_ARN Dev CD Role 서비스별 Prod CD Role
SERVICE_DOMAIN dev.needu.gift v2.needu.gift → 전환 후 needu.gift

AI Repository에는 다음 값도 둔다.

변수 용도
AWS_TASK_SUBNET_IDS Catalog Task 실행 Subnet
AWS_CATALOG_SYNC_SG_ID Catalog Sync Security Group
AWS_CATALOG_IMPORT_SG_ID Catalog Import Security Group

Subnet과 Security Group ID는 Terraform Output 값을 사용한다.

6.3 Cloud Repository Variables

변수 Environment 값
AWS_TERRAFORM_PLAN_ROLE_ARN terraform-plan Terraform Plan Role
AWS_TERRAFORM_ROLE_ARN dev Terraform Dev Role
AWS_TERRAFORM_ROLE_ARN production Terraform Prod Role (Shared 포함)

7. Branch 운영

7.1 기본 흐름

feature/*
   │
   ▼
  dev
   │
   ▼
  main

dev와 main은 Branch Protection을 적용한다.

  • PR을 통한 Merge
  • 필수 CI 검사 통과
  • Review 완료 후 Merge

dev → main은 Merge Commit 방식만 허용한다. Production Workflow가 HEAD^2에서 Dev SHA를 추출하므로 Squash Merge와 Rebase Merge는 허용하지 않는다.

7.2 dev → main

dev → main Merge는 Merge Commit 방식을 사용한다.

Production Workflow는 Merge Commit의 두 번째 Parent에서 Dev에서 검증한 SHA를 추출한다.

main Merge Commit
├── Parent 1 = 기존 main
└── Parent 2 = 검증 완료된 dev SHA

따라서 Production에 배포할 Image는 Parent 2의 SHA를 사용한다.


8. Application CI

8.1 검증 범위

서비스 feature → dev PR dev → main PR dev Push
Backend Unit Test, Build, Integration Test, Docker Build Check Unit Test, Build Image Build → ECR → Dev Deploy
Frontend Format, Type Check, Lint, Build, Docker Build Check Format, Type Check, Lint, Build Sentry 공통값 로드 → Image Build → ECR → Dev Deploy
AI Dependency Sync, Unit Test, Ruff, Docker Build Check Dependency Sync, Unit Test, Ruff Image Build → ECR → Dev Deploy

Docker Build Check는 feature → dev PR에서 수행한다.

dev → main PR에서는 이미 Dev에서 실제 Image가 Build되고 배포되었으므로 다시 수행하지 않는다.


9. Backend CI

PR
├── Unit Test
├── Build
│
└── feature → dev인 경우
    ├── MySQL Integration Test
    └── Docker Build Check

dev Push
├── Unit Test
├── Build
├── Docker Build
├── ECR Push
└── Dev Deploy

Integration Test에서는 MySQL 8.4 Service Container를 사용한다.

services:
  mysql:
    image: mysql:8.4
    env:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: needu_test
      MYSQL_USER: test
      MYSQL_PASSWORD: test

Docker Image Tag는 Git Commit SHA를 사용한다.

need-u/backend:<github.sha>

10. Frontend CI

npm ci
   ↓
Format Check
   ↓
Next.js Type Generation
   ↓
Type Check
   ↓
Lint
   ↓
Build

feature → dev PR에서는 추가로 Docker Build Check를 수행한다.

10.1 Frontend Build 값

Frontend Image Build 시 환경별 Backend 주소를 넣지 않는다.

Docker Build
└── BACKEND_API_BASE_URL ×

ECS Runtime
└── BACKEND_API_BASE_URL ○

Docker Build 시 사용하는 값은 공통 Sentry 설정이다.

/needu/common/frontend-build/
├── NEXT_PUBLIC_SENTRY_DSN
├── SENTRY_ORG
├── SENTRY_PROJECT
└── SENTRY_AUTH_TOKEN

SENTRY_RELEASE는 Git SHA를 사용하고, SENTRY_AUTH_TOKEN은 Docker BuildKit Secret으로 전달한다.


11. AI CI

uv sync --frozen --dev
        │
        ▼
pytest tests/unit
        │
        ▼
ruff check .

feature → dev PR에서는 Docker Build Check를 추가한다.

AI Runtime과 Catalog Sync / Import는 동일한 Image를 사용한다.

need-u/ai:<SHA>
       │
       ├── AI Service
       ├── Catalog Sync
       └── Catalog Import

12. 공통 Deployment Workflow

배포 로직은 각 저장소의 deploy.yml에 정의한다.

입력값:

environment
image_tag
verify_dev_match
deploy.yml
   │
   ├── Image SHA 형식 확인
   ├── Environment별 Resource 이름 결정
   ├── OIDC → AWS Role
   ├── ECR Image 존재 확인
   │
   ├── Production인 경우
   │      └── Dev 실행 SHA와 동일한지 확인
   │
   ├── 현재 Task Definition 조회
   ├── Image만 새 SHA로 변경
   ├── 새 Task Definition Revision 등록
   ├── ECS Service Rolling Update
   ├── Service 안정화 대기
   │
   ├── AI
   │      └─ Catalog Sync / Import Task Definition도 같은 SHA로 갱신
   │
   └── Smoke Test

Terraform에서 Task Definition의 기본 구조를 관리하고, CD에서는 Image만 변경한다.


13. 서비스별 Deployment 설정

설정 Frontend Backend AI
Service frontend backend ai
Container frontend backend ai
Catalog Task Definition 갱신 — — Sync / Import
Smoke Test / /api/<BE 지정 경로> 외부 Smoke Test 없음

AI는 외부 ALB에 직접 노출되지 않기 때문에 Service 안정화와 Service Connect Metric을 통해 배포 상태를 확인한다.

Backend의 /actuator/health는 /api/* 경로에 포함되지 않으므로 외부 Smoke Test 주소로 사용하지 않는다.


14. 동시 배포 제어

서비스와 환경별로 GitHub Actions concurrency Group을 분리한다.

deploy-dev-frontend
deploy-dev-backend
deploy-dev-ai

deploy-production-frontend
deploy-production-backend
deploy-production-ai

동일 서비스에 동시에 여러 Deployment가 실행되는 것을 방지한다. 실행 중인 Deployment는 중단하지 않고 끝까지 진행한다.


15. Production Deploy

main Push가 발생하면 prod-deploy.yml을 실행한다.

15.1 SHA 추출

Merge Commit의 두 번째 Parent에서 검증된 Dev SHA를 가져온다.

git rev-parse HEAD^2

Merge Commit이 아니면 배포를 중단한다.

15.2 Production 배포

추출한 SHA를 deploy.yml에 전달한다.

environment = production
image_tag = Dev SHA
verify_dev_match = true

Production Environment 승인이 완료된 후 다음을 확인한다.

ECR에 해당 SHA Image 존재
        +
현재 Dev에서 실행 중인 SHA == 배포 요청 SHA

둘 중 하나라도 일치하지 않으면 Production 배포를 중단한다.

Production 배포 Workflow는 Merge Commit에서 추출한 SHA를 고정해 사용한다. 승인 대기 중 Dev에 새로운 배포가 발생하면 현재 Dev 실행 SHA 검증이 실패하므로 Production 배포를 중단하고 다시 검증한다.

15.3 성공 Tag

배포가 모두 성공하면 다음 Tag를 생성한다.

prod-YYYYMMDD-<run_number>

이 Tag는 실제 Production 배포에 성공한 버전을 나타낸다.


16. Rollback

Rollback은 rollback.yml을 수동 실행한다.

입력:

image_tag = 되돌아갈 Git SHA

Rollback 전에 다음을 확인한다.

입력 SHA
   │
   ├── 40자리 SHA 형식
   ├── prod- Tag 존재
   └── ECR Image 존재

prod- Tag가 없는 SHA는 Production 배포 이력이 없으므로 Rollback 대상으로 허용하지 않는다.

Rollback 역시 기존 deploy.yml을 호출한다.

rollback.yml
     │
     ▼
deploy.yml
     │
     ▼
Production 승인
     │
     ▼
ECS 배포

17. 자동 Rollback

17.1 ECS 배포 실패

새 Task가 정상적으로 실행되지 않거나 Health Check에 실패한 경우 ECS Deployment Circuit Breaker가 이전 정상 Deployment로 되돌린다.

Deployment
   │
   ▼
Task 실행 실패 / Health Check 실패
   │
   ▼
Circuit Breaker
   │
   ▼
자동 Rollback

ECS Deployment Circuit Breaker와 rollback = true를 활성화한다.

17.2 Backend 오류

Backend는 ALB 5xx Metric을 기준으로 CloudWatch Alarm을 연결한다.

Backend 5xx 증가 → ECS Deployment Alarm → Deployment Rollback

CloudWatch Alarm만 생성해서는 자동 Rollback되지 않는다. ECS Service의 Deployment Alarm으로 연결하고 Rollback 옵션을 활성화한다.

17.3 AI 오류

AI는 ALB 뒤에 없으므로 Service Connect HTTP Metric(HTTPCode_Target_5XX_Count, RequestCount)을 ECS Deployment Alarm에 연결한다.

AI SSE 응답이 HTTP 200 이후 Streaming 과정에서 끊기는 문제는 5xx로 집계되지 않을 수 있으므로 운영자가 판단하여 수동 Rollback한다.


18. 같은 버전 재배포

Terraform에서 CPU / Memory 등의 Task Definition 설정을 변경했지만 Image 자체는 바뀌지 않는 경우 같은 SHA를 재배포할 수 있다.

Dev

마지막 dev Push의 CI 실행에서 Deploy to Dev Job만 Re-run한다.

전체 Workflow를 다시 실행하지 않는다. ECR이 IMMUTABLE이므로 전체 Workflow를 재실행하면 같은 SHA Image Push 단계에서 실패할 수 있다.

Production

현재 Production SHA를 rollback.yml에 입력한다. 현재 Production 버전에는 이미 prod- Tag가 존재하므로 검증을 통과한다.

배포 과정에서 AWS에 등록된 최신 Task Definition을 조회하므로 Terraform에서 변경한 설정이 반영된다.


19. AI Catalog Pipeline

[1] AWS
Catalog Sync
     │
     ├── MySQL 상품 조회
     ├── PostgreSQL Catalog 동기화
     └── S3 Input 생성
              │
              ▼
[2] Local
AI 팀원 Mac
     │
     ├── S3 Input Download
     ├── Local Model 설명 생성
     └── S3 Output Upload
              │
              ▼
[3] AWS
Catalog Import
     │
     ├── S3 Output 조회
     ├── Upstage Embedding
     └── PostgreSQL 저장

Dev에서 전체 과정을 먼저 검증한 후 Production에서 실행한다. Production 실행은 Cloud 팀 승인을 거친다.


20. Catalog Sync

catalog-sync.yml은 수동으로 실행하며, 사용자는 Environment(dev / production)를 선택한다.

job_id는 Workflow가 자동 생성한다.

YYYYMMDD-<github.run_number>
예: 20261007-145
Catalog Sync Workflow
      │
      ├── job_id 생성
      ├── ECS RunTask
      ├── Task 종료 대기
      ├── Exit Code 확인
      └── S3 Input 존재 확인

성공 조건:

Task Exit Code = 0
        +
jobs/<job_id>/input/products.json 존재

ecs:RunTask 호출 성공만으로 Batch 성공으로 판단하지 않고 실제 Task 종료까지 기다린 뒤 Exit Code를 확인한다.


21. Local Catalog 작업

AI 팀원은 Catalog Sync 화면에 표시된 job_id를 사용한다.

JOB_ID=<catalog-sync Job ID>
BUCKET=<catalog-bucket>

aws s3 cp \
  "s3://$BUCKET/jobs/$JOB_ID/input/products.json" \
  ./products.json

# Local Model로 설명 생성 → enriched-products.json

aws s3 cp \
  ./enriched-products.json \
  "s3://$BUCKET/jobs/$JOB_ID/output/enriched-products.json"

Mac에서는 DB에 직접 접근하지 않고 Catalog S3에만 접근한다.


22. Catalog Import

catalog-import.yml 역시 수동 Workflow로 실행한다.

입력값: environment, job_id

실행 전에 jobs/<job_id>/output/enriched-products.json 존재를 확인하고, 없으면 Import Task를 실행하지 않는다.

Catalog Import Workflow
       │
       ├── job_id 검증
       ├── S3 Output 존재 확인
       ├── ECS RunTask
       ├── Task 종료 대기
       └── Exit Code 확인

Task 내부에서는 다음을 수행한다.

S3 Output → Upstage Embedding → PostgreSQL + pgvector

23. Terraform CI/CD

Application CI/CD와 Terraform CI/CD는 분리한다.

Application Repository
└── Application Build / Deployment

Cloud Repository
└── AWS Infrastructure Plan / Apply

23.1 Terraform 구성 단위

State 내용 적용 방법
bootstrap State Bucket, Terraform Role Cloud 팀 로컬 (파이프라인 제외)
shared ECR, CI Role, FE 공통 Parameter 파이프라인 + Cloud 팀 승인
dev Dev 인프라 파이프라인 자동
prod Prod 인프라 파이프라인 + Cloud 팀 승인

적용 순서는 다음과 같다.

bootstrap → shared → dev → prod
 (로컬)     (승인)   (자동)  (Dev 검증 후 승인)

23.2 전체 흐름

PR
 │
 ├── terraform fmt
 ├── terraform validate
 │
 └── Terraform Plan (shared / dev / prod)
        │
        └── Cloud 팀 승인 → Read Only Plan Role

PR Review
   │
   ▼
main Merge
   │
   ├── shared 변경 → Shared Apply (승인)
   │
   └── dev / prod 변경
          │
          ▼
       Dev Apply
          │
          ▼
     Dev Infrastructure 검증
          │
          ▼
     Production 승인
          │
          ▼
       Prod Apply

24. Terraform PR

PR에서는 실제 Infrastructure 변경을 수행하지 않는다.

먼저 AWS 권한 없이 다음을 실행한다.

terraform fmt
terraform validate

Plan은 terraform-plan Environment를 이용한다. Cloud 팀 승인 후 Read Only Plan Role을 Assume한다.

Terraform PR
    │
    ├── fmt
    ├── validate
    │
    └── Plan
         ├── Shared
         ├── Dev
         └── Prod

변경된 폴더에 따라 Plan 대상을 정한다.

변경된 폴더 Plan 대상
environments/shared/ Shared
environments/dev/, environments/prod/ Dev, Prod
modules/ Shared, Dev, Prod 모두
bootstrap/ 없음 (로컬 적용)

Plan은 읽기 전용으로 실행하며, 동시 Apply가 실행되지 않는 조건에서만 State Lock을 생성하지 않는다.

-lock=false

25. Terraform Apply

25.1 Shared Apply

environments/shared/가 변경된 경우 main Merge 후 Shared Apply를 실행한다.

main Merge (shared 변경)
   │
   ▼
Production 승인 (Cloud 팀)
   │
   ▼
Shared Plan → Shared Apply
  • Shared는 Dev·Prod 모두에 영향을 주므로 production Environment 승인을 거친다. 예를 들어 ECR Lifecycle Policy를 잘못 바꾸면 Prod Rollback에 필요한 Image가 삭제될 수 있다.
  • Shared는 변경이 드물어 별도 Role 없이 Terraform Prod Role로 적용한다.

25.2 Dev / Prod Apply

environments/dev/, environments/prod/ 또는 Dev·Prod가 사용하는 모듈이 변경되면 Dev Apply를 자동 실행한다.

main Merge
   │
   ▼
Dev Plan → Dev Apply
   │
   ▼
Dev 검증
   │
   ▼
Production 승인
   │
   ▼
Prod Plan → Prod Apply

Production에서는 승인 직후 Plan을 다시 생성한 뒤 동일 Job 안에서 Apply한다. PR 당시의 Plan과 실제 Apply 시점의 상태가 달라질 수 있기 때문이다.

25.3 Shared 변경 규칙

Shared와 Dev·Prod를 함께 바꿔야 하는 경우 Shared 변경을 별도 PR로 먼저 Merge·적용한 뒤 Dev·Prod 변경 PR을 올린다.

  • Dev·Prod는 Shared 리소스(ECR 등)를 이름으로 찾아 읽으므로 Shared가 먼저 적용되어야 한다.
  • 순서를 어기면 Dev Apply가 "리소스 없음" 오류로 중단될 뿐 기존 인프라는 변경되지 않는다. Shared 적용 후 다시 실행한다.
  • Shared와 Dev·Prod가 함께 사용하는 모듈(parameters/, iam-github-oidc/)을 바꾸는 경우에도 같은 순서를 따른다.
  • Shared 변경이 잦아지면 파이프라인에서 순서를 자동 보장하도록 바꾼다.

26. GitHub OIDC 권한

26.1 Application

Role 사용 위치 범위
CI Role dev Push ECR Push, FE Build Parameter 조회
Dev CD Role environment:dev Dev ECS 배포, Dev Catalog 실행
FE Prod CD Role FE production Prod FE 배포
BE Prod CD Role BE production Prod BE 배포
AI Prod CD Role AI production Prod AI 배포 및 Catalog 실행

Prod CD Role은 Production 배포 전 SHA 검증을 위해 자신과 동일한 서비스의 Dev Resource에 대한 조회 권한만 추가로 가진다.

AI CD Role은 Catalog 실행 과정에서 S3 파일 존재 여부를 확인할 수 있는 읽기 권한을 가진다.

26.2 Terraform

Role 사용 위치 범위 생성 위치
Terraform Plan Role terraform-plan Read Only (Shared·Dev·Prod State 읽기 포함) bootstrap
Terraform Dev Role dev Dev Infrastructure bootstrap
Terraform Prod Role production Prod Infrastructure + Shared 리소스 bootstrap
  • Terraform Role은 파이프라인이 사용하는 Role이므로 파이프라인보다 먼저 존재해야 한다. 따라서 bootstrap에서 Cloud 팀이 로컬로 생성한다.
  • bootstrap State Bucket에는 어떤 파이프라인 Role도 접근하지 않는다.
  • PR 신분에서는 Application / Terraform 어느 Role도 직접 Assume할 수 없다.

27. V1 대비 변경점

항목 V1 V2
Image Build main Push dev Push
주요 CI 검증 dev → main PR feature → dev PR
Dev Environment 없음 자동 배포
Prod 배포 SHA 수동 입력 dev → main Merge에서 SHA 자동 결정
배포 대상 SSM → EC2 Script ECS Rolling Update
FE Build 설정 Prod Frontend Parameter 전체 공통 Build Parameter만
성공 버전 기록 EC2 Tag File prod- Git Tag
자동 Rollback Deployment Script ECS Circuit Breaker + ECS Deployment Alarm
AWS 인증 GitHub OIDC 환경·역할별 GitHub OIDC
Infrastructure 관리 Console Terraform (bootstrap / shared / dev / prod)

28. Production 전환 전 검증

CI / Dev 배포

확인 항목 기대 결과
FE / BE / AI dev Merge Image 생성 → Dev 자동 배포
Dev Smoke Test 정상 응답
연속 dev Merge 최신 Image가 Dev에서 실행
Dev Deployment Job Re-run 동일 SHA + 최신 Task Definition으로 재배포

Production 배포

확인 항목 기대 결과
dev → main Merge Production 승인 대기
승인 완료 SHA 검증 후 Deployment
Deployment 성공 prod- Tag 생성
Dev SHA와 다른 SHA Deployment 중단
Merge Commit이 아닌 Main Commit Deployment 중단

Rollback

확인 항목 기대 결과
prod- Tag 존재 SHA Rollback 가능
Tag 없는 SHA Rollback 거부
Health Check 실패 ECS 자동 Rollback
Backend 5xx 증가 Alarm 기반 자동 Rollback
AI 5xx 증가 Service Connect Alarm 기반 자동 Rollback

권한

확인 항목 기대 결과
Dev Role → Prod Service 변경 AWS에서 거부
FE Prod Role → BE Prod 변경 AWS에서 거부
Application PR Workflow → AWS Login AWS에서 거부
Terraform Plan 승인 전 실행 승인 대기
Terraform Dev Role → Shared·Prod 변경 AWS에서 거부
파이프라인 Role → bootstrap State Bucket 접근 AWS에서 거부

Terraform

확인 항목 기대 결과
Shared 변경 PR Merge Production 승인 후 Shared Apply
Dev·Prod 변경 PR Merge Dev 자동 Apply → Prod 승인 대기
Shared 적용 전 Dev가 Shared 리소스 참조 Dev Apply 중단, 기존 인프라 변경 없음
modules/ 변경 PR Shared·Dev·Prod Plan 모두 표시

AI Catalog

확인 항목 기대 결과
Dev Sync → Local → Import 정상 완료
Sync Task Exit Code 0 + Input 생성
Output 없는 Import 실행 전 실패
Import Task Exit Code 0 + PostgreSQL 저장
Prod Catalog 실행 Cloud 팀 승인 대기

다중 Task

확인 항목 기대 결과
Dev Backend Task 2개 Kakao 로그인 정상
FE Image를 Dev / Prod 각각 실행 각 환경 Backend와 Sentry 환경 정상 분리
/api/v1/* 요청 ALB를 통해 Backend 정상 처리

29. 최종 구조

                          GitHub
                             │
             ┌───────────────┴───────────────┐
             │                               │
      Application Repositories          Cloud Repository
       FE / BE / AI                      Terraform
             │                               │
             ▼                               ▼
            CI                         Terraform PR
             │                         ├── fmt
             │                         ├── validate
             │                         └── plan (shared / dev / prod)
             ▼                               │
       Docker Image                          ▼
             │                          main Merge
             ▼                               │
            ECR (shared)          ┌──────────┴──────────┐
             │                    ▼                     ▼
        ┌────┴────┐         Shared Apply            Dev Apply
        │         │          (승인)                     │
        ▼         ▼                                     ▼
       Dev       Prod                              Prod Apply
        │         │                                  (승인)
        │      Approval
        │         │
        └─────────┘

bootstrap (Cloud 팀 로컬)
└── State Bucket, Terraform Role

AI 별도 운영 흐름

Catalog Sync → S3 Input → AI Team Mac → S3 Output → Catalog Import → PostgreSQL

30. 참고 자료

⚠️ **GitHub.com Fallback** ⚠️