Menggunakan tombol fitur Mandiri

Pelajari cara menggunakan tombol fitur App Lifecycle Manager sebagai layanan mandiri untuk mengelola ketersediaan fitur di aplikasi Anda, meskipun aplikasi tersebut tidak di-deploy atau dikelola oleh App Lifecycle Manager.

Pengantar

Panduan memulai ini menunjukkan cara menggunakan kemampuan tombol fitur yang andal dan peluncuran terkontrol dari App Lifecycle Manager tanpa perlu menggunakan App Lifecycle Manager untuk penyediaan infrastruktur (seperti men-deploy VM atau layanan Cloud Run menggunakan blueprint Terraform). Pendekatan ini ideal jika Anda mengelola infrastruktur aplikasi secara independen, tetapi ingin menggunakan App Lifecycle Manager untuk pengelolaan tombol fitur yang aman.

Dalam pendekatan mandiri ini, Anda akan:

  1. Modelkan sistem Anda dengan resource App Lifecycle Manager yang ringan: Buat Units App Lifecycle Manager untuk merepresentasikan komponen infrastruktur yang ada (misalnya, deployment microservice tertentu, lingkungan tenant, satu instance biner). Unit ini hanya berfungsi sebagai target untuk konfigurasi tanda dan tidak melibatkan deployment infrastruktur menggunakan blueprint App Lifecycle Manager.
  2. Menentukan dan Mendistribusikan Flag: Gunakan App Lifecycle Manager API atau konsol Google Cloud untuk membuat tombol fitur. Kelola siklus prosesnya menggunakan App Lifecycle Manager Rollouts untuk memastikan penyebaran perubahan konfigurasi yang aman dan bertahap ke Units yang dimodelkan. Hal ini memberikan konsistensi dan keamanan operasional meskipun hanya mengelola flag.
  3. Integrasikan dengan Aplikasi Anda: Gunakan OpenFeature SDK dengan penyedia flagd dalam kode aplikasi Anda (berjalan di mana saja – secara lokal, on-premise, cloud yang dikelola sendiri). Konfigurasikan untuk terhubung ke layanan flag App Lifecycle Manager (saasconfig.googleapis.com), lakukan autentikasi, dan identifikasi dirinya menggunakan nama resource Unit yang sesuai untuk mengambil nilai flag yang benar.

Dengan pendekatan ini, Anda dapat memanfaatkan distribusi flag yang aman dan terkelola tanpa mengubah pipeline deployment atau alat pengelolaan infrastruktur yang ada.

Tombol fitur App Lifecycle Manager tersedia dalam Pratinjau Pribadi. Akses memerlukan pemberian izin. Untuk meminta akses bagi organisasi atau project Anda, lengkapi formulir ini.

Panduan memulai ini menggunakan aplikasi Python dasar yang dijalankan secara lokal untuk menunjukkan cara mengakses flag, yang menyimulasikan cara aplikasi Anda yang ada akan diintegrasikan.

Tujuan

  • Siapkan project Google Cloud baru atau gunakan project yang sudah ada.
  • Aktifkan API yang diperlukan (App Lifecycle Manager dan SaaS Config).
  • Memberikan izin Identity and Access Management yang diperlukan untuk pembuatan resource dan pembacaan flag.
  • Membuat resource App Lifecycle Manager minimal (Penawaran aplikasi, Jenis Unit, Unit) untuk memodelkan komponen aplikasi tanpa men-deploy infrastruktur.
  • Tentukan resource tombol fitur yang terkait dengan Jenis Unit.
  • Buat mekanisme peluncuran flag (Jenis Peluncuran) yang menentukan strategi distribusi.
  • Distribusikan konfigurasi flag awal menggunakan App Lifecycle Manager Rollout.
  • Jalankan aplikasi Python contoh secara lokal yang terhubung ke layanan flag App Lifecycle Manager dan mengevaluasi flag untuk Unit yang dimodelkan.
  • Perbarui nilai flag, buat rilis flag baru, dan distribusikan perubahan.
  • Pastikan aplikasi mengambil nilai flag yang diperbarui.

Sebelum memulai

  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. Instal Python: Pastikan Anda telah menginstal Python 3.7+ di komputer tempat Anda akan menjalankan aplikasi contoh. Anda juga memerlukan pip untuk menginstal dependensi.
    python --version
    pip --version
  8. Mengautentikasi gcloud untuk Kredensial Default Aplikasi (ADC): Skrip Python lokal menggunakan ADC untuk melakukan autentikasi ke layanan Google Cloud . Login menggunakan akun pengguna Anda:
    gcloud auth application-default login
  9. Memberikan Izin Identitas Aplikasi: Aplikasi Anda memerlukan izin untuk membaca konfigurasi flag dari layanan SaaS Config. Berikan peran `roles/saasconfig.viewer` ke identitas yang akan digunakan aplikasi. Untuk panduan memulai ini, yang menggunakan ADC secara lokal dengan akun pengguna Anda, berikan peran tersebut ke alamat email Anda:
        gcloud projects add-iam-policy-binding PROJECT_ID \
            --member="user:YOUR_EMAIL_ADDRESS" \
            --role="roles/saasconfig.viewer"
    Ganti PROJECT_ID dengan project ID Google Cloud Anda dan YOUR_EMAIL_ADDRESS dengan email yang terkait dengan login CLI Anda.

