Esegui il deployment dei flag di funzionalità

Questa guida rapida mostra come creare, eseguire il deployment e utilizzare i flag di funzionalità con App Lifecycle Manager.

In questa guida rapida imparerai a installare e configurare un provider di flag ed eseguire il flag di funzionalità di base utilizzando i flag di funzionalità di App Lifecycle Manager.

Prima di iniziare

  1. 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

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

  3. Enable the App Lifecycle Manager, Artifact Registry, Infrastructure Manager, Developer Connect, Cloud Build, Cloud Storage, Cloud Run and SaaS Config APIs, if any are not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

  4. 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.

  5. Install the Google Cloud CLI.

  6. Configure the gcloud CLI to use your federated identity.

    For more information, see Sign in to the gcloud CLI with your federated identity.

  7. To initialize the gcloud CLI, run the following command:

    gcloud init
  8. Crea un'offerta di app. Per completare questa guida rapida, è necessaria un'offerta di app. Per saperne di più su come creare un'offerta di app, consulta Crea un'offerta di app.

Concedi le autorizzazioni al account di servizio App Lifecycle Manager

Quando abiliti l'API App Lifecycle Manager, App Lifecycle Manager crea un service account. Questo account di servizio è denominato service-PROJECT-NUMBER@gcp-sa-saasservicemgmt., dove PROJECT-NUMBER è il numero del progetto.

Concedi a questo account di servizio le autorizzazioni richieste eseguendo questo comando:

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

Sostituisci:

  • PROJECT_ID: un identificatore di stringa che rappresenta l'ID progetto.
  • PROJECT_NUMBER: il numero del progetto.

Individuazione della documentazione di riferimento

Questo account di servizio agisce per tuo conto per varie attività, come il provisioning delle unità.

Crea un repository in Artifact Registry

Per utilizzare App Lifecycle Manager, devi avere un repository in Artifact Registry. Per creare questo repository, esegui questo comando nel terminale:

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

Questo repository conterrà un progetto (file Terraform pacchettizzati) che descrive come eseguire il provisioning delle unità.

Crea un progetto iniziale di applicazione per il flag di funzionalità

Crea uno script Python che legga un flag funzionalità e utilizzalo per creare ed eseguire il push di un'immagine Docker:

  1. Crea una directory denominata alm_docker per il contesto di build Docker.

  2. Nella directory alm_docker, crea il file flags.py con questo snippet:

    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)
    

    Questo script Python mostra come accedere ai flag di funzionalità all'interno della tua applicazione in esecuzione come immagine Docker su un'unità App Lifecycle Manager. Utilizza i principi OpenFeature standard per l'integrazione con il servizio di configurazione flag funzionalità di App Lifecycle Manager (saasconfig.googleapis.com).

  3. Crea un file di testo denominato requirements.txt nella directory alm_docker contenente questo snippet:

    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. Aggiungi Dockerfile alla directory alm_docker con:

    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. Esegui questo comando nel tuo ambiente locale per creare l'immagine Docker ed eseguirne il 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}"
    

    Sostituisci:

    • PROJECT_ID: un identificatore di stringa che rappresenta l'ID progetto.
  6. Nel tuo ambiente Docker, crea una directory alm_terraform.

  7. In alm_terraform, crea questi file:

    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. Nella directory alm_terraform, esegui questo comando per pacchettizzare i file del blueprint Terraform:

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

Utilizza il progetto dell'applicazione per creare un'unità

Dopo aver creato un progetto di applicazione che utilizza i flag di funzionalità, devi creare un tipo di unità App Lifecycle Manager (flags-unit-kind) e poi creare un'unità di questo tipo (flags-quickstart-unit).

Per ulteriori informazioni sulle unità e sui tipi di unità, consulta Unità di modello e pacchetto di un deployment.

Per utilizzare il progetto dell'applicazione per creare un'unità, segui questi passaggi di gcloud CLI:

  1. Per pacchettizzare la configurazione Terraform come immagine OCI (progetto), crea un file denominato Dockerfile nella directory Terraform:

    # syntax=docker/dockerfile:1-labs
    FROM scratch
    COPY --exclude=Dockerfile --exclude=.git --exclude=.gitignore . /
    
  2. Crea ed esegui il push di Dockerfile nel repository 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 .
    

    Sostituisci:

    • PROJECT_ID: un identificatore di stringa che rappresenta l'ID progetto.
  3. Crea la risorsa flags-unit-kind e 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
    

    Sostituisci:

    • PROJECT_ID: un identificatore di stringa che rappresenta l'ID progetto.
  4. Crea l'unità 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
    

    Sostituisci:

    • PROJECT_ID: un identificatore di stringa che rappresenta l'ID progetto.

Crea un flag funzionalità ed eseguine il provisioning

Prima che un flag funzionalità di App Lifecycle Manager possa essere utilizzato dall'unità di cui hai eseguito il provisioning, devi creare la risorsa flag funzionalità e avviare un'implementazione per propagare la configurazione all'unità.

Esegui i comandi per creare ed eseguire il provisioning del flag funzionalità quickstart-flag:

  1. Nel tuo ambiente, definisci queste variabili:

    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. Crea la risorsa flag funzionalità:

    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. Crea una revisione:

    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. Crea una release:

    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. Crea un tipo di implementazione:

    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. Crea l'implementazione:

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

Puoi monitorare lo stato dell'implementazione con:

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

Visualizza il valore del flag nel servizio in esecuzione

Dopo che l'unità App Lifecycle Manager ha eseguito il provisioning del servizio Cloud Run, puoi verificare che l'applicazione sia in esecuzione e che valuti correttamente il flag funzionalità:

  1. Nella console Google Cloud , vai a Cloud Run:

    Vai a Cloud Run

  2. Trova il servizio denominato saas-flags-quickstart-svc nella regione us-central1. Un segno di spunta accanto a saas-flags-quickstart-svc indica che l'esecuzione è andata a buon fine.

  3. Fai clic su saas-flags-quickstart-svc per visualizzarne i dettagli.

    Vai a saas-flags-quickstart-svc.

  4. Seleziona la scheda Log.

    1. Nelle voci di log, cerca un messaggio simile al seguente:

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

      Ciò conferma che l'applicazione è stata avviata, si è connessa al servizio SaaS Config e ha valutato quickstart-flag.

  5. Per accedere all'endpoint pubblico, fai clic sulla scheda Networking.

    1. Trova l'URL pubblico elencato nella sezione Endpoint.
    2. Fai clic sull'URL per aprirlo nel browser o utilizza uno strumento come curl per accedervi dal terminale (ad esempio curl YOUR_SERVICE_URL).
    3. Ogni volta che accedi all'URL, il servizio valuta il flag funzionalità e restituisce il suo valore corrente in formato JSON. Ad esempio:

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

Hai eseguito il deployment di un servizio Google Cloud che legge un flag funzionalità gestito da App Lifecycle Manager. Puoi sperimentare modificando il valore del flag e creando una nuova implementazione per vedere l'applicazione applicare la modifica.

Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questa pagina, segui questi passaggi.

(Facoltativo) Elimina il progetto

Se hai eseguito il deployment della soluzione in un nuovo progetto Google Cloud e non hai più bisogno del progetto, eliminalo completando i seguenti passaggi:

  1. Nella console Google Cloud , vai alla pagina Gestisci risorse.

    Vai a Gestisci risorse

  2. Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
  3. Al prompt, digita l'ID progetto, quindi fai clic su Chiudi.

Passaggi successivi