Funktions-Flags eigenständig verwenden

Hier erfahren Sie, wie Sie Funktions-Flags von App Lifecycle Manager als eigenständigen Dienst verwenden, um die Verfügbarkeit von Funktionen in Ihren Anwendungen zu verwalten, auch wenn diese Anwendungen nicht von App Lifecycle Manager bereitgestellt oder verwaltet werden.

Einführung

In dieser Kurzanleitung erfahren Sie, wie Sie die robusten Funktions-Flags und die kontrollierten Roll-out-Funktionen von App Lifecycle Manager verwenden, ohne App Lifecycle Manager für die Infrastrukturbereitstellung (z. B. die Bereitstellung von VMs oder Cloud Run-Diensten mit Terraform-Blueprints) verwenden zu müssen. Dieser Ansatz ist ideal, wenn Sie Ihre Anwendungsinfrastruktur unabhängig verwalten, aber App Lifecycle Manager für die sichere Verwaltung von Funktions-Flags verwenden möchten.

Bei diesem eigenständigen Ansatz gehen Sie so vor:

  1. System mit einfachen App Lifecycle Manager-Ressourcen modellieren: Erstellen Sie App Lifecycle Manager-Units, um Komponenten Ihrer vorhandenen Infrastruktur darzustellen (z.B. eine bestimmte Mikrodienstbereitstellung, eine Mandantenumgebung, eine einzelne Binärinstanz). Diese Einheiten dienen ausschließlich als Ziele für Flag-Konfigurationen und umfassen keine Bereitstellung von Infrastruktur mithilfe von App Lifecycle Manager-Blueprints.
  2. Flags definieren und verteilen: Verwenden Sie die App Lifecycle Manager API oder die Google Cloud Console, um Funktions-Flags zu erstellen. Verwalten Sie den Lebenszyklus mit App Lifecycle Manager Rollouts, um eine sichere, schrittweise Weitergabe von Konfigurationsänderungen an Ihre modellierten Units zu gewährleisten. Dies sorgt für betriebliche Konsistenz und Sicherheit, auch wenn nur Flags verwaltet werden.
  3. In Ihre Anwendung einbinden: Verwenden Sie das OpenFeature SDK mit dem flagd-Anbieter in Ihrem Anwendungscode (der überall ausgeführt werden kann – lokal, lokal, selbstverwaltete Cloud). Konfigurieren Sie ihn so, dass er eine Verbindung zum App Lifecycle Manager-Flag-Dienst (saasconfig.googleapis.com) herstellt, sich authentifiziert und sich mit dem entsprechenden Unit-Ressourcennamen identifiziert, um die richtigen Flag-Werte abzurufen.

So können Sie von einer verwalteten, sicheren Flag-Verteilung profitieren, ohne Ihre vorhandenen Bereitstellungspipelines oder Managementtools für die Infrastruktur ändern zu müssen.

Funktions-Flags für App Lifecycle Manager sind in der privaten Vorschau verfügbar. Für den Zugriff ist die Aufnahme in die Zulassungsliste erforderlich. Wenn Sie Zugriff für Ihre Organisation oder Ihr Projekt anfordern möchten, füllen Sie dieses Formular aus.

In dieser Kurzanleitung wird eine einfache Python-Anwendung verwendet, die lokal ausgeführt wird, um den Zugriff auf die Flags zu demonstrieren und die Einbindung Ihrer vorhandenen Anwendung zu simulieren.

