部署功能旗標

本快速入門導覽課程說明如何使用 App Lifecycle Manager 建立、推出及使用功能標記。

在本快速入門導覽課程中,您將瞭解如何安裝及設定旗標供應器,並使用 App Lifecycle Manager 功能旗標執行基本功能旗標作業。

事前準備

  1. 登入 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. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 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. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 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 的字串 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 映像檔:

  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 指令碼示範如何存取應用程式中的功能旗標,該應用程式以 Docker 映像檔的形式,在 App Lifecycle Manager 裝置上執行。它會使用標準 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 映像檔:

    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 的字串 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
    

使用應用程式藍圖建立單元

建立使用功能旗標的應用程式藍圖後,您需要建立應用程式生命週期管理工具單元類型 (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 存放區:

    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 的字串 ID。
  3. 建立 flags-unit-kindflags-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 的字串 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 的字串 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. 建立推出作業 kind:

    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. 前往 Google Cloud 控制台的「Cloud Run」

    前往 Cloud Run

  2. us-central1 區域中找出名為 saas-flags-quickstart-svc 的服務。saas-flags-quickstart-svc 旁邊的勾號表示執行成功。

  3. 按一下 saas-flags-quickstart-svc 即可查看詳細資料。

    前往 saas-flags-quickstart-svc

  4. 選取 [Logs] (記錄) 分頁標籤。

    1. 在記錄項目中,尋找類似下列內容的訊息:

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

      這會確認應用程式已啟動、連線至 SaaS 設定服務,並評估 quickstart-flag

  5. 如要存取公開端點,請按一下「網路」分頁標籤。

    1. 在「端點」部分下方,找出列出的公開 URL
    2. 按一下網址即可在瀏覽器中開啟,或使用 curl 等工具從終端機存取 (例如 curl YOUR_SERVICE_URL)。
    3. 每次存取網址時,服務都會評估功能旗標,並以 JSON 格式傳回目前的值。例如:

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

您已成功部署 Google Cloud 服務,可讀取 App Lifecycle Manager 管理的功能旗標。您可以嘗試變更旗標的值,並建立新的推出作業,看看應用程式是否會採用這項變更。

清除所用資源

為了避免系統向您的 Google Cloud 帳戶收取本頁面所用資源的費用,請按照下列步驟操作。

(選用) 刪除專案

如果您是在新 Google Cloud 專案中部署解決方案,且現在已不再需要該專案,請完成下列步驟來刪除專案:

  1. 前往 Google Cloud 控制台的「Manage resources」(管理資源) 頁面。

    前往「Manage resources」(管理資源)

  2. 從專案清單中選取要刪除的專案,然後點選「Delete」(刪除)
  3. 收到提示時,請輸入專案 ID,然後點選「Shut down」(關閉)

後續步驟