Implantar flags de recursos

Neste guia de início rápido, mostramos como criar, implantar e usar flags de recursos com o App Lifecycle Manager.

Neste guia de início rápido, você vai aprender a instalar e configurar um provedor de flags e realizar a flag de recursos básica usando as flags de recursos do Gerenciador de ciclo de vida do app.

Antes de começar

  1. Faça login na sua Conta do Google.

    Se você ainda não tiver uma, inscreva-se agora.

  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. Instale a CLI do Google Cloud.

  7. Ao usar um provedor de identidade (IdP) externo, primeiro faça login na gcloud CLI com sua identidade federada.

  8. Para inicializar a gcloud CLI, execute o seguinte 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. Instale a CLI do Google Cloud.

  14. Ao usar um provedor de identidade (IdP) externo, primeiro faça login na gcloud CLI com sua identidade federada.

  15. Para inicializar a gcloud CLI, execute o seguinte comando:

    gcloud init
  16. Crie uma oferta de SaaS. Você precisa de uma oferta de SaaS para concluir este guia de início rápido. Para mais informações sobre como criar uma oferta de SaaS, consulte Criar uma oferta de SaaS.

Conceder permissões à conta de serviço do App Lifecycle Manager

Quando você ativa a API App Lifecycle Manager, o App Lifecycle Manager cria uma conta de serviço. Essa conta de serviço é chamada de service-PROJECT-NUMBER@gcp-sa-saasservicemgmt.iam.gserviceaccount.com, em que PROJECT-NUMBER é o número do projeto.

Conceda a essa conta de serviço as permissões necessárias executando o seguinte 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"

Substitua:

  • PROJECT_ID: um identificador de string que representa o ID do projeto.
  • PROJECT_NUMBER: o número do projeto.

Como encontrar documentação de referência

Essa conta de serviço age em seu nome para várias tarefas, como provisionamento de unidades.

Criar um repositório no Artifact Registry

Para usar o App Lifecycle Manager, você precisa de um repositório no Artifact Registry. Para criar esse repositório, execute o comando a seguir no terminal:

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

Esse repositório vai conter um blueprint (arquivos do Terraform empacotados) que descreve como provisionar suas unidades.

Criar um blueprint de aplicativo de flags de recursos

Crie um script Python que leia uma flag de recurso e use-a para criar e enviar uma imagem Docker:

  1. Crie um diretório chamado alm_docker para seu contexto de build do Docker.

  2. No diretório alm_docker, crie o arquivo flags.py com o seguinte snippet:

    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)
    

    Este script Python demonstra como acessar flags de recursos no seu aplicativo executado como uma imagem Docker em uma unidade do App Lifecycle Manager. Ele usa princípios padrão do OpenFeature para se integrar ao serviço de configuração de flag de recurso do App Lifecycle Manager (saasconfig.googleapis.com).

  3. Crie um arquivo de texto chamado requirements.txt no diretório alm_docker que contenha este snippet:

    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. Adicione o Dockerfile no diretório alm_docker com:

    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. Execute este comando no ambiente local para criar e enviar a imagem 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}"
    

    Substitua:

    • PROJECT_ID: um identificador de string que representa o ID do projeto.
  6. No ambiente do Docker, crie um diretório alm_terraform.

  7. Em alm_terraform, crie estes arquivos:

    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. No diretório alm_terraform, execute este comando para empacotar os arquivos de blueprint do Terraform:

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

Usar o blueprint do aplicativo para criar uma unidade

Depois de criar um projeto de aplicativo que usa flags de recursos, você precisa criar um tipo de unidade do App Lifecycle Manager (flags-unit-kind) e, em seguida, criar uma unidade desse tipo (flags-quickstart-unit).

Para mais informações sobre unidades e tipos de unidades, consulte Unidades de modelo e pacote de uma implantação.

Para usar o projeto do aplicativo para criar uma unidade, siga estas etapas da CLI gcloud:

  1. Para empacotar sua configuração do Terraform como uma imagem OCI (blueprint), crie um arquivo chamado Dockerfile no diretório do Terraform:

    # syntax=docker/dockerfile:1-labs
    FROM scratch
    COPY --exclude=Dockerfile --exclude=.git --exclude=.gitignore . /
    
  2. Crie e envie Dockerfile para o repositório do 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 .
    

    Substitua:

    • PROJECT_ID: um identificador de string que representa o ID do projeto.
  3. Crie os recursos flags-unit-kind e 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
    

    Substitua:

    • PROJECT_ID: um identificador de string que representa o ID do projeto.
  4. Crie a unidade 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
    

    Substitua:

    • PROJECT_ID: um identificador de string que representa o ID do projeto.

Criar e provisionar uma flag de recurso

Antes que uma flag de recurso do App Lifecycle Manager possa ser usada pela unidade provisionada, é necessário criar o recurso de flag e iniciar um lançamento para propagar a configuração para a unidade.

Execute os comandos para criar e provisionar a flag de recurso quickstart-flag:

  1. No seu ambiente, defina estas variáveis:

    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. Crie o recurso de flag de recurso:

    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. Criar uma revisão:

    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. Crie uma versão:

    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. Criar um tipo de lançamento:

    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. Crie o lançamento:

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

É possível monitorar o status do lançamento com:

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

Ver o valor da flag no serviço em execução

Depois que a unidade do App Lifecycle Manager provisionar o serviço do Cloud Run, verifique se o aplicativo está em execução e avaliando corretamente a flag de recurso:

  1. No Google Cloud console, acesse o Cloud Run:

    Acessar o Cloud Run

  2. Encontre o serviço chamado saas-flags-quickstart-svc na região us-central1. Uma marca de seleção ao lado de saas-flags-quickstart-svc indica que ele está sendo executado com sucesso.

  3. Clique em saas-flags-quickstart-svc para ver os detalhes.

    Acesse saas-flags-quickstart-svc.

  4. Selecione a guia Registros.

    1. Nas entradas de registro, procure uma mensagem semelhante a esta:

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

      Isso confirma que o aplicativo foi iniciado, conectado ao serviço SaaS Config e avaliou o quickstart-flag.

  5. Para acessar o endpoint público, clique na guia Rede.

    1. Encontre o URL público listado na seção Endpoints.
    2. Clique no URL para abrir no navegador ou use uma ferramenta como curl para acessar pelo terminal (curl YOUR_SERVICE_URL, por exemplo).
    3. Cada vez que você acessa o URL, o serviço avalia a flag de recurso e retorna o valor atual dela no formato JSON. Exemplo:

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

Você implantou um serviço Google Cloud que lê uma flag de recurso gerenciada pelo App Lifecycle Manager. Você pode mudar o valor da flag e criar um novo lançamento para ver o aplicativo receber a mudança.

Limpar

Para evitar cobranças na conta do Google Cloud pelos recursos usados nesta página, siga as etapas abaixo.

Excluir o projeto

Se você implantou a solução em um novo projeto do Google Cloud e não precisa mais dele, exclua-o seguindo estas etapas:

  1. No console Google Cloud , acesse a página Gerenciar recursos.

    Acessar "Gerenciar recursos"

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir.
  3. No prompt, digite o ID do projeto e clique em Encerrar.

A seguir