Close

Bitbucket Pipelines에서 Split 기능 플래그 사용

Warren Marusiak 얼굴 사진
Warren Marusiak

선임 기술 에반젤리스트

프로덕션 환경에 새 코드를 배포하는 것은 위험합니다. 코드가 단위 테스트, 통합 테스트, 테스트 및 스테이징 환경에서의 시스템 테스트를 거친 후에도 프로덕션에서 버그가 발생할 수 있습니다. 기존에는 프로덕션에서 버그가 발생하고 사용자가 영향을 받으면 개발자가 두 가지 선택을 할 수 있었습니다. 버그가 있는 코드를 롤백하거나 수정을 배포할 수 있었으며 두 해결책 모두 시간이 걸렸습니다. 이제는 개발자가 관련 코드 변경을 기능 플래그에 래핑하여 버튼을 한 번만 클릭하면 환경에서 기능을 활성화 또는 비활성화할 수 있습니다. 버그가 발생한 코드가 사용자에게 미치는 영향을 즉시 완화할 수 있으며 수정을 개발하고 안전하게 적용할 수 있습니다. 이 문서에서는 Bitbucket Pipelines 및 ImageLabeller 데모 애플리케이션의 Split 기능 플래그를 사용하여 이것을 보여줍니다.

ImageLabeller 기능 플래그 데모

ImageLabeller는 머신러닝을 사용하여 이미지에 레이블을 지정하는 작은 애플리케이션입니다. ImageLabeller는 테스트, 스테이징, Production-us-west-2, Production-us-east-1, Production-ca-central-1의 다섯 가지 환경에 배포됩니다. 이 문서에서는 기능 플래그를 사용하여 ImageLabeller의 SubmitImage 컴포넌트에 대한 변경 사항을 관리하는 방법을 보여줍니다. SubmitImage는 Go로 작성된 AWS Lambda입니다. 이 데모는 기능 플래그 관리에 Split을, 소스 제어에 Bitbucket을, CI/CD 기능 관리에 Bitbucket Pipelines를 사용합니다.

Bitbucket Pipelines에서 Split 기능 플래그를 사용하는 방법

Split 계정을 만들고 관리자 설정으로 이동하여 워크스페이스로 이동합니다. 사용 가능한 환경을 보려면 기본 작업 영역에서 보기를 클릭합니다.

관리자 설정의 작업 영역 스크린샷

기본 환경의 이름을 바꾸고 사용 사례에 맞게 새 환경을 추가합니다. ImageLabeller는 테스트, 스테이징, 그리고 US-WEST-2, US-EAST-1, CA-CENTRAL-1의 세 AWS 리전에 해당하는 세 가지 프로덕션 환경에 배포됩니다.

작업 영역 편집 옵션

분할을 클릭한 다음 왼쪽 탐색 패널에서 분할 만들기를 클릭하여 기능 플래그인 새 분할을 만듭니다.

분할을 만들기 위한 팝업 창

Split에 이름을 지정하고 트래픽 유형을 사용자로 변경합니다.

분할 창 만들기에서 트래픽 유형 입력

규칙 추가를 클릭하여 스플릿을 만든 후에 타겟팅 규칙을 추가합니다. 테스트 환경을 위한 타겟팅 규칙을 만듭니다. 각 환경은 별도의 타겟팅 규칙을 가질 수 있습니다. 타겟팅 규칙은 코드에서 액세스할 때 분할에서 반환되는 데이터를 정의합니다. 이 가이드에서는 분할이 기본적으로 비활성화되고 특정 사용자가 분할에 액세스할 때 활성화되도록 설정합니다.

규칙 추가

기본 규칙 설정을 펼치고 비활성화로 설정합니다.

기본 규칙 설정

개별 대상 설정을 펼치고 대상 추가를 클릭한 다음 서브활성화로 설정하고 사용자에게를 QA 프로세스의 일부인 사용자로 설정합니다. 이 가이드에서는 테스트 사용자로 AtlassianDemoUser@atlassian.com을 사용합니다.

허용 목록 만들기

변경 사항을 저장합니다. 이제 분할에 테스트 환경을 위한 타겟팅 규칙이 있습니다. 다른 리전의 환경 드롭다운을 클릭합니다. 예를 들면 스테이징이 있습니다.

환경 드롭다운

다음에서 타겟팅 규칙 복사를 클릭하고 테스트를 선택하여 이전에 만든 타겟팅 규칙을 복사합니다. 각 환경에 이 과정을 반복합니다. 환경마다 타겟팅 규칙이 매우 다를 수 있습니다. 이 가이드는 환경 전반의 타겟팅 규칙을 동일하게 유지합니다.

대상 규칙 복사 중

관리자 설정으로 이동한 후 API 키로 이동하여 각 환경의 API 키 목록을 받습니다. API 키는 올바른 버전의 Split을 가져오기 위해 코드에서 API 호출 중에 Split으로 다시 전송됩니다. 이 가이드에서는 각 환경에 서버 측 키를 사용합니다.

관리자 설정

Bitbucket 리포지토리로 이동한 다음 리포지토리 설정, 리포지토리 변수로 이동하여 각 API 키에 변수를 추가합니다.

리포지토리 설정의 리포지토리 변수

