LLM WikiAccess-protected knowledge portal

WIKI

팀 운영: 브랜치 전략, 리뷰 프로세스, 배포 권한 관리

데이터 플랫폼에서 팀 운영이 기술 문제가 되는 순간 CI/CD의 마지막 병목은 종종 도구가 아니라 팀 운영이다. dbt run 은 빠르게 끝나고, Airflow DAG validation도 통과했는데, 정작 배포는 “누가 approve해야 하지?”, “이 변경은 데이터 계약 breaking change인가?”, “운영 DB 권한을 가진 사람이 직접 눌러도 되나?” 같은 질문에서 멈춘다. 데이터 플랫폼 변경은 애플리케이션 코드보

경로human/study/content/ci-cd-data-platform/08-team-operations-branch-review-deployment-permissions.md
카테고리Study
태그#airflow #branch #cicd #deployment #infra #operations #permissions #review #study

데이터 플랫폼에서 팀 운영이 기술 문제가 되는 순간

CI/CD의 마지막 병목은 종종 도구가 아니라 팀 운영이다. dbt run은 빠르게 끝나고, Airflow DAG validation도 통과했는데, 정작 배포는 “누가 approve해야 하지?”, “이 변경은 데이터 계약 breaking change인가?”, “운영 DB 권한을 가진 사람이 직접 눌러도 되나?” 같은 질문에서 멈춘다.

데이터 플랫폼 변경은 애플리케이션 코드보다 영향 범위가 늦게 드러나는 편이다. 컬럼 하나를 삭제하면 빌드는 성공할 수 있지만, 다음 날 아침 대시보드와 ML feature job이 동시에 깨질 수 있다. DAG schedule을 바꾸면 태스크는 정상 완료되지만 downstream freshness SLO가 밀릴 수 있다. 그래서 팀 운영 규칙은 “회의를 늘리기 위한 절차”가 아니라 작은 변경을 빠르게 합치되, 위험한 변경은 자동으로 더 강한 검토를 받게 하는 제어면(control plane) 이어야 한다.

이 장에서는 데이터 플랫폼 팀이 쓸 수 있는 브랜치 전략, PR 리뷰 규칙, CODEOWNERS, 배포 환경 권한, 예외 처리 방식을 하나의 운영 모델로 묶어본다.


기본 원칙: 긴 승인 체인보다 짧은 피드백 루프

좋은 팀 운영은 두 목표를 동시에 만족해야 한다.

  1. 변경 lead time을 줄인다. 작은 수정이 며칠 동안 리뷰 대기열에 묶이면 배포 단위가 커지고, 충돌과 롤백 비용도 커진다.
  2. 고위험 변경을 놓치지 않는다. 권한, 스키마, 파티션, lineage, 비용, 개인정보 관련 변경은 일반 코드 스타일 리뷰와 같은 강도로 보면 안 된다.

DORA는 소프트웨어 전달 성과를 change lead time, deployment frequency, change fail rate, failed deployment recovery time, deployment rework rate 같은 지표로 본다. 중요한 점은 속도와 안정성을 따로 최적화하지 않는다는 것이다. 배포를 자주 하려면 테스트, 리뷰, 권한 경계가 자동화되어야 하고, 안정성을 높이려면 변경 단위를 작게 유지해야 한다.

데이터 플랫폼 팀의 실무 원칙은 다음처럼 정리할 수 있다.


브랜치 전략: GitFlow보다 짧은 feature branch

데이터 플랫폼에서는 보통 GitFlow식 장기 브랜치보다 짧은 feature branch + 보호된 main이 낫다. 이유는 단순하다. SQL 모델, DAG, Terraform, Helm chart는 서로 다른 파일처럼 보여도 실제로는 같은 운영 그래프를 바꾼다. 브랜치가 오래 살아 있으면 “각자 CI는 통과했지만 main에서 합치면 깨지는” 상황이 늘어난다.

