フィーチャー トグルのデプロイ

このクイックスタートでは、App Lifecycle Manager でフィーチャー トグルを作成、ロールアウト、使用する方法について説明します。

このクイックスタートでは、フラグ プロバイダをインストールして構成する方法と、App Lifecycle Manager のフィーチャー トグルを使用して基本的なフィーチャー トグルを行う方法について説明します。

始める前に

  1. ログイン Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、 新しいアカウントを登録します

  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the App Lifecycle Manager, Artifact Registry, Infrastructure Manager, Developer Connect, Cloud Build, Cloud Storage, Cloud Run and SaaS Config APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  5. Create a service account:

    1. Ensure that you have the Create Service Accounts IAM role (roles/iam.serviceAccountCreator) and the Project IAM Admin role (roles/resourcemanager.projectIamAdmin). Learn how to grant roles.
    2. In the Google Cloud console, go to the Create service account page.

      Go to Create service account
    3. Select your project.
    4. In the Service account name field, enter a name. The Google Cloud console fills in the Service account ID field based on this name.

      In the Service account description field, enter a description. For example, Service account for quickstart.

    5. Click Create and continue.
    6. Grant the Project > Owner role to the service account.

      To grant the role, find the Select a role list, then select Project > Owner.

    7. Click Continue.
    8. Click Done to finish creating the service account.

  6. Google Cloud CLI をインストールします。

  7. 外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。

  8. gcloud CLI を初期化するには、次のコマンドを実行します:

    gcloud init
  9. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  10. Verify that billing is enabled for your Google Cloud project.

  11. Enable the App Lifecycle Manager, Artifact Registry, Infrastructure Manager, Developer Connect, Cloud Build, Cloud Storage, Cloud Run and SaaS Config APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  12. Create a service account:

    1. Ensure that you have the Create Service Accounts IAM role (roles/iam.serviceAccountCreator) and the Project IAM Admin role (roles/resourcemanager.projectIamAdmin). Learn how to grant roles.
    2. In the Google Cloud console, go to the Create service account page.

      Go to Create service account
    3. Select your project.
    4. In the Service account name field, enter a name. The Google Cloud console fills in the Service account ID field based on this name.

      In the Service account description field, enter a description. For example, Service account for quickstart.

    5. Click Create and continue.
    6. Grant the Project > Owner role to the service account.

      To grant the role, find the Select a role list, then select Project > Owner.

    7. Click Continue.
    8. Click Done to finish creating the service account.

  13. Google Cloud CLI をインストールします。

  14. 外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。

  15. gcloud CLI を初期化するには、次のコマンドを実行します:

    gcloud init
  16. SaaS サービスを作成します。このクイックスタートを完了するには、SaaS サービスが必要です。 SaaS サービスを作成する方法の詳細については、SaaS サービスの作成 をご覧ください

App Lifecycle Manager サービス アカウントに権限を付与する

App Lifecycle Manager API を有効にすると、App Lifecycle Manager はサービス アカウントを作成します。このサービス アカウントは service-PROJECT-NUMBER@gcp-sa-saasservicemgmt.iam.gserviceaccount.com と呼ばれます。ここで、PROJECT-NUMBER はプロジェクト番号です。

次のコマンドを実行して、このサービス アカウントに必要な権限を付与します。

gcloud projects add-iam-policy-binding `PROJECT_ID` \
    --member="serviceAccount:service-<var>`PROJECT_NUMBER`</var>@gcp-sa-saasservicemgmt.iam.gserviceaccount.com" \
    --role="roles/saasservicemgmt.serviceAgent"

次のように置き換えます。

  • PROJECT_ID: プロジェクト ID を表す文字列識別子。
  • PROJECT_NUMBER: プロジェクトの番号。

リファレンス ドキュメントの場所

このサービス アカウントは、ユニットのプロビジョニングなど、さまざまなタスクを代行します。

Artifact Registry にリポジトリを作成する

App Lifecycle Manager を使用するには、Artifact Registry にリポジトリが必要です。このリポジトリを作成するには、ターミナルで次のコマンドを実行します。