Ziele

  • Richten Sie ein neues Google Cloud -Projekt ein oder verwenden Sie ein vorhandenes.
  • Aktivieren Sie die erforderlichen APIs (App Lifecycle Manager und SaaS Config).
  • Erteilen Sie die erforderlichen IAM-Berechtigungen (Identity and Access Management) für die Ressourcenerstellung und das Lesen von Flags.
  • Erstellen Sie minimale App Lifecycle Manager-Ressourcen (App-Angebot, Einheitentyp, Einheit), um eine Anwendungskomponente ohne Bereitstellung von Infrastruktur zu modellieren.
  • Definieren Sie eine Funktions-Flag-Ressource, die mit der Art der Einheit verknüpft ist.
  • Erstellen Sie einen Flag-Roll-out-Mechanismus (Roll-out-Art), der die Verteilungsstrategie definiert.
  • Verteilen Sie die ursprüngliche Flag-Konfiguration mithilfe eines App Lifecycle Manager-Rollouts.
  • Führen Sie eine Python-Beispielanwendung lokal aus, die eine Verbindung zum Flag-Dienst von App Lifecycle Manager herstellt und das Flag für die modellierte Einheit auswertet.
  • Aktualisieren Sie den Flag-Wert, erstellen Sie einen neuen Flag-Release und verteilen Sie die Änderung.
  • Prüfen Sie, ob die Anwendung den aktualisierten Flag-Wert übernimmt.

Hinweis

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

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

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

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

    gcloud init
  7. Python installieren: Auf dem Computer, auf dem Sie die Beispielanwendung ausführen, muss Python 3.7 oder höher installiert sein. Außerdem benötigen Sie pip, um Abhängigkeiten zu installieren.
    python --version
    pip --version
  8. gcloud für Standardanmeldedaten für Anwendungen (Application Default Credentials, ADC) authentifizieren: Das lokale Python-Script verwendet ADC, um sich bei Google Cloud -Diensten zu authentifizieren. Melden Sie sich mit Ihrem Nutzerkonto an:
    gcloud auth application-default login
  9. Anwendungsidentitätsberechtigungen gewähren: Ihre Anwendung benötigt die Berechtigung, Flag-Konfigurationen aus dem SaaS Config-Dienst zu lesen. Weisen Sie der Identität, die die Anwendung verwenden wird, die Rolle „roles/saasconfig.viewer“ zu. Weisen Sie für diese Kurzanleitung, in der ADC lokal mit Ihrem Nutzerkonto verwendet wird, die Rolle Ihrer E-Mail-Adresse zu:
        gcloud projects add-iam-policy-binding PROJECT_ID \
            --member="user:YOUR_EMAIL_ADDRESS" \
            --role="roles/saasconfig.viewer"
    Ersetzen Sie PROJECT_ID durch Ihre Projekt-ID in Google Cloud und YOUR_EMAIL_ADDRESS durch die E-Mail-Adresse, die mit Ihrer CLI-Anmeldung verknüpft ist.

Minimale App Lifecycle Manager-Ressourcen erstellen

Auch wenn wir mit App Lifecycle Manager keine Infrastruktur bereitstellen, benötigen wir einige Ressourcen, um unsere Flags sicher zu organisieren, auszurichten und zu verteilen. Diese Ressourcen stellen Ihre vorhandenen Anwendungskomponenten in App Lifecycle Manager dar.

  1. Variablen definieren: Legen Sie Umgebungsvariablen für Ressourcennamen und ‑standorte fest.

    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. App-Angebot erstellen:Dies dient als Container der obersten Ebene für die Konfiguration Ihres Dienstes, einschließlich Flags.

    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. Art der Einheit erstellen: Damit wird der Typ der Komponente definiert, die Sie modellieren. Wir stellen keinen Blueprint bereit, da wir keine Infrastruktur verwalten.

    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. Einheit erstellen: Dies stellt eine bestimmte Instanz Ihrer Anwendung dar.

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

Funktions-Flag definieren und bereitstellen

Erstellen Sie jetzt das eigentliche Funktions-Flag und verwenden Sie den Roll-out-Mechanismus von App Lifecycle Manager, um die Konfiguration für die von Ihnen erstellten Einheiten verfügbar zu machen.

  1. Flag-Variablen definieren:

    export FLAG_ID="standalone-flag-01"
    export FLAG_KEY="enable-beta-feature" 
    
  2. Flag-Ressource, ‑Version und ‑Release erstellen:

    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. Roll‑out-Art erstellen: Definieren Sie die Strategie für die Verteilung von Flag-Änderungen.

    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. Roll-out erstellen:Starten Sie den Bereitstellungsprozess.

    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. Roll-out überwachen: Prüfen Sie, ob die Bereitstellung erfolgreich war, bevor Sie fortfahren.

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