짧은 feature branch
하루~이틀 단위
작은 diff
PR + 자동 CI
lint / compile / test
lineage 영향도
CODEOWNERS 리뷰
경로별 담당 팀
위험도별 승인
protected main
직접 push 금지
status check 필수
staging 자동 배포
동일 artifact
smoke check
production 승인
환경 보호 규칙
self-review 차단
핵심은 “main에 자주 합치되, production 권한은 별도 gate로 보호한다”는 분리다.
데이터 플랫폼 팀의 권장 변경 흐름

언제 trunk-based에 가깝게 운영할 수 있나

다음 조건이 있으면 trunk-based에 가깝게 운영할 수 있다.

반대로 다음 상황에서는 release branch가 필요할 수 있다.

하지만 release branch를 쓰더라도 장기 브랜치를 “개발 공간”으로 쓰면 안 된다. release branch는 검증과 hotfix를 위한 짧은 안정화 공간이어야 한다.


PR 리뷰 프로세스: 모든 PR을 같은 방식으로 보지 않는다

데이터 플랫폼 PR은 위험도가 다르다. README 수정과 fct_revenue grain 변경을 같은 승인 규칙으로 처리하면, 둘 중 하나는 항상 틀린 절차가 된다. 리뷰 프로세스는 변경 유형을 먼저 분류해야 한다.

변경 유형예시자동 체크사람 리뷰 포인트
저위험문서, 주석, dashboard descriptionmarkdown lint, link check의미가 맞는지
일반 코드Airflow task 함수, dbt staging 모델unit test, DAG import, dbt compile유지보수성, 실패 처리
데이터 계약컬럼 추가/삭제, type 변경, model grain 변경contract check, downstream lineage diff하위 호환성, 소비자 공지
운영 위험schedule 변경, retry 정책, pool/queue 변경integration test, dry runbackfill 영향, 중복 처리
보안·권한IAM, secret, masking, PII 접근policy-as-code, secret scanleast privilege, 감사 가능성
비용 위험대형 backfill, partition 변경, cluster size 변경cost estimate, row count estimate제한 시간, kill switch

리뷰어가 볼 질문도 바뀌어야 한다.

리뷰 템플릿은 이 질문을 PR 작성자에게 미리 묻는 장치다.

## 변경 유형
- [ ] 일반 코드
- [ ] 데이터 계약 변경
- [ ] 운영 파라미터 변경
- [ ] 권한/보안 변경
- [ ] 대량 backfill 또는 비용 영향

## 영향 범위
- 변경되는 테이블/DAG:
- downstream dashboard/job:
- owner 공지 필요 여부:

## 검증
- 로컬/CI에서 실행한 명령:
- 샘플 row count 또는 reconciliation 결과:

## 롤백/완화
- 롤백 방법:
- 실패 시 중단 기준:
- 배포 후 확인할 지표:

이 템플릿의 목적은 서류 작업이 아니다. 리뷰어가 “무엇을 봐야 하는지”를 매번 추측하지 않게 하는 것이다.


CODEOWNERS: 사람 이름보다 팀 경계로 설계한다

GitHub의 CODEOWNERS는 특정 경로가 바뀌면 책임 있는 사용자나 팀을 자동으로 리뷰어로 요청하는 기능이다. branch protection 또는 ruleset에서 code owner review를 필수로 설정하면, 해당 owner의 승인이 있어야 merge할 수 있다.

데이터 플랫폼 저장소에서는 경로가 곧 운영 책임 경계인 경우가 많다.

# .github/CODEOWNERS

# 기본 fallback: 어떤 변경도 owner 없이 지나가지 않게 한다.
* @org/data-platform-maintainers

# Airflow 운영 경계
/dags/payments/ @org/payments-data-eng @org/data-platform-ops
/dags/marketing/ @org/marketing-analytics

# dbt mart는 도메인 owner와 플랫폼 owner가 함께 본다.
/dbt/models/marts/finance/ @org/finance-analytics @org/data-platform-maintainers
/dbt/models/marts/growth/ @org/growth-analytics