gcloud artifacts repositories create flags-quickstart \
    --repository-format=docker \
    --location=us-central1

このリポジトリには、ユニットのプロビジョニング方法を記述したブループリント(パッケージ化された Terraform ファイル)が含まれます。

フィーチャー トグル アプリケーション ブループリントを作成する

フィーチャー トグルを読み取る Python スクリプトを作成し、それを使用して Docker イメージをビルドして push します。

  1. Docker ビルド コンテキスト用の alm_docker という名前のディレクトリを作成します。

  2. alm_docker ディレクトリに、次のスニペットを含む flags.py ファイルを作成します。

    import google.auth.transport.grpc
    import google.auth.transport.requests
    import grpc
    import logging
    import time
    import os
    import sys
    from flask import Flask, jsonify
    
    from openfeature import api
    from openfeature.provider import ProviderEvent, ProviderStatus
    from openfeature.contrib.provider.flagd import FlagdProvider
    from openfeature.contrib.provider.flagd.config import ResolverType
    
    # --- Flask App Setup ---
    app = Flask(__name__)
    
    # --- Logging Setup ---
    logging.basicConfig(stream=sys.stdout) # Log to stdout for Cloud Run
    log = logging.getLogger(__name__)
    log.setLevel(logging.INFO) # Use INFO or DEBUG as needed
    
    # --- OpenFeature/Flagd Setup ---
    FLAG_KEY = "quickstart-flag"
    DEFAULT_FLAG_VALUE = False
    
    # Check for necessary environment variable
    provider_id = os.environ.get("FLAGD_SOURCE_PROVIDER_ID")
    if not provider_id:
      log.critical("FATAL: FLAGD_SOURCE_PROVIDER_ID environment variable not set.")
      sys.exit("FLAGD_SOURCE_PROVIDER_ID not set") # Exit if critical config is missing
    
    log.info(f"Initializing OpenFeature provider for ID: {provider_id}")
    
    def add_x_goog_request_params_header(config_name):
      return lambda context, callback: callback([("x-goog-request-params", f'name={config_name}')], None)
    
    try:
      # Configure gRPC credentials for Google Cloud service
      configservice_credentials = grpc.composite_channel_credentials(
          grpc.ssl_channel_credentials(),
          grpc.metadata_call_credentials(
              google.auth.transport.grpc.AuthMetadataPlugin(
                  google.auth.default()[0], # Get just the credentials from the tuple
                  google.auth.transport.requests.Request()
              )
          ),
          grpc.metadata_call_credentials(
              add_x_goog_request_params_header(provider_id)
          )
      )
    
      # Set up the Flagd provider to connect to SaaS Config service
      # Using IN_PROCESS resolver type as recommended for direct gRPC connection
      provider = FlagdProvider(
          resolver_type=ResolverType.IN_PROCESS,
          host="saasconfig.googleapis.com",
          port=443,
          sync_metadata_disabled=True, # Important when using IN_PROCESS with direct service
          provider_id=provider_id,
          channel_credentials=configservice_credentials
      )
      api.set_provider(provider)
      client = api.get_client()
    
      initial_flag_value = client.get_boolean_value(FLAG_KEY, DEFAULT_FLAG_VALUE)
      log.info(f"***** STARTUP FLAG CHECK ***** Flag '{FLAG_KEY}' evaluated to: {initial_flag_value}")
    
    except Exception as e:
      log.critical(f"FATAL: Failed to initialize OpenFeature provider: {e}", exc_info=True)
      # Depending on the desired behavior, you might exit or let Flask start
      # but log the critical failure. Exiting might be safer in production.
      sys.exit(f"Provider initialization failed: {e}")
    
    # --- Flask Routes ---
    @app.route('/')
    def home():
      """Endpoint to check the feature flag's value."""
      log.info(f"Request received for flag: {FLAG_KEY}")
      try:
          # Get the flag value. Use the client initialized earlier.
          # The default value (DEFAULT_FLAG_VALUE) is returned if the flag isn't found
          # or if the provider isn't ready/errors occur during evaluation.
          flag_value = client.get_boolean_value(FLAG_KEY, DEFAULT_FLAG_VALUE)
          log.info(f"Evaluated flag '{FLAG_KEY}': {flag_value}")
          return jsonify({
              "flag_key": FLAG_KEY,
              "value": flag_value,
          })
      except Exception as e:
          log.error(f"Error evaluating flag '{FLAG_KEY}': {e}", exc_info=True)
          # Return an error response but keep the server running
          return jsonify({
              "error": f"Failed to evaluate flag {FLAG_KEY}",
              "details": str(e),
          }), 500
    
    if __name__ == '__main__':
      port = int(os.environ.get('PORT', 8080))
      log.info(f"Starting Flask server on port {port}")
      app.run(host='0.0.0.0', port=port)
    

    この Python スクリプトは、App Lifecycle Manager ユニットで Docker イメージとして実行されているアプリケーション内のフィーチャー トグルにアクセスする方法を示しています。標準の OpenFeature の原則を使用して、App Lifecycle Manager のフィーチャー トグル構成サービス(saasconfig.googleapis.com)と統合します。

  3. alm_docker ディレクトリに、次のスニペットを含む requirements.txt という名前のテキスト ファイルを作成します。

    google-auth
    grpcio>=1.49.1,<2.0.0dev
    openfeature-sdk==0.8.0
    openfeature-provider-flagd==0.2.2
    requests 
    typing_extensions
    Flask>=2.0
    
  4. alm_docker ディレクトリの Dockerfile に次を追加します。

    FROM python:3.11-slim
    
    WORKDIR /app
    
    COPY requirements.txt .
    
    RUN pip install --no-cache-dir -r requirements.txt
    COPY flags.py .
    CMD ["python", "flags.py"]
    
  5. ローカル環境で次のコマンドを実行して、Docker イメージをビルドして push します。

    export DOCKER_REGISTRY="us-central1-docker.pkg.dev/PROJECT_ID/flags-quickstart"
    export FULL_IMAGE_PATH="${DOCKER_REGISTRY}/flags-quickstart:latest"
    docker build -t "${FULL_IMAGE_PATH}" .
    docker push "${FULL_IMAGE_PATH}"
    

    次のように置き換えます。

    • PROJECT_ID: プロジェクト ID を表す文字列識別子。
  6. Docker 環境に alm_terraform ディレクトリを作成します。

  7. alm_terraform に次のファイルを作成します。

    main.tf

    locals {
      config_path = "projects/${var.system_unit_project}/locations/${var.system_unit_location}/featureFlagsConfigs/${var.system_unit_name}"
      docker_image_path = "${var.system_unit_location}-docker.pkg.dev/${var.system_unit_project}/${var.docker_repo_name}/${var.docker_tag}"
    }
    
    provider "google" {
      project = var.system_unit_project
      region  = var.system_unit_location
    }
    
    resource "google_cloud_run_service" "flags_quickstart_service" {
      name     = var.cloud_run_service_name
      location = var.system_unit_location
      project  = var.system_unit_project
    
      template {
        spec {
          containers {
            image = local.docker_image_path 
    
            env {
              name  = "FLAGD_SOURCE_PROVIDER_ID"
              value = local.config_path
            }
          }
          service_account_name = var.actuation_sa
        }
      }
    }
    

    variables.tf

    variable "actuation_sa" {
      description = "Actuation SA"
      type        = string
    }
    
    variable "system_unit_project" {
      description = "Project id - variable set by App Lifecycle Manager"
      type        = string
    }
    
    variable "system_unit_location" {
      description = "Location - variable set by App Lifecycle Manager"
      type        = string
    }
    
    variable "system_unit_name" {
      description = "Unit name- variable set by App Lifecycle Manager"
      type = string
    }
    
    variable "docker_repo_name" {
      description = "The name of the Artifact Registry repository where the Docker image is stored."
      type        = string
      default     = "flags-quickstart"
    }
    
    variable "docker_tag" {
      description = "The tag of the Docker image to deploy."
      type        = string
      default     = "flags-quickstart:latest"
    }
    
    variable "cloud_run_service_name" {
      description = "Name for the Cloud Run service to be created."
      type        = string
      default     = "saas-flags-quickstart-svc"
    }
    
  8. alm_terraform ディレクトリで次のコマンドを実行して、Terraform ブループリント ファイルをパッケージ化します。

    zip terraform-files.zip main.tf variables.tf
    

