본문 바로가기
카테고리 없음

Feature Flag 자동화 끝판왕 가이드: LaunchDarkly SDK & API 중심 롤아웃

by 지식과 지혜의 나무 2025. 5. 26.
반응형




1. 서론: Feature Flag로 릴리즈 통제하기

대규모 마이크로서비스·멀티테넌트·셀프서비스 플랫폼 환경에서, 코드 배포와 기능 롤아웃을 분리하지 않으면 아래 문제가 발생합니다:
• 배포 위험: 신규 기능 버그가 전체 트래픽에 즉시 노출
• 종속성 문제: 백엔드·프론트엔드 운용이 코드 경로에 묶임
• 지속 배포 지연: ‘배포→테스트→롤백’ 사이클 장기화

Feature Flag(토글)를 적용하면, 코드는 배포되지만 기능은 플래그로 켜고 끌 수 있습니다. 실리콘밸리·심천 톱티어 기업들은 LaunchDarkly를 중심으로 SDK와 API를 결합해 완전 자동화된 롤아웃 파이프라인을 구축합니다.



2. 아키텍처 개관

Git Repo     CI/CD         │       LaunchDarkly       │      Application
  │            │           │ ┌────────────────────────┐ │         │
  ▼            ▼           │ │ Feature Flag Config    │ │         ▼
Build & Test ──▶ Deploy ──▶│ │ ├─ Environments (dev…)  │ │  SDK   Eval(flag)
                            │ │ ├─ Feature Flags       │ ├────▶ act_on_flag()
                            │ │ └─ Segments/Targets    │ │
                            │ └────────────────────────┘ │
                            ▼                           │
                   API-Driven Flag Updates              │
                            │                           │
                           CLI                           │
                        (ldctl)                          │

1. Environments: dev, staging, prod 분리
2. Feature Flags: boolean, multivariate, percentage rollout
3. SDK: 서버·클라이언트에서 실시간 평가
4. API/CD: ldctl 또는 LaunchDarkly REST API로 코드 변경 없이 플래그 조정
5. CI/CD: PR 머지 시 자동으로 플래그 생성·변경·삭제



3. LaunchDarkly SDK 연동

3.1 Node.js 예제

const { LDClient, init } = require('launchdarkly-node-server-sdk');

const sdkKey = process.env.LD_SDK_KEY;
const ldClient = init(sdkKey, { stream: true, offline: false });

async function start() {
  await ldClient.waitForInitialization();
  const user = { key: 'user-123', custom: { plan: 'premium' } };
  const showFeature = await ldClient.variation('new-dashboard', user, false);
  if (showFeature) {
    // 신규 대시보드 컴포넌트 렌더링
  } else {
    // 기존 UI
  }
}
start();

• stream: true로 실시간 플래그 변경을 즉시 반영
• ldClient.variation(flagKey, user, default)

3.2 Python 예제

from ldclient import LDClient, Context

ld_client = LDClient(config_key='sdk-key')
user = Context.builder('user-456').set("region", "ap-northeast-2").build()

show = ld_client.variation("beta-payment", user, False)
if show:
    enable_beta_payment()
else:
    disable_beta_payment()

3.3 React 클라이언트

npm install launchdarkly-react-client-sdk

import { withLDProvider, useFlags } from 'launchdarkly-react-client-sdk';

function App() {
  const { newFeature } = useFlags();
  return newFeature ? <NewFeature /> : <OldFeature />;
}

export default withLDProvider({
  clientSideID: process.env.REACT_APP_LD_CLIENT_ID,
  user: { key: 'user-789' }
})(App);




4. 플래그 및 환경 구성

4.1 환경(환경별 프로젝트)
• Projects & Environments:
• 하나의 프로젝트에 dev·staging·prod 복수 환경
• 환경별 JSON config → GitOps로 관리

4.2 플래그 유형
• Boolean: on/off
• Multivariate: red / blue / green
• Percentage Rollout: 특정 %의 사용자에게만 켜기
• Targeting: 사용자 세그먼트(Plan, Country, Beta Tester)

4.3 세그먼트(배포 대상)
• User Segment: e.g., { plan == 'enterprise' }
• Custom Rules: JavaScript 평가식
• Generated IDs: 세그먼트를 코드에서 활용해 동적 타겟팅



