Usa marcas de funciones independientes
Aprende a usar las marcas de funciones de App Lifecycle Manager como un servicio independiente para administrar la disponibilidad de funciones en tus aplicaciones, incluso si App Lifecycle Manager no las implementa ni administra.
Introducción
En esta guía de inicio rápido, se muestra cómo usar las sólidas capacidades de lanzamiento controlado y de marcas de funciones de App Lifecycle Manager sin necesidad de usar App Lifecycle Manager para el aprovisionamiento de infraestructura (como la implementación de VMs o servicios de Cloud Run con planos de Terraform). Este enfoque es ideal si administras la infraestructura de tu aplicación de forma independiente, pero quieres usar App Lifecycle Manager para la administración segura de marcas de funciones.
En este enfoque independiente, harás lo siguiente:
- Modele su sistema con recursos ligeros de App Lifecycle Manager: Cree
Unitsde App Lifecycle Manager para representar componentes de su infraestructura existente (p.ej., una implementación de microservicio específica, un entorno de usuario, una sola instancia binaria). Estas unidades actúan únicamente como destinos para las configuraciones de marcas y no implican la implementación de infraestructura con planos de App Lifecycle Manager. - Definir y distribuir marcas: Usa la API de App Lifecycle Manager o Google Cloud la consola para crear marcas de funciones. Administra su ciclo de vida con
Rolloutsde App Lifecycle Manager para garantizar la propagación segura y gradual de los cambios de configuración a tusUnitsmodeladas. Esto proporciona coherencia operativa y seguridad, incluso cuando solo se administran marcas. - Realizar la integración con tu aplicación: Usa el SDK de OpenFeature con el proveedor
flagden el código de tu aplicación (que se ejecuta en cualquier lugar: de forma local, en las instalaciones o en la nube autoadministrada). Configúralo para que se conecte al servicio de marcas de App Lifecycle Manager (saasconfig.googleapis.com), se autentique y se identifique con su nombre de recursoUnitcorrespondiente para recuperar los valores de marca correctos.
Este enfoque te permite beneficiarte de la distribución segura y administrada de marcas sin alterar tus canalizaciones de implementación existentes ni las herramientas de administración de infraestructura.
Las marcas de funciones de App Lifecycle Manager están en versión preliminar privada. El acceso requiere una lista de entidades permitidas. Para solicitar acceso para tu organización o proyecto, completa este formulario.
En esta guía de inicio rápido, se usa una aplicación básica de Python que se ejecuta de forma local para demostrar el acceso a las marcas, lo que simula cómo se integraría tu aplicación existente.
Objetivos
- Configurar un proyecto Google Cloud nuevo o usar uno existente
- Habilitar las APIs requeridas (App Lifecycle Manager y SaaS Config)
- Otorgar los permisos necesarios de Identity and Access Management para la creación de recursos y la lectura de marcas
- Crear recursos mínimos de App Lifecycle Manager (SaaS Offering, Unit Kind, Unit) para modelar un componente de la aplicación sin implementar la infraestructura
- Definir un recurso de marca de funciones asociado con el tipo de unidad
- Crear un mecanismo de lanzamiento de marcas (tipo de lanzamiento) que defina la estrategia de distribución
- Distribuir la configuración inicial de la marca con un lanzamiento de App Lifecycle Manager
- Ejecutar de forma local una aplicación de muestra de Python que se conecte al servicio de marcas de App Lifecycle Manager y evalúe la marca para la unidad modelada
- Actualizar el valor de la marca, crear una nueva versión de la marca y distribuir el cambio
- Verificar que la aplicación recupere el valor de la marca actualizado
Antes de comenzar
-
Accede a tu cuenta de Google.
Si todavía no tienes una cuenta, regístrate para obtener una nueva.
-
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 theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
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 theserviceusage.services.enablepermission. Learn how to grant roles.-
Instala Google Cloud CLI.
-
Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.
-
Para inicializar gcloud CLI, ejecuta el siguiente comando:
gcloud init -
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 theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
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 theserviceusage.services.enablepermission. Learn how to grant roles.-
Instala Google Cloud CLI.
-
Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.
-
Para inicializar gcloud CLI, ejecuta el siguiente comando:
gcloud init -
Instala Python: Asegúrate de tener Python 3.7 o una versión posterior instalada en la máquina en la que ejecutarás la aplicación de muestra. También necesitas pip para instalar dependencias.
python --version
pip --version
-
Autentica gcloud para las credenciales predeterminadas de la aplicación (ADC): La secuencia de comandos local de Python usa ADC para autenticarse en los Google Cloud servicios. Accede con tu cuenta de usuario:
gcloud auth application-default login
-
Otorga permisos de identidad de la aplicación: Tu aplicación necesita permiso para leer las configuraciones de marcas del servicio de SaaS Config. Otorga el rol `roles/saasconfig.viewer` a la identidad que usará la aplicación. Para esta guía de inicio rápido que usa ADC de forma local con tu cuenta de usuario, otorga el rol a tu dirección de correo electrónico:
Reemplaza PROJECT_ID por el ID de tu Google Cloud proyecto y YOUR_EMAIL_ADDRESS por el correo electrónico asociado con tu información de acceso a la CLI.gcloud projects add-iam-policy-binding PROJECT_ID \ --member="user:YOUR_EMAIL_ADDRESS" \ --role="roles/saasconfig.viewer"
Crea recursos mínimos de App Lifecycle Manager
Aunque no implementamos infraestructura con App Lifecycle Manager, necesitamos algunos recursos para organizar, segmentar y distribuir nuestras marcas de forma segura. Estos recursos representan los componentes de tu aplicación existente en App Lifecycle Manager.
Define variables: Establece variables de entorno para los nombres y las ubicaciones de los recursos.
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"Crea una oferta de SaaS: Actúa como un contenedor de nivel superior para la configuración de tu servicio, incluidas las marcas.
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}Crea un tipo de unidad: Define el tipo de componente que estás modelando. Es fundamental que no proporcionemos un plano porque no administramos la infraestructura.
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}Crea una unidad: Representa una instancia específica de tu aplicación.
gcloud beta app-lifecycle-manager units create ${UNIT_ID} \ --project=${PROJECT_ID} \ --unit-kind=${UNIT_KIND_ID} \ --location=${LOCATION_1}
Define y lanza la marca de funciones
Ahora, crea la marca de funciones real y usa el mecanismo de lanzamiento de App Lifecycle Manager para que su configuración esté disponible para las unidades que creaste.
Define variables de marca:
export FLAG_ID="standalone-flag-01" export FLAG_KEY="enable-beta-feature"Crea el recurso, la revisión y la versión de la marca:
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=globalCrea un tipo de lanzamiento: Define la estrategia para distribuir los cambios de marca.
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=globalCrea el lanzamiento: Inicia el proceso de distribución.
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=globalSupervisa el lanzamiento: Asegúrate de que la implementación se realice correctamente antes de continuar.
gcloud beta app-lifecycle-manager rollouts describe ${ROLLOUT_ID_1} \ --project=${PROJECT_ID} \ --location=global
Configura la infraestructura independiente
En una configuración independiente, administras tu propio hosting de aplicaciones (p.ej., Cloud Run o GKE) y usas App Lifecycle Manager únicamente para la sincronización de la configuración. El código de la aplicación sigue siendo estándar en todas las implementaciones. Solo requiere que la variable de entorno FLAGD_SOURCE_PROVIDER_ID esté presente en el tiempo de ejecución para conectarse al servicio de SaaS Config.
Puedes asignar tus definiciones de unidades de App Lifecycle Manager a tus definiciones de implementación estándar de Terraform pasando la ruta construida como una variable de entorno.
Define tu infraestructura: Asigna la ruta en tu plantilla de implementación (p.ej.,
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}" } } } }Define los valores de tus variables: Proporciona los parámetros de la unidad de configuración en un archivo de variables asociado (p.ej.,
terraform.tfvars).project_id = "PROJECT_ID" region = "LOCATION_1" unit_id = "UNIT_ID"
Integra y ejecuta la aplicación de muestra
Ejecuta una aplicación de ejemplo de Python de forma local para conectarte al servicio de marcas de App Lifecycle Manager con las configuraciones de unidades modeladas.
Crea el directorio y los archivos del proyecto:
mkdir saas_flags_standalone_app cd saas_flags_standalone_appCrea
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.0Instala las dependencias:
pip install -r requirements.txtCrea 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)Ejecuta la aplicación:
export FLAGD_SOURCE_PROVIDER_ID="projects/${PROJECT_ID}/locations/${LOCATION_1}/featureFlagsConfigs/${UNIT_ID}" python app.pyVerifica el valor inicial de la marca: Ejecuta una verificación en el extremo local en una terminal secundaria.
curl http://localhost:8080
Actualiza la marca y distribuye el cambio
Modifica el estado del tiempo de ejecución de la definición de la marca y distribuye la actualización a los destinos conectados.
Actualiza el recurso de la marca:
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=globalCrea un lanzamiento nuevo para la actualización:
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=globalSupervisa el lanzamiento nuevo:
gcloud beta app-lifecycle-manager rollouts describe ${ROLLOUT_ID_2} \ --project=${PROJECT_ID} \ --location=globalVerifica el cambio en la aplicación en ejecución:
curl http://localhost:8080
Limpia
Sigue estos pasos para evitar que se apliquen cargos a tu Google Cloud cuenta de por los recursos que usaste en esta página.
- Presiona
Ctrl+Cen la terminal en la que se ejecutaapp.pypara detener la aplicación local de Python. - Establece el estado de la marca.
- Crea un lanzamiento nuevo para quitar las marcas obsoletas.
Una vez que se complete el lanzamiento y se quiten las marcas obsoletas, borra los recursos de 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} --quietBorra el directorio local:
cd .. rm -rf saas_flags_standalone_app
¿Qué sigue?
- Lee la descripción general de las marcas de funciones de App Lifecycle Manager para obtener más detalles conceptuales.
- Prueba la guía de inicio rápido Implementa marcas de funciones para ver cómo las marcas se integran de forma estrecha con las implementaciones administradas por App Lifecycle Manager.