アプリケーション ブループリントを使用してユニットを作成する

フィーチャー トグルを使用するアプリケーション ブループリントを作成したら、App Lifecycle Manager ユニットの種類(flags-unit-kind)を作成し、この種類のユニット(flags-quickstart-unit)を作成する必要があります。

ユニットとユニットの種類の詳細については、デプロイのユニットのモデル化とパッケージ化 をご覧ください

アプリケーション ブループリントを使用してユニットを作成するには、次の gcloud CLI の手順を行います。

  1. Terraform 構成を OCI イメージ(ブループリント)としてパッケージ化するには、Terraform ディレクトリに Dockerfile という名前のファイルを作成します。

    # syntax=docker/dockerfile:1-labs
    FROM scratch
    COPY --exclude=Dockerfile --exclude=.git --exclude=.gitignore . /
    
  2. Dockerfile をビルドして Artifact Registry リポジトリに push します。

    IMAGE_NAME="us-central1-docker.pkg.dev/PROJECT_ID/flags-quickstart/flags-quickstart-blueprint:latest"
    ENGINE_TYPE=inframanager
    ENGINE_VERSION=1.5.7
    
    docker buildx build -t $IMAGE_NAME \
      --push \
      --annotation "com.easysaas.engine.type=$ENGINE_TYPE" \
      --annotation "com.easysaas.engine.version=$ENGINE_VERSION" \
      --provenance=false .
    

    次のように置き換えます。

    • PROJECT_ID: プロジェクト ID を表す文字列識別子。
  3. flags-unit-kind リソースと flags-release リソースを作成します。

    # Create unit kind
    gcloud beta app-lifecycle-manager unit-kinds create flags-unit-kind \
      --project=PROJECT_ID \
      --location=global \
      --saas=flags-quickstart-saas-offering
    
    # Create release referencing the Blueprint image
    gcloud beta app-lifecycle-manager releases create flags-release \
      --project=PROJECT_ID \
      --location=global \
      --unit-kind=flags-unit-kind \
      --blueprint-package=$IMAGE_NAME
    

    次のように置き換えます。

    • PROJECT_ID: プロジェクト ID を表す文字列識別子。
  4. flags-quickstart-unit ユニットを作成します。

    gcloud beta app-lifecycle-manager units create flags-quickstart-unit \
      --project=PROJECT_ID \
      --location=us-central1 \
      --unit-kind=flags-unit-kind \
      --management-mode=user
    

    次のように置き換えます。

    • PROJECT_ID: プロジェクト ID を表す文字列識別子。