bitbucket-pipelines.yml 파일을 편집하고 AWS SAM 배포 단계에 STACK_PARAMETERS를 추가합니다. 이 작업은 환경별로 수행됩니다. 아래의 YAML 스니펫은 AWS US-WEST-1 테스트 리전의 배포 단계를 보여줍니다. 따라서 이 단계는 위의 split_test_env 리포지토리 변수 설정을 참조합니다. 각 환경에 적합한 리포지토리 변수를 사용하세요.

- pipe: atlassian/aws-sam-deploy:1.2.0
  variables:
    AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
    AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
    AWS_DEFAULT_REGION: 'us-west-1'
    STACK_NAME: 'OpenDevOpsSubmitImage'
    CAPABILITIES: [ 'CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM', 'CAPABILITY_AUTO_EXPAND' ]
    TEMPLATE: 'https://s3.amazonaws.com/open-devops-code-us-west-1-${AWS_ACCOUNT_ID}/submit-image-packaged.yml'
    WAIT: 'true'
    DEBUG: 'true'
    S3_BUCKET: 'open-devops-code-us-west-1-${AWS_ACCOUNT_ID}'
    SAM_TEMPLATE: 'build/template.yaml'
    STACK_PARAMETERS: '[{
      "ParameterKey": "SplitIOSDKKey",
      "ParameterValue": "${split_test_env}"
    }]'

AWS CloudFormation template.yml 파일을 편집하고 Split SDK 키를 참조하는 매개 변수 섹션을 추가합니다.

Parameters:
  SplitIOSDKKey:
    Type: String

template.yml 파일에서 Split에 액세스하는 데 필요한 각 AWS Lambda 리소스에 환경 섹션을 추가합니다. 이 가이드는 다음을 보여줍니다

Environment:
  Variables:
    SplitIOSDKKey:
      Ref: SplitIOSDKKey

Split SDK를 사용할 Go 파일에 다음 종속성을 가져옵니다.

"github.com/splitio/go-client/v6/splitio/client"
"github.com/splitio/go-client/v6/splitio/conf"

이 함수는 클라이언트를 만들고 Split UI에서 만들어진 “SubmitImageDemoSplit”의 기능 플래그 값을 검색합니다. 사용자 이름이라는 단일 매개 변수가 있어야 합니다.

func getSplitIOFlag(username string) (string, error) {
  splitIOSDKKey := os.Getenv("SplitIOSDKKey")

  cfg := conf.Default()
  factory, err := client.NewSplitFactory(splitIOSDKKey, cfg)
  if err != nil {
    fmt.Printf("SDK init error: %s\n", err)
    return "", err
  }

  splitClient := factory.Client()
  err = splitClient.BlockUntilReady(10)
  if err != nil {
    fmt.Printf("SDK timeout: %s\n", err)
    return "", err
  }

  treatment := splitClient.Treatment(username, "SubmitImageDemoSplit", nil)
  fmt.Printf("SPLIT_DEMO treatment is %s, username is %s\n", treatment, username)

  return treatment, nil
}

이메일 주소로 함수를 호출합니다. 이 경우 someRandomUser@atlassian.com은 기능 플래그와 연결된 허용 목록의 구성원이 아니므로 기능 플래그의 기본값을 가져옵니다. AtlassianTestUser@atlassian.com은 자신이 속한 허용 목록에 연결된 기능 플래그의 값을 가져옵니다.

foo, err := getSplitIOFlag("someRandomUser@atlassian.com")
  _ = foo

  bar, err := getSplitIOFlag("AtlassianDemoUser@atlassian.com")
  _ = bar

코드가 실행된 후에 AWS CloudWatch 로그의 출력을 살펴보세요. someRandomUser@atlassian.com이 액세스할 때 기능 플래그가 비활성화되고 AtlassianTestUser@atlassian.com이 액세스할 때 기능 플래그가 다시 활성화되는 것을 살펴보세요.

이벤트 로그

이런 식으로 개발자들은 다른 배포를 하지 않고도 코드 실행을 제어할 수 있습니다. 환경에서 버그가 발견되면 해당 환경의 기능 플래그를 비활성화하고 이전 코드를 실행할 수 있습니다.

결론

Split 기능 플래그는Bitbucket Pipelines를 통해 배포된 애플리케이션에 쉽게 통합됩니다. 개발자는 기능 플래그를 사용하여 배포된 코드의 실행을 제어할 수 있습니다. 이렇게 하면 버그가 있는 배포에 더 빠르게 대응하고 사용자에게 미치는 영향을 줄일 수 있습니다. 시간을 내어 Bitbucket 및 Split 인스턴스를 시작하고 팀의 역량을 테스트하세요.

Warren Marusiak
Warren Marusiak

Warren is a Canadian developer from Vancouver, BC with over 10 years of experience. He came to Atlassian from AWS in January of 2021.


이 문서 공유

여러분께 도움을 드릴 자료를 추천합니다.

이러한 리소스에 책갈피를 지정하여 DevOps 팀의 유형에 대해 알아보거나 Atlassian에서 DevOps에 대한 지속적인 업데이트를 확인하세요.

DevOps 일러스트레이션

DevOps 커뮤니티

DevOps 일러스트레이션

DevOps 학습 경로

맵 일러스트레이션

무료로 사용해보기

DevOps 뉴스레터 신청

Thank you for signing up