# 보안·권한·배포 설정은 더 좁게 보호한다.
/infra/terraform/ @org/platform-infra @org/security
/.github/workflows/deploy*.yml @org/platform-infra
/policies/ @org/security @org/data-governance

운영에서 중요한 점은 세 가지다.

  1. 개인보다 팀을 owner로 둔다. 한 명이 휴가 가면 배포가 멈추는 구조는 운영 리스크다.
  2. fallback owner를 둔다. 새 디렉터리가 생겼는데 아무도 owner가 아니면, 가장 위험한 변경이 가장 쉽게 지나간다.
  3. 권한을 실제로 확인한다. GitHub CODEOWNERS에서 owner가 되려면 write 권한이 필요하다. 팀 owner는 visible이어야 하고, 팀 자체가 명시적인 write 권한을 가져야 한다.

CODEOWNERS는 만능이 아니다. 파일 경로 기반이므로 “이 PR이 production 배포를 포함하는가”, “이 변경이 10TB backfill인가” 같은 문맥은 알지 못한다. 그래서 label, CI risk classifier, environment protection rule과 함께 써야 한다.


Branch protection과 ruleset: main을 사람 손에서 떼어놓기

main을 보호하지 않으면 모든 절차는 권고사항으로 끝난다. GitHub branch protection은 protected branch에 대해 PR 리뷰, status check, conversation resolution, signed commits, linear history, merge queue, successful deployment 같은 조건을 강제할 수 있다. 기본적으로 force push와 branch deletion도 막는다.

데이터 플랫폼 팀의 최소 권장값은 다음과 같다.

main 보호 규칙
- Require a pull request before merging
- Require approvals: 1~2명
- Require review from Code Owners
- Dismiss stale pull request approvals when new commits are pushed
- Require status checks to pass
  - lint
  - unit/integration tests
  - dbt compile/test 또는 DAG validation
  - secret scan / policy check
- Require conversation resolution before merging
- Do not allow bypassing the above settings
- Block force pushes and deletions

조직 단위로 여러 repository를 관리한다면 branch protection rule보다 ruleset이 운영하기 쉽다. 개별 repo 설정이 drift되는 문제를 줄이고, “모든 production 배포 repo는 동일한 최소 보호 규칙을 가진다”는 표준을 만들 수 있기 때문이다.