Membuat resource App Lifecycle Manager minimal

Meskipun tidak men-deploy infrastruktur dengan App Lifecycle Manager, kita memerlukan beberapa resource untuk mengatur, menargetkan, dan mendistribusikan flag kita dengan aman. Resource ini mewakili komponen aplikasi yang ada dalam App Lifecycle Manager.

  1. Menentukan variabel: Menetapkan variabel lingkungan untuk nama dan lokasi resource.

    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. Buat penawaran Aplikasi: Ini berfungsi sebagai penampung tingkat atas untuk konfigurasi layanan Anda, termasuk 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. Membuat jenis unit: Tindakan ini menentukan jenis komponen yang Anda buat modelnya. Yang terpenting, kami tidak menyediakan blueprint karena kami tidak mengelola infrastruktur.

    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. Membuat unit: Ini mewakili instance tertentu dari aplikasi Anda.

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

Menentukan dan men-deploy tombol fitur

Sekarang, buat tombol fitur yang sebenarnya dan gunakan mekanisme peluncuran App Lifecycle Manager untuk menyediakan konfigurasinya bagi unit yang Anda buat.

  1. Tentukan variabel flag:

    export FLAG_ID="standalone-flag-01"
    export FLAG_KEY="enable-beta-feature" 
    
  2. Membuat resource, revisi, dan rilis 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_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. Membuat jenis peluncuran: Tentukan strategi untuk mendistribusikan perubahan 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. Membuat peluncuran: Memulai proses distribusi.

    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. Pantau peluncuran: Pastikan deployment berhasil sebelum melanjutkan.

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

Mengonfigurasi infrastruktur mandiri

Dalam penyiapan mandiri, Anda mengelola hosting aplikasi Anda sendiri (misalnya, Cloud Run atau GKE) dan menggunakan App Lifecycle Manager murni untuk sinkronisasi konfigurasi. Kode aplikasi tetap standar di seluruh deployment; kode ini hanya memerlukan variabel lingkungan FLAGD_SOURCE_PROVIDER_ID saat runtime untuk terhubung ke SaaS Config Service.

Anda dapat memetakan definisi unit App Lifecycle Manager ke dalam definisi deployment Terraform standar dengan meneruskan jalur yang dibuat sebagai variabel lingkungan.

  1. Tentukan infrastruktur Anda: Petakan jalur di template deployment Anda (misalnya, 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. Tentukan nilai variabel Anda: Berikan parameter unit konfigurasi dalam file variabel terkait (misalnya, terraform.tfvars).

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

Mengintegrasikan dan menjalankan aplikasi contoh

Jalankan contoh aplikasi Python secara lokal untuk terhubung ke layanan flag App Lifecycle Manager menggunakan konfigurasi unit yang dimodelkan.

  1. Membuat direktori dan file project:

    mkdir saas_flags_standalone_app
    cd saas_flags_standalone_app
    

    Buat 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
    

    Instal dependensi:

    pip install -r requirements.txt
    
  2. Buat 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. Jalankan aplikasi:

    export FLAGD_SOURCE_PROVIDER_ID="projects/${PROJECT_ID}/locations/${LOCATION_1}/featureFlagsConfigs/${UNIT_ID}"
    python app.py
    
  4. Verifikasi nilai flag awal: Jalankan pemeriksaan terhadap endpoint lokal di terminal sekunder.

    curl http://localhost:8080
    

Memperbarui flag dan mendistribusikan perubahan

Mengubah status runtime definisi flag dan mendistribusikan update ke target yang terhubung.

  1. Perbarui resource 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. Buat peluncuran baru untuk 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. Pantau peluncuran baru:

    gcloud beta app-lifecycle-manager rollouts describe ${ROLLOUT_ID_2} \
      --project=${PROJECT_ID} \
      --location=global 
    
  4. Verifikasi perubahan pada aplikasi yang sedang berjalan:

    curl http://localhost:8080
    

Pembersihan

Agar akun Google Cloud Anda tidak dikenai biaya untuk resource yang digunakan pada halaman ini, ikuti langkah-langkah berikut.

  1. Tekan Ctrl+C di terminal tempat app.py berjalan untuk menghentikan aplikasi Python lokal.
  2. Tetapkan status flag.
  3. Buat peluncuran baru untuk menghapus tanda yang sudah tidak berlaku.
  4. Setelah peluncuran selesai dan flag yang tidak digunakan lagi telah dihapus, hapus resource 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. Hapus direktori lokal:

    cd ..
    rm -rf saas_flags_standalone_app
    

Langkah berikutnya