Implementa marcas de función

En esta guía de inicio rápido, se muestra cómo crear, implementar y usar marcas de función con App Lifecycle Manager.

En esta guía de inicio rápido, aprenderás a instalar y configurar un proveedor de marcas, y a realizar el marcado de funciones básico con las marcas de función de App Lifecycle Manager.

Antes de comenzar

  1. Accede a tu cuenta de Google.

    Si todavía no tienes una cuenta, regístrate para obtener una nueva.

  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, Artifact Registry, Infrastructure Manager, Developer Connect, Cloud Build, Cloud Storage, Cloud Run 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. 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.

  6. Instala Google Cloud CLI.

  7. Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.

  8. Para inicializar gcloud CLI, ejecuta el siguiente comando:

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

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

  11. Enable the App Lifecycle Manager, Artifact Registry, Infrastructure Manager, Developer Connect, Cloud Build, Cloud Storage, Cloud Run 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

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

  13. Instala Google Cloud CLI.

  14. Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.

  15. Para inicializar gcloud CLI, ejecuta el siguiente comando:

    gcloud init
  16. Crea una oferta de SaaS. Necesitas una oferta de SaaS para completar esta guía de inicio rápido. Para obtener más información sobre cómo crear una oferta de SaaS, consulta Crea una oferta de SaaS.

Otorga permisos a la cuenta de servicio de App Lifecycle Manager

Cuando habilitas la API de App Lifecycle Manager, App Lifecycle Manager crea una cuenta de servicio. Esta cuenta de servicio se denomina service-PROJECT-NUMBER@gcp-sa-saasservicemgmt.iam.gserviceaccount.com, en la que PROJECT-NUMBER es tu número de proyecto.

Para otorgar a esta cuenta de servicio los permisos necesarios, ejecuta el siguiente comando:

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

Reemplaza lo siguiente:

  • PROJECT_ID: Un identificador de cadena que representa tu ID del proyecto.
  • PROJECT_NUMBER: Tu número de proyecto.

Cómo encontrar documentación de referencia

Esta cuenta de servicio actúa en tu nombre para varias tareas, como el aprovisionamiento de unidades.

Crea un repositorio en Artifact Registry

Para usar App Lifecycle Manager, necesitas un repositorio en Artifact Registry. Para crear este repositorio, ejecuta el siguiente comando en la terminal:

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

Este repositorio contendrá un esquema (archivos de Terraform empaquetados) que describe cómo aprovisionar tus unidades.

Crea un esquema de aplicación de marcado de funciones

Crea una secuencia de comandos de Python que lea una marca de función y úsala para compilar y enviar una imagen de Docker:

  1. Crea un directorio llamado alm_docker para el contexto de compilación de Docker.

  2. En el directorio alm_docker, crea el archivo flags.py con este fragmento:

    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)
    

    Esta secuencia de comandos de Python muestra cómo acceder a las marcas de función dentro de tu aplicación que se ejecuta como una imagen de Docker en una unidad de App Lifecycle Manager. Usa los principios estándar de OpenFeature para integrarse con el servicio de configuración de marcas de función de App Lifecycle Manager (saasconfig.googleapis.com).

  3. Crea un archivo de texto llamado requirements.txt en el directorio alm_docker que contenga este fragmento:

    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. Agrega lo siguiente al Dockerfile en el directorio alm_docker:

    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. Ejecuta este comando en tu entorno local para compilar y enviar la imagen de Docker:

    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}"
    

    Reemplaza lo siguiente:

    • PROJECT_ID: Un identificador de cadena que representa tu ID del proyecto.
  6. En tu entorno de Docker, crea un directorio alm_terraform.

  7. En alm_terraform, crea estos archivos:

    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. En el directorio alm_terraform, ejecuta este comando para empaquetar los archivos de esquema de Terraform:

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

Usa el esquema de la aplicación para crear una unidad

Después de crear un esquema de aplicación que utilice marcas de función, debes crear un tipo de unidad de App Lifecycle Manager (flags-unit-kind) y, luego, crear una unidad de este tipo (flags-quickstart-unit).

Para obtener más información sobre las unidades y los tipos de unidades, consulta Unidades de modelo y paquete de una implementación.

Para usar el esquema de la aplicación para crear una unidad, sigue estos pasos de gcloud CLI:

  1. Para empaquetar tu configuración de Terraform como una imagen de OCI (esquema), crea un archivo llamado Dockerfile en tu directorio de Terraform:

    # syntax=docker/dockerfile:1-labs
    FROM scratch
    COPY --exclude=Dockerfile --exclude=.git --exclude=.gitignore . /
    
  2. Compila y envía Dockerfile a tu repositorio de 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 .
    

    Reemplaza lo siguiente:

    • PROJECT_ID: Un identificador de cadena que representa tu ID del proyecto.
  3. Crea el recurso flags-unit-kind y 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
    

    Reemplaza lo siguiente:

    • PROJECT_ID: Un identificador de cadena que representa tu ID del proyecto.
  4. Crea la unidad 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
    

    Reemplaza lo siguiente:

    • PROJECT_ID: Un identificador de cadena que representa tu ID del proyecto.

Crea y aprovisiona una marca de función

Antes de que tu unidad aprovisionada pueda utilizar una marca de función de App Lifecycle Manager, debes crear el recurso de marca de función y, luego, iniciar un lanzamiento para propagar la configuración a la unidad.

Ejecuta los comandos para crear y aprovisionar la marca de función quickstart-flag:

  1. En tu entorno, define estas variables:

    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 el recurso de marca de función:

    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 revisión:

    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 versión:

    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 de lanzamiento:

    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 el lanzamiento:

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

Puedes supervisar el estado del lanzamiento con:

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

Visualiza el valor de la marca en tu servicio en ejecución

Después de que tu unidad de App Lifecycle Manager haya aprovisionado correctamente el servicio de Cloud Run, puedes verificar que tu aplicación se esté ejecutando y evaluando correctamente la marca de función:

  1. En Google Cloud la consola, ve a Cloud Run:

    Ir a Cloud Run

  2. Busca el servicio llamado saas-flags-quickstart-svc en la región us-central1. Una marca de verificación junto a saas-flags-quickstart-svc indica que se está ejecutando correctamente.

  3. Haz clic en saas-flags-quickstart-svc para ver sus detalles.

    Ir a saas-flags-quickstart-svc.

  4. Selecciona la pestaña Registros.

    1. En las entradas de registro, busca un mensaje similar al siguiente:

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

      Esto confirma que la aplicación se inició, se conectó al servicio de configuración de SaaS y evaluó quickstart-flag.

  5. Para acceder al extremo público, haz clic en la pestaña Redes.

    1. Busca la URL pública que aparece en la sección Extremos.
    2. Haz clic en la URL para abrirla en tu navegador o usa una herramienta como curl para acceder a ella desde tu terminal (curl YOUR_SERVICE_URL, por ejemplo).
    3. Cada vez que accedes a la URL, el servicio evalúa la marca de función y muestra su valor actual en formato JSON. Por ejemplo:

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

Implementaste correctamente un Google Cloud servicio que lee una marca de función administrada por App Lifecycle Manager. Puedes experimentar con cambiar el valor de la marca y crear un lanzamiento nuevo para ver cómo tu aplicación detecta el cambio.

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.

Opcional: borra el proyecto

Si implementaste la solución en un proyecto nuevo Google Cloud y ya no la necesitas, bórrala completando los siguientes pasos:

  1. En la Google Cloud consola, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  3. Cuando se te solicite, escribe el ID del proyecto y, luego, haz clic en Apagar.

¿Qué sigue?