Eigenständige Infrastruktur konfigurieren

In einer eigenständigen Einrichtung verwalten Sie Ihr eigenes Anwendungshosting (z.B. Cloud Run oder GKE) und verwenden App Lifecycle Manager nur für die Konfigurationssynchronisierung. Der Anwendungscode bleibt bei allen Bereitstellungen gleich. Es ist nur erforderlich, dass die Umgebungsvariable FLAGD_SOURCE_PROVIDER_ID zur Laufzeit vorhanden ist, um eine Verbindung zum SaaS Config Service herzustellen.

Sie können Ihre App Lifecycle Manager-Einheitendefinitionen Ihren Standard-Terraform-Bereitstellungsdefinitionen zuordnen, indem Sie den erstellten Pfad als Umgebungsvariable übergeben.

  1. Infrastruktur definieren: Ordnen Sie den Pfad in Ihrer Bereitstellungsvorlage zu (z.B. 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. Variablenwerte definieren: Geben Sie die Parameter der Konfigurationseinheit in einer zugehörigen Variablendatei an (z.B. terraform.tfvars).

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

Beispielanwendung einbinden und ausführen

Führen Sie eine Python-Beispielanwendung lokal aus, um mithilfe der modellierten Einheitenkonfigurationen eine Verbindung zum Flag-Dienst von App Lifecycle Manager herzustellen.

  1. Projektverzeichnis und Dateien erstellen:

    mkdir saas_flags_standalone_app
    cd saas_flags_standalone_app
    

    requirements.txt erstellen:

    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
    

    Installieren Sie die Abhängigkeiten:

    pip install -r requirements.txt
    
  2. app.py erstellen:

    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. Führen Sie die Anwendung aus:

    export FLAGD_SOURCE_PROVIDER_ID="projects/${PROJECT_ID}/locations/${LOCATION_1}/featureFlagsConfigs/${UNIT_ID}"
    python app.py
    
  4. Anfänglichen Flag-Wert prüfen: Führen Sie in einem zweiten Terminal eine Prüfung für den lokalen Endpunkt aus.

    curl http://localhost:8080
    

Flag aktualisieren und Änderung verteilen

Ändern Sie den Laufzeitstatus der Flag-Definition und verteilen Sie das Update an verbundene Ziele.

  1. Aktualisieren Sie die Flag-Ressource:

    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. Erstellen Sie einen neuen Roll-out für das Update:

    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. Neues Roll-out überwachen:

    gcloud beta app-lifecycle-manager rollouts describe ${ROLLOUT_ID_2} \
      --project=${PROJECT_ID} \
      --location=global 
    
  4. Prüfen Sie die Änderung in der laufenden Anwendung:

    curl http://localhost:8080
    

Bereinigen

Mit den folgenden Schritten vermeiden Sie, dass Ihrem Google Cloud -Konto die auf dieser Seite verwendeten Ressourcen in Rechnung gestellt werden:

  1. Drücken Sie im Terminal, in dem app.py ausgeführt wird, Ctrl+C, um die lokale Python-Anwendung zu beenden.
  2. Legen Sie den Flag-Status fest.
  3. Erstellen Sie einen neuen Roll‑out, um veraltete Flags zu entfernen.
  4. Nachdem der Roll-out abgeschlossen ist und veraltete Flags entfernt wurden, löschen Sie die App Lifecycle Manager-Ressourcen:

    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. Löschen Sie das lokale Verzeichnis:

    cd ..
    rm -rf saas_flags_standalone_app
    

Nächste Schritte