5. CI/CD 파이프라인 통합

5.1 Terraform으로 Flag 정의

resource "launchdarkly_feature_flag" "new_dashboard" {
  project_key = "my-app"
  environment_keys = ["dev", "staging", "prod"]
  name = "New Dashboard"
  variations = [
    { value = false, name = "off" },
    { value = true,  name = "on"  }
  ]
  default_variation = 0
}

• terraform plan/apply 로 플래그 일관 정의
• 관리형 모듈로 재사용

5.2 GitHub Actions 예시

name: Feature Flag Rollout

on:
  workflow_dispatch:
    inputs:
      flagKey: { required: true }
      env:     { required: true }
      pct:     { required: true }

jobs:
  rollout:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install ldctl
        run: curl -sL https://github.com/launchdarkly/ldctl/releases/latest/download/ldctl-linux-x64.tar.gz | tar -xz -C /usr/local/bin
      - name: Rollout Percentage
        run: |
          ldctl feature-flag update \
            --project my-app \
            --environment ${{ inputs.env }} \
            --flag-key ${{ inputs.flagKey }} \
            --rule "percentage:${{ inputs.pct }}"

• workflow_dispatch로 수동 트리거
• ldctl CLI로 API 호출

5.3 Jenkins Pipeline

pipeline {
  agent any
  stages {
    stage('Rollout Feature Flag') {
      steps {
        withCredentials([string(credentialsId: 'LD_API_TOKEN', variable: 'LD_TOKEN')]) {
          sh """
            ldctl feature-flag update \
              --token $LD_TOKEN \
              --project my-app \
              --environment prod \
              --flag-key new-dashboard \
              --rule "percentage:20"
          """
        }
      }
    }
  }
}




6. 고급 롤아웃 전략

6.1 Canary Release
1. 0→10%: 내부 직원(사번) 세그먼트
2. 10→50%: Beta Tester 세그먼트
3. 50→100%: 전체 사용자

6.2 진입·철수 조건
• 자동 프로모션: Datadog 지표(error_rate<1%) 연동 via Webhook
• 자동 롤백: ldctl feature-flag patch --off 실행

6.3 실시간 이벤트 처리
• Streaming: SDK stream 옵션
• Data Export: LaunchDarkly Exports으로 이벤트 데이터 Lake 저장



7. 모니터링 & 메트릭
• LaunchDarkly Dashboard: 실시간 상세 이벤트 뷰
• Custom Metrics:
• Data export → Kafka → Druid/ClickHouse → Grafana
• Tag 기반 메트릭(e.g., flag:new-dashboard,count:user-served)
• Alerting:
• CloudWatch Alarm via Lambda when event count spike
• PagerDuty Webhook on rollout errors



8. 모범 사례 & “아, 이런 방법도”
1. Flag 네이밍 컨벤션:

<service>.<feature>.<stage>
payment.checkout.new_ui.flag


2. Kill Switch:
• 최우선 룰로 off 처리 가능한 글로벌 스위치
3. Flag 정리·만료:
• 사용 완료 후 ldctl feature-flag delete 자동화
• 만료일(custom attribute)로 flagged cleanup script
4. Config as Code:
• 모든 플래그 정의를 Git 레포에서 관리 (flags.json)
• Terraform/ldctl sync 파이프라인으로 동기화
5. Fallback 핸들러:

const show = await ldClient.variation('flag', user, null);
if (show===null) {
  logger.warn('LD unavailable, using default OFF');
}


6. Performance:
• Client-side SDK 연결 풀 활용
• Server-side SDK에는 offline 모드 + 캐시 활성화



9. 결론
• LaunchDarkly SDK로 애플리케이션에서 실시간 플래그 평가
• Terraform/ldctl로 플래그 정의 & 무중단 업데이트
• CI/CD 통합으로 PR부터 배포까지 플래그 자동 롤아웃
• 고급 전략(Canary, Webhook, Data Export)으로 완전 자동화

“교과서론 절대 다루지 않는, 실리콘밸리·심천 IT기업 톱티어 개발자급 Feature Flag 자동화”를 직접 구현해 보세요. 코드 한 줄 배포만으로 완벽한 컨트롤과 무중단 릴리즈가 가능합니다!

반응형