フィーチャー トグルを作成してプロビジョニングする

プロビジョニングされたユニットで App Lifecycle Manager のフィーチャー トグルを使用するには、フィーチャー トグル リソースを作成し、ロールアウトを開始して構成をユニットに伝播する必要があります。

次のコマンドを実行して、quickstart-flag フィーチャー トグルを作成してプロビジョニングします。

  1. 環境で次の変数を定義します。

    export FLAG_ID="quickstart-flag"
    export FLAG_KEY="quickstart-flag"
    export SAAS_OFFERING_ID="flags-quickstart-saas-offering"
    export UNIT_KIND_ID="flags-unit-kind"
    export UNIT_ID="flags-quickstart-unit"
    export ROLLOUT_KIND_ID="flags-quickstart-rollout-kind"
    export ROLLOUT_ID="flags-quickstart-rollout"
    
  2. フィーチャー トグル リソースを作成します。

    gcloud beta app-lifecycle-manager flags create ${FLAG_ID} \
      --project=${PROJECT_ID} \
      --key=${FLAG_KEY} \
      --flag-value-type=BOOL \
      --location=global \
      --unit-kind=${UNIT_KIND_ID}
    
  3. リビジョンを作成します。

    export FLAG_REVISION_ID="${FLAG_ID}-rev1"
    gcloud beta app-lifecycle-manager flags revisions create ${FLAG_REVISION_ID} \
      --project=${PROJECT_ID} \
      --flag=${FLAG_ID} \
      --location=global
    
  4. リリースを作成します。

    export FLAG_RELEASE_ID="${FLAG_ID}-rel1"
    gcloud beta app-lifecycle-manager flags releases create ${FLAG_RELEASE_ID} \
      --project=${PROJECT_ID} \
      --flag-revisions=${FLAG_REVISION_ID} \
      --unit-kind=${UNIT_KIND_ID} \
      --location=global
    
  5. ロールアウトの種類を作成します。

    gcloud beta app-lifecycle-manager rollout-kinds create ${ROLLOUT_KIND_ID} \
      --project=${PROJECT_ID} \
      --unit-kind=${UNIT_KIND_ID} \
      --rollout-orchestration-strategy=Google.Cloud.Simple.AllAtOnce \
      --location=global
    
  6. ロールアウトを作成します。

    gcloud beta app-lifecycle-manager rollouts create ${ROLLOUT_ID} \
      --project=${PROJECT_ID} \
      --flag-release=${FLAG_RELEASE_ID} \
      --rollout-kind=${ROLLOUT_KIND_ID} \
      --location=global
    

