Utilizzare i flag funzionalità autonomi

Scopri come utilizzare i flag funzionalità di App Lifecycle Manager come servizio autonomo per gestire la disponibilità delle funzionalità nelle tue applicazioni, anche se queste non sono sottoposte a deployment o gestite da App Lifecycle Manager.

Introduzione

Questa guida rapida mostra come utilizzare le funzionalità di flag funzionalità e di implementazione controllata di App Lifecycle Manager senza dover utilizzare App Lifecycle Manager per il provisioning dell'infrastruttura (ad esempio, il deployment di VM o servizi Cloud Run utilizzando i blueprint di Terraform). Questo approccio è ideale se gestisci l'infrastruttura delle applicazioni in modo indipendente, ma vuoi utilizzare App Lifecycle Manager per la gestione sicura dei flag funzionalità.

In questo approccio autonomo:

  1. Modella il tuo sistema con risorse App Lifecycle Manager leggere: crea Units di App Lifecycle Manager per rappresentare i componenti dell'infrastruttura esistente (ad es. un deployment di microservizi specifico, un ambiente tenant, una singola istanza binaria). Queste unità fungono esclusivamente da target per le configurazioni dei flag e non comportano il deployment dell'infrastruttura utilizzando i blueprint di App Lifecycle Manager.
  2. Definisci e distribuisci i flag: utilizza l'API App Lifecycle Manager o Google Cloud la console per creare flag funzionalità. Gestisci il loro ciclo di vita utilizzando Rollouts di App Lifecycle Manager per garantire una propagazione sicura e graduale delle modifiche alla configurazione delle Units modellate. In questo modo, puoi garantire coerenza operativa e sicurezza anche quando gestisci solo i flag.
  3. Integra con l'applicazione: utilizza l'SDK OpenFeature con il provider flagd nel codice dell'applicazione (in esecuzione ovunque: localmente, on-premise, cloud autogestito). Configuralo per connetterti al servizio di flag di App Lifecycle Manager (saasconfig.googleapis.com), autenticarti e identificarti utilizzando il nome della risorsa Unit corrispondente per recuperare i valori dei flag corretti.

Questo approccio ti consente di usufruire della distribuzione di flag gestita e sicura senza modificare le pipeline di deployment o gli strumenti di gestione dell'infrastruttura esistenti.

I flag funzionalità di App Lifecycle Manager sono in anteprima privata. L'accesso richiede l'inserimento nella lista consentita. Per richiedere l'accesso per la tua organizzazione o il tuo progetto, compila questo modulo.

Questa guida rapida utilizza un'applicazione Python di base eseguita localmente per dimostrare l'accesso ai flag, simulando l'integrazione dell'applicazione esistente.

Obiettivi

  • Configura un nuovo Google Cloud progetto o utilizzane uno esistente.
  • Abilita le API richieste (App Lifecycle Manager e SaaS Config).
  • Concedi le autorizzazioni Identity and Access Management necessarie per la creazione delle risorse e la lettura dei flag.
  • Crea risorse App Lifecycle Manager minime (offerta SaaS, tipo di unità, unità) per modellare un componente dell'applicazione senza eseguire il deployment dell'infrastruttura.
  • Definisci una risorsa flag funzionalità associata al tipo di unità.
  • Crea un meccanismo di implementazione dei flag (tipo di implementazione) che definisca la strategia di distribuzione.
  • Distribuisci la configurazione iniziale dei flag utilizzando un'implementazione di App Lifecycle Manager.
  • Esegui localmente un'applicazione Python di esempio che si connette al servizio di flag di App Lifecycle Manager e valuta il flag per l'unità modellata.
  • Aggiorna il valore del flag, crea una nuova release del flag e distribuisci la modifica.
  • Verifica che l'applicazione recuperi il valore del flag aggiornato.