주의할 점도 있다. GitHub 문서에 따르면 branch protection rule은 한 번에 하나만 적용된다. 여러 규칙이 같은 branch를 겨냥하면 어떤 규칙이 적용되는지 헷갈릴 수 있다. 따라서 main, release/*, hotfix/*처럼 명확하게 나누고, 예외 규칙은 문서화해야 한다.


배포 권한: merge 권한과 production 권한을 분리한다

PR을 merge할 수 있는 사람과 production 배포를 승인할 수 있는 사람은 같을 수도 있지만, 권한 모델에서는 분리해서 생각해야 한다. 특히 데이터 플랫폼은 배포가 곧 외부 시스템 권한 사용을 의미하는 경우가 많다.

GitHub Actions environment는 배포 대상별 보호 규칙과 secret을 나눌 수 있다. 예를 들어 staging은 main merge 후 자동 배포하고, production은 required reviewer와 branch/tag restriction을 둔다.

# .github/workflows/deploy.yml
name: deploy-data-platform

on:
  push:
    branches: [main]
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: ./scripts/build_artifact.sh

  deploy-staging:
    needs: build
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - run: ./scripts/deploy.sh staging

  deploy-production:
    needs: deploy-staging
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://data-platform.example.internal
    steps:
      - run: ./scripts/deploy.sh production

production environment에는 다음 규칙을 권장한다.

이렇게 하면 “PR은 합쳐졌지만 production credential은 아직 열리지 않은” 상태를 만들 수 있다. 이 분리가 중요하다. 리뷰는 코드 품질과 위험 검토이고, production gate는 실제 운영 환경에 영향을 주는 행위의 승인이다.


위험도 기반 승인 매트릭스

팀 규모가 커질수록 “누가 승인해야 하는가”를 매번 Slack에서 정하면 병목이 된다. 승인 매트릭스를 미리 정해두면 자동화하기 쉽고, 예외 처리도 투명해진다.

위험도조건필요한 승인배포 방식
Low문서, 테스트, non-prod 설정1명 또는 auto-mergemain merge 후 자동
Medium일반 DAG/dbt 모델 변경CODEOWNER 1명 + CI 통과staging 자동, prod 자동 또는 팀 승인
Highcontract breaking 가능성, schedule 변경, 대량 backfilldomain owner + platform ownerproduction required reviewer
CriticalPII, 권한, secret, Terraform state, warehouse admin rolesecurity/governance + platform leadchange window + 수동 승인 + 감사 로그

이 매트릭스는 policy-as-code로 일부 자동화할 수 있다.

# 예시: PR label 기반 위험도 게이트
rules:
  - match:
      paths: ["infra/terraform/**", "policies/**"]
    require_labels: ["risk:critical"]
    require_reviewers: ["security", "platform-infra"]

  - match:
      paths: ["dbt/models/marts/**"]
    require_checks: ["dbt-test", "lineage-impact"]
    require_labels: ["owner-notified"]

  - match:
      paths: ["dags/**"]
    require_checks: ["dag-import", "dag-test"]
    require_reviewers: ["data-platform-ops"]

자동화는 완벽할 필요가 없다. 목표는 “리뷰어가 위험도를 놓치지 않게 하는 것”이다. 의심스러운 PR에 risk:needs-triage를 붙이고 merge를 막는 것만으로도 사고 가능성이 크게 줄어든다.


예외와 긴급 배포: bypass를 없애지 말고 기록하게 한다

운영에서 예외는 반드시 생긴다. 새벽 장애 중에 primary DAG를 멈춰야 하거나, 잘못 배포된 권한 정책을 즉시 되돌려야 할 수 있다. 중요한 것은 예외를 불가능하게 만드는 것이 아니라, 예외가 감사 가능하고 사후 검토 가능한 형태로만 일어나게 하는 것이다.

긴급 절차는 다음 정보를 남겨야 한다.

Emergency deploy checklist
1. Incident commander가 emergency label 부여
2. on-call platform owner가 변경 diff 확인
3. production reviewer 1명이 승인 (self-review 금지 유지)
4. 배포 후 smoke check / freshness / row count 확인
5. incident timeline에 commit SHA, workflow run, 승인자 기록
6. 24시간 안에 postmortem 또는 follow-up PR 작성

“관리자는 언제든 bypass 가능”한 설정은 편하지만 위험하다. GitHub environment와 branch protection 모두 bypass 제한 옵션을 제공하므로, 평소에는 우회를 막고 break-glass 계정을 별도로 관리하는 편이 낫다. break-glass 사용은 알림과 감사 로그가 붙어야 한다.


데이터 플랫폼 팀 운영 체크리스트

마지막으로 실무에서 바로 점검할 수 있는 체크리스트다.

Repository

CI

Deployment

Operation


마무리: 권한은 느리게 만들기 위해서가 아니라 작게 실패하기 위해서다

팀 운영 규칙이 잘못 설계되면 CI/CD는 “자동화된 배포”가 아니라 “자동화 주변의 수동 승인 지옥”이 된다. 반대로 규칙이 잘 설계되면 대부분의 작은 변경은 빠르게 지나가고, 정말 위험한 변경만 더 강한 검토를 받는다.

데이터 플랫폼의 좋은 운영 모델은 다음 문장으로 요약된다.

작은 변경은 자주 합치고, production 권한은 분리하며, 위험도는 사람이 기억하지 말고 시스템이 드러내게 한다.

브랜치 전략, CODEOWNERS, branch protection, environment protection, 승인 매트릭스는 각각 따로 보면 설정 항목이다. 하지만 함께 묶으면 팀이 빠르게 움직이면서도 데이터 품질, 보안, 비용, 복구 가능성을 잃지 않게 하는 운영 체계가 된다.

References