Close

Bitbucket Pipelines での Split 機能フラグの使用

Warren Marusiak の顔写真
Warren Marusiak

シニア テクニカル エバンジェリスト

新しいコードを本番環境にデプロイするのは危険です。テスト環境やステージング環境でコードのユニット テスト、統合テスト、システム テストを実施した後でも、バグが本番環境に侵入する可能性があります。バグが本番環境に侵入してユーザーが影響を受けると、従来、開発者には 2 つの選択肢がありました。バグのあるコードをロール バックするか、修正をロール フォワードすることです。どちらの解決法も時間がかかります。今では、開発者は関連するコード変更を機能フラグで囲み、ボタンをクリックするだけで、環境内の機能をオンまたはオフにすることができます。バグのあるコードがユーザーに与える影響をすばやく軽減でき、修正プログラムを開発して安全にロール フォワードできます。この記事では、ImageLabeller デモ アプリケーションで Bitbucket Pipelines と Split 機能フラグを使用して、この内容をご説明します。

ImageLabeller 機能フラグ デモ

ImageLabeller は、機械学習を使用して画像にラベルを添付する小さなアプリケーションです。IamgeLabeller は 5 つの環境にデプロイされます。テスト、ステージング、Production-us-west-2、Production-us-east-1、Production-ca-central-1 です。この記事では、機能フラグを使用して ImageLabeller の SubmitImage コンポーネントへの変更を管理する方法についてご説明します。SubmitImage は、Go で記述される AWS Lambda です。このデモでは、Split を使用して機能フラグを管理します。Bitbucket をソース管理に、Bitbucket Pipelines を CI/CD 機能に使用します。

Bitbucket Pipelines で Split 機能フラグを使用する方法

Split アカウントを作成し、[管理者設定]、[ワークスペース] の順に移動します。デフォルトのワークスペースで [表示] をクリックすると、使用可能な環境が表示されます。

管理者設定でのワークスペースのスクリーンショット

デフォルト環境の名前を変更し、ご自身のユース ケースに合わせて新しい環境を追加します。IamgeLabeller は 5 つの環境にわたってデプロイされます。テスト、ステージング、および 3 つの AWS リージョン (US-WEST-2、US-EAST-1、CA-CENTRAL-1) に対応する 3 つの本番環境です。

ワークスペースの編集オプション

左側のナビゲーションパネルで [Splits (スプリット)]、[Create split (スプリットを作成)] を順にクリックして、新しいスプリット (機能フラグ) を作成します。

スプリットを作成するためのポップアップ ウィンドウ

スプリットに名前を付け、[トラフィック タイプ] を [ユーザー] に変更します。

スプリット作成ウィンドウでのトラフィック タイプの入力

スプリットを作成したら、[ルールを追加] をクリックして、ターゲティング ルールを追加します。テスト環境のターゲティング ルールを作成します。環境ごとに個別のターゲティング ルールを設定できます。ターゲティング ルールでは、コードでのアクセス時に、スプリットによって返されるデータを定義します。このガイドでは、スプリットをデフォルトでオフに、特定のユーザーがスプリットにアクセスしている場合はオンになるように設定します。

ルールの追加

[Set the default rule (デフォルト ルールを設定)] を展開し、オフに設定します。

デフォルト ルールの設定

[Set individual targets (個々のターゲットを設定)] を展開し、[Add Target (ターゲットを追加)] をクリックして [Serve (提供)] をオンに設定します。[To Users (対象ユーザー)] を QA プロセスの一部であるユーザーに設定します。このガイドでは、AtlassianDemoUser@atlassian.com をテスト ユーザーとして使用します。

ホワイトリストを作成

変更を保存します。このスプリットには、テスト環境のターゲティング ルールが適用されるようになりました。別のリージョンの [環境] ドロップダウンをクリックします。例: ステージング。

環境のドロップダウン

[Copy targeting rules from (ターゲティング ルールのコピー元)] をクリックして、[テスト] を選択し、以前に作成したターゲティング ルールをコピーします。各環境でこのプロセスを繰り返します。環境によってターゲティング ルールが大きく異なる可能性があります。このガイドでは、環境全体でターゲティング ルールを同一にします。

ターゲット ルールのコピー

[管理者設定]、[API キー] の順に移動して、各環境の API キーのリストを取得します。これらの API キーは、スプリットの正しいバージョンを取得するために、コードでの API 呼び出し時にスプリットに送り返されます。このガイドでは、各環境の Server 側のキーを使用します。

管理者設定

Bitbucket のリポジトリ、[リポジトリ設定]、[リポジトリ変数] の順に移動し、各 API キーに変数を追加します。

リポジトリ設定のリポジトリ変数

bitbucket-pipelines.yml ファイルを編集して、STACK_PARAMETERS を AWS SAM のデプロイ ステップに追加します。これを環境ごとに実行します。以下の 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」の機能フラグ値を取得します。これは username という単一のパラメーターを取得します。

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 チームのタイプに関する詳細や、アトラシアンの DevOps についての継続的な更新をご覧ください。

DevOps のイラスト

DevOps コミュニティ

DevOps のイラスト

DevOps ラーニング パス

マップのイラスト

無料で始める

DevOps ニュースレター購読

Thank you for signing up