Prima di iniziare

  1. Accedi al tuo Account Google.

    Se non ne hai già uno, registrati per creare un nuovo account.

  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 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. Installa Google Cloud CLI.

  6. Se utilizzi un provider di identità (IdP) esterno, devi prima accedere a gcloud CLI con la tua identità federata.

  7. Per inizializzare gcloud CLI, esegui questo comando:

    gcloud init
  8. 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

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

  10. Enable the App Lifecycle Manager 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

  11. Installa Google Cloud CLI.

  12. Se utilizzi un provider di identità (IdP) esterno, devi prima accedere a gcloud CLI con la tua identità federata.

  13. Per inizializzare gcloud CLI, esegui questo comando:

    gcloud init
  14. Installa Python: assicurati di aver installato Python 3.7 o versioni successive sulla macchina su cui eseguirai l'applicazione di esempio. Ti serve anche pip per installare le dipendenze.
    python --version
    pip --version
  15. Autentica gcloud per le credenziali predefinite dell'applicazione (ADC): lo script Python locale utilizza ADC per l'autenticazione ai Google Cloud servizi. Accedi utilizzando il tuo account utente:
    gcloud auth application-default login
  16. Concedi le autorizzazioni per l'identità dell'applicazione: la tua applicazione deve avere l'autorizzazione per leggere le configurazioni dei flag dal servizio SaaS Config. Concedi il ruolo `roles/saasconfig.viewer` all'identità che l'applicazione utilizzerà. Per questa guida rapida che utilizza ADC localmente con il tuo account utente, concedi il ruolo al tuo indirizzo email:
        gcloud projects add-iam-policy-binding PROJECT_ID \
            --member="user:YOUR_EMAIL_ADDRESS" \
            --role="roles/saasconfig.viewer"
    Sostituisci PROJECT_ID con l'ID progetto Google Cloud e YOUR_EMAIL_ADDRESS con l'indirizzo email associato al tuo accesso alla CLI.

Crea risorse App Lifecycle Manager minime

Anche se non eseguiamo il deployment dell'infrastruttura con App Lifecycle Manager, abbiamo bisogno di alcune risorse per organizzare, indirizzare e distribuire i nostri flag in modo sicuro. Queste risorse rappresentano i componenti dell'applicazione esistenti in App Lifecycle Manager.

  1. Definisci le variabili: imposta le variabili di ambiente per i nomi e le località delle risorse.

    export PROJECT_ID="your-project-id"
    export SAAS_OFFERING_ID="standalone-flags-saas"
    export UNIT_KIND_ID="standalone-app-kind"
    export UNIT_ID="my-app-instance-01"
    export LOCATION_1="us-central1" # Example region where your app instance conceptually resides
    # Add more locations if your app components span multiple regions
    # export LOCATION_2="europe-west1"
    
  2. Crea un'offerta SaaS: funge da contenitore di primo livello per la configurazione del servizio, inclusi i flag.

    gcloud beta app-lifecycle-manager saas create ${SAAS_OFFERING_ID} \
        --project=${PROJECT_ID} \
        --location=global \
        --locations=name=${LOCATION_1} # Add --locations=name=${LOCATION_2} if using more regions
    
     gcloud beta app-lifecycle-manager saas create ${SAAS_OFFERING_ID} \
        --project=${PROJECT_ID} \
        --location=${LOCATION_1} \
        --locations=name=${LOCATION_1} 
    
  3. Crea un tipo di unità: definisce il tipo di componente che stai modellando. È fondamentale che non forniamo un blueprint perché non gestiamo l'infrastruttura.

    gcloud beta app-lifecycle-manager unit-kinds create ${UNIT_KIND_ID} \
      --project=${PROJECT_ID} \
      --location=global \
      --saas=${SAAS_OFFERING_ID}
    
    gcloud beta app-lifecycle-manager unit-kinds create ${UNIT_KIND_ID} \
      --project=${PROJECT_ID} \
      --location=${LOCATION_1} \
      --saas=${SAAS_OFFERING_ID}
    
  4. Crea un'unità: rappresenta un'istanza specifica dell'applicazione.

    gcloud beta app-lifecycle-manager units create ${UNIT_ID} \
      --project=${PROJECT_ID} \
      --unit-kind=${UNIT_KIND_ID} \
      --location=${LOCATION_1} 
    

Definisci e implementa il flag funzionalità

Ora crea il flag funzionalità effettivo e utilizza il meccanismo di implementazione di App Lifecycle Manager per rendere disponibile la sua configurazione alle unità che hai creato.

  1. Definisci le variabili dei flag:

    export FLAG_ID="standalone-flag-01"
    export FLAG_KEY="enable-beta-feature" 
    
  2. Crea la risorsa flag, la revisione e la release:

    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} \
    
    export FLAG_REVISION_ID_1="${FLAG_ID}-rev1"
    gcloud beta app-lifecycle-manager flags revisions create ${FLAG_REVISION_ID_1} \
      --project=${PROJECT_ID} \
      --flag=${FLAG_ID} \
      --location=global
    
    export FLAG_RELEASE_ID_1="${FLAG_ID}-rel1"
    gcloud beta app-lifecycle-manager flags releases create ${FLAG_RELEASE_ID_1} \
      --project=${PROJECT_ID} \
      --flag-revisions=${FLAG_REVISION_ID_1} \
      --unit-kind=${UNIT_KIND_ID} \
      --location=global
    
  3. Crea un tipo di implementazione: definisci la strategia per la distribuzione delle modifiche dei flag.

    export ROLLOUT_KIND_ID="standalone-flags-rollout-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
    
  4. Crea l'implementazione: avvia il processo di distribuzione.

    export ROLLOUT_ID_1="${FLAG_ID}-rollout1"
    
    gcloud beta app-lifecycle-manager rollouts create ${ROLLOUT_ID_1} \
      --project=${PROJECT_ID} \
      --flag-release=${FLAG_RELEASE_ID_1} \
      --rollout-kind=${ROLLOUT_KIND_ID} \
      --location=global
    
  5. Monitora l'implementazione: assicurati che il deployment vada a buon fine prima di procedere.

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