ロールアウトのステータスは次の方法でモニタリングできます。

gcloud beta app-lifecycle-manager rollouts describe ${ROLLOUT_ID} --project=${PROJECT_ID} --location=global

実行中のサービスでフラグの値を確認する

App Lifecycle Manager ユニットが Cloud Run サービスを正常にプロビジョニングしたら、アプリケーションが実行され、フィーチャー トグルが正しく評価されていることを確認できます。

  1. コンソールで [Cloud Run] に移動します。 Google Cloud

    Cloud Run に移動

  2. us-central1 リージョンで saas-flags-quickstart-svc という名前のサービスを見つけます。saas-flags-quickstart-svc の横にチェックマークが表示されている場合は、正常に実行されています。

  3. saas-flags-quickstart-svc をクリックして詳細を表示します。

    saas-flags-quickstart-svc に移動

  4. [ログ] タブを選択します。

    1. ログエントリで、次のようなメッセージを探します。

      INFO:__main__:***** STARTUP FLAG CHECK ***** Flag 'quickstart-flag' evaluated to: false
      

      これにより、アプリケーションが起動し、SaaS Config サービスに接続して、quickstart-flag を評価したことが確認できます。

  5. パブリック エンドポイントにアクセスするには、[ネットワーキング] タブをクリックします。

    1. [エンドポイント] セクションに表示されているパブリック URL を見つけます。
    2. URL をクリックしてブラウザで開くか、curl などのツールを使用して ターミナルからアクセスします(curl YOUR_SERVICE_URL、例)。
    3. URL にアクセスするたびに、サービスはフィーチャー トグルを評価し、現在の値を JSON 形式で返します。次に例を示します。

      {
        "flag_key": "quickstart-flag",
        "value": false
      }
      

App Lifecycle Manager で管理されるフィーチャー トグルを読み取る サービスが正常にデプロイされました。 Google Cloud フラグの値を変更して新しいロールアウトを作成し、アプリケーションが変更を反映していることを確認できます。

クリーンアップ

このページで使用したリソースについて、 Google Cloud アカウントに課金されないようにするには、 次の手順を実施します。

省略可: プロジェクトを削除する

新しい Google Cloud プロジェクトにソリューションをデプロイし、その プロジェクトが不要になった場合は、次の手順で削除します。

  1. Google Cloud コンソールで [リソースの管理] ページに移動します。

    [リソースの管理] に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. プロンプトでプロジェクト ID を入力し、[シャットダウン] をクリックします。

次のステップ