Configura l'infrastruttura autonoma

In una configurazione autonoma, gestisci il tuo hosting delle applicazioni (ad es. Cloud Run o GKE) e utilizzi App Lifecycle Manager esclusivamente per la sincronizzazione della configurazione. Il codice dell'applicazione rimane standard tra i deployment; richiede solo la presenza della variabile di ambiente FLAGD_SOURCE_PROVIDER_ID al runtime per connettersi al servizio SaaS Config.

Puoi mappare le definizioni delle unità di App Lifecycle Manager nelle definizioni di deployment Terraform standard passando il percorso costruito come variabile di ambiente.

  1. Definisci l'infrastruttura: mappa il percorso nel modello di deployment (ad es. standalone.tf).

    variable "project_id" { type = string }
    variable "region"     { type = string }
    variable "unit_id"    { type = string }
    
    resource "google_cloud_run_v2_service" "standalone_app" {
      name     = "my-standalone-service"
      location = var.region
    
      template {
        containers {
          image = "us-central1-docker.pkg.dev/my-project/my-repo/my-image:latest"
    
          env {
            name  = "FLAGD_SOURCE_PROVIDER_ID"
            value = "projects/${var.project_id}/locations/${var.region}/featureFlagsConfigs/${var.unit_id}"
          }
        }
      }
    }
    
  2. Definisci i valori delle variabili: fornisci i parametri dell'unità di configurazione in un file di variabili associato (ad es. terraform.tfvars).

    project_id = "PROJECT_ID"
    region     = "LOCATION_1"
    unit_id    = "UNIT_ID"
    

Integra ed esegui l'applicazione di esempio

Esegui un'applicazione Python di esempio localmente per connetterti al servizio di flag di App Lifecycle Manager utilizzando le configurazioni delle unità modellate.

  1. Crea la directory e i file del progetto:

    mkdir saas_flags_standalone_app
    cd saas_flags_standalone_app
    

    Crea 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
    

    Installa le dipendenze:

    pip install -r requirements.txt
    
  2. Crea app.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.contrib.provider.flagd import FlagdProvider
    from openfeature.contrib.provider.flagd.config import ResolverType
    
    app = Flask(__name__)
    
    logging.basicConfig(stream=sys.stdout, level=logging.INFO,
                        format='%(asctime)s - %(levelname)s - %(message)s')
    log = logging.getLogger(__name__)
    
    FLAG_KEY = os.environ.get("FLAG_KEY", "enable-beta-feature")
    DEFAULT_FLAG_VALUE = False 
    
    # CRITICAL: Read the Unit resource name from environment variable.
    # This identifies the application instance to the flag service.
    provider_id = os.environ.get("FLAGD_SOURCE_PROVIDER_ID")
    if not provider_id:
        log.critical("FATAL: FLAGD_SOURCE_PROVIDER_ID not set.")
        sys.exit("FLAGD_SOURCE_PROVIDER_ID not set")
    
    log.info(f"Initializing OpenFeature provider for Unit: {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:
        credentials, detected_project_id = google.auth.default(
            scopes=["https://www.googleapis.com/auth/cloud-platform"] 
        )
        auth_req = google.auth.transport.requests.Request() 
    
        configservice_credentials = grpc.composite_channel_credentials(
            grpc.ssl_channel_credentials(), 
            grpc.metadata_call_credentials( 
                google.auth.transport.grpc.AuthMetadataPlugin(credentials, auth_req)
            ),
            grpc.metadata_call_credentials(
                add_x_goog_request_params_header(provider_id)
            )
        )
    
        provider = FlagdProvider(
            resolver_type=ResolverType.IN_PROCESS,    
            host="saasconfig.googleapis.com",         
            port=443,                                 
            sync_metadata_disabled=True,              
            provider_id=provider_id,                  
            channel_credentials=configservice_credentials 
        )
    
        api.set_provider(provider)
        client = api.get_client()
    
        time.sleep(5)
    
        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)
        sys.exit(f"Provider initialization failed: {e}")
    
    @app.route('/')
    def home():
        log.info(f"Request received for endpoint '/', evaluating flag: {FLAG_KEY}")
        try:
            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,
                "provider_id": provider_id 
            })
        except Exception as e:
            log.error(f"Error evaluating flag '{FLAG_KEY}': {e}", exc_info=True)
            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 web server on host 0.0.0.0 port {port}")
        app.run(host='0.0.0.0', port=port)
    
  3. Esegui l'applicazione:

    export FLAGD_SOURCE_PROVIDER_ID="projects/${PROJECT_ID}/locations/${LOCATION_1}/featureFlagsConfigs/${UNIT_ID}"
    python app.py
    
  4. Verifica il valore iniziale del flag: esegui un controllo sull'endpoint locale in un terminale secondario.

    curl http://localhost:8080
    

Aggiorna il flag e distribuisci la modifica

Modifica lo stato di runtime della definizione del flag e distribuisci l'aggiornamento ai target connessi.

  1. Aggiorna la risorsa flag:

    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}
    
    export FLAG_REVISION_ID_2="${FLAG_ID}-rev2"
    gcloud beta app-lifecycle-manager flags revisions create ${FLAG_REVISION_ID_2} \
      --project=${PROJECT_ID} \
      --flag=${FLAG_ID} \
      --location=global
    
    export FLAG_RELEASE_ID_2="${FLAG_ID}-rel2"
    gcloud beta app-lifecycle-manager flags releases create ${FLAG_RELEASE_ID_2} \
      --project=${PROJECT_ID} \
      --flag-revisions=${FLAG_REVISION_ID_2} \
      --unit-kind=${UNIT_KIND_ID} \
      --location=global
    
  2. Crea una nuova implementazione per l'aggiornamento:

    export ROLLOUT_ID_2="${FLAG_ID}-rollout2"
    
    gcloud beta app-lifecycle-manager rollouts create ${ROLLOUT_ID_2} \
      --project=${PROJECT_ID} \
      --flag-release=${FLAG_RELEASE_ID_2} \
      --rollout-kind=${ROLLOUT_KIND_ID} \
      --location=global
    
  3. Monitora la nuova implementazione:

    gcloud beta app-lifecycle-manager rollouts describe ${ROLLOUT_ID_2} \
      --project=${PROJECT_ID} \
      --location=global 
    
  4. Verifica la modifica nell'applicazione in esecuzione:

    curl http://localhost:8080
    

Libera spazio

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

  1. Premi Ctrl+C nel terminale in cui è in esecuzione app.py per arrestare l'applicazione Python locale.
  2. Imposta lo stato del flag.
  3. Crea una nuova implementazione per rimuovere i flag obsoleti.
  4. Al termine dell'implementazione e dopo la rimozione dei flag obsoleti, elimina le risorse App Lifecycle Manager:

    gcloud beta app-lifecycle-manager rollouts delete ${ROLLOUT_ID_1} --project=${PROJECT_ID} --location=global --quiet 
    gcloud beta app-lifecycle-manager rollouts delete ${ROLLOUT_ID_2} --project=${PROJECT_ID} --location=global --quiet 
    gcloud beta app-lifecycle-manager rollout-kinds delete ${ROLLOUT_KIND_ID} --project=${PROJECT_ID} --location=global --quiet 
    gcloud beta app-lifecycle-manager flags releases delete ${FLAG_RELEASE_ID_1} --project=${PROJECT_ID} --location=global --quiet 
    gcloud beta app-lifecycle-manager flags releases delete ${FLAG_RELEASE_ID_2} --project=${PROJECT_ID} --location=global --quiet 
    gcloud beta app-lifecycle-manager flags delete ${FLAG_ID} --project=${PROJECT_ID} --location=global --quiet 
    gcloud beta app-lifecycle-manager units delete ${UNIT_ID} --project=${PROJECT_ID} --location=${LOCATION_1} --quiet 
    gcloud beta app-lifecycle-manager unit-kinds delete ${UNIT_KIND_ID} --project=${PROJECT_ID} --location=global --quiet 
    gcloud beta app-lifecycle-manager unit-kinds delete ${UNIT_KIND_ID} --project=${PROJECT_ID} --location=${LOCATION_1} --quiet 
    gcloud beta app-lifecycle-manager saas delete ${SAAS_OFFERING_ID} --project=${PROJECT_ID} --location=global --quiet 
    gcloud beta app-lifecycle-manager saas delete ${SAAS_OFFERING_ID} --project=${PROJECT_ID} --location=${LOCATION_1} --quiet 
    
  5. Elimina la directory locale:

    cd ..
    rm -rf saas_flags_standalone_app
    

Passaggi successivi