Usar flags de recursos independentes
Saiba como usar as flags de recurso do App Lifecycle Manager como um serviço independente para gerenciar a disponibilidade de recursos nos seus aplicativos, mesmo que eles não sejam implantados ou gerenciados pelo App Lifecycle Manager.
Introdução
Neste guia de início rápido, mostramos como usar os recursos robustos de flag de recurso e lançamento controlado do App Lifecycle Manager sem precisar usá-lo para provisionamento de infraestrutura (como implantar VMs ou serviços do Cloud Run usando blueprints do Terraform). Essa abordagem é ideal se você gerencia a infraestrutura do aplicativo de forma independente, mas quer usar o App Lifecycle Manager para gerenciar as flag de recurso com segurança.
Nessa abordagem independente, você vai:
- Modele seu sistema com recursos leves do App Lifecycle Manager:crie
Unitsdo App Lifecycle Manager para representar componentes da sua infraestrutura atual (por exemplo, uma implantação de microsserviço específica, um ambiente de locatário, uma única instância binária). Essas unidades atuam apenas como destinos para configurações de flag e não envolvem a implantação de infraestrutura usando blueprints do App Lifecycle Manager. - Definir e distribuir flags:use a API App Lifecycle Manager ou o console do Google Cloud para criar flags de recurso. Gerencie o ciclo de vida deles usando o App Lifecycle Manager
Rolloutspara garantir a propagação segura e gradual das mudanças de configuração para oUnitsmodelado. Isso garante consistência e segurança operacional, mesmo ao gerenciar apenas flags. - Integração com o aplicativo: use o SDK do OpenFeature com o provedor do
flagdno código do aplicativo (em execução em qualquer lugar: localmente, no local, nuvem autogerenciada). Configure-o para se conectar ao serviço de flag do App Lifecycle Manager (saasconfig.googleapis.com), autenticar e se identificar usando o nome do recursoUnitcorrespondente para buscar os valores de flag corretos.
Essa abordagem permite que você se beneficie da distribuição gerenciada e segura de flags sem alterar os pipelines de implantação ou as ferramentas de gestão de infraestrutura atuais.
As flags de recurso do App Lifecycle Manager estão em pré-lançamento particular. O acesso requer inclusão na lista de permissões. Para solicitar acesso para sua organização ou projeto, preencha este formulário.
Este guia de início rápido usa um aplicativo Python básico executado localmente para demonstrar o acesso às flags, simulando como seu aplicativo atual seria integrado.
Objetivos
- Configure um novo projeto do Google Cloud ou use um atual.
- Ative as APIs necessárias (App Lifecycle Manager e SaaS Config).
- Conceder as permissões necessárias do Identity and Access Management para criação de recursos e leitura de sinalizações.
- Criar recursos mínimos do App Lifecycle Manager (oferta de app, tipo de unidade, unidade) para modelar um componente de aplicativo sem implantar infraestrutura.
- Defina um recurso de flag de recurso associado ao tipo de unidade.
- Crie um mecanismo de lançamento de flag (tipo de lançamento) que defina a estratégia de distribuição.
- Distribua a configuração inicial da flag usando um lançamento do App Lifecycle Manager.
- Execute localmente um aplicativo Python de exemplo que se conecta ao serviço de flag do App Lifecycle Manager e avalia a flag para a unidade modelada.
- Atualize o valor da flag, crie uma nova versão dela e distribua a mudança.
- Verifique se o aplicativo detecta o valor atualizado da flag.
Antes de começar
-
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, if any are not already enabled.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. 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.-
Install the Google Cloud CLI.
-
Configure the gcloud CLI to use your federated identity.
For more information, see Sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init -
Instale o Python:verifique se o Python 3.7 ou mais recente está instalado na máquina em que você vai executar o aplicativo de exemplo. Você também precisa do pip para instalar dependências.
python --version
pip --version
-
Autentique a gcloud para o Application Default Credentials (ADC): o script Python local usa o ADC para autenticar nos serviços do Google Cloud . Faça login usando sua conta de usuário:
gcloud auth application-default login
-
Conceder permissões de identidade do aplicativo:seu aplicativo precisa de permissão para ler as configurações de flag do serviço de configuração de SaaS. Conceda o papel `roles/saasconfig.viewer` à identidade que o aplicativo vai usar. Para este guia de início rápido, use o ADC localmente com sua conta de usuário e conceda o papel ao seu endereço de e-mail:
Substitua PROJECT_ID pelo ID do projeto do Google Cloud e YOUR_EMAIL_ADDRESS pelo e-mail associado ao seu login da CLI.gcloud projects add-iam-policy-binding PROJECT_ID \ --member="user:YOUR_EMAIL_ADDRESS" \ --role="roles/saasconfig.viewer"
Criar recursos mínimos do App Lifecycle Manager
Mesmo que não estejamos implantando infraestrutura com o App Lifecycle Manager, precisamos de alguns recursos para organizar, segmentar e distribuir nossas flags com segurança. Esses recursos representam os componentes de aplicativo existentes no App Lifecycle Manager.
Definir variáveis:defina variáveis de ambiente para nomes e locais de 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"Criar uma oferta de app:funciona como um contêiner de nível superior para a configuração do serviço, incluindo 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}Criar um tipo de unidade:define o tipo de componente que você está modelando. É importante ressaltar que não fornecemos um blueprint porque não gerenciamos a infraestrutura.
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}Criar uma unidade:representa uma instância específica do aplicativo.
gcloud beta app-lifecycle-manager units create ${UNIT_ID} \ --project=${PROJECT_ID} \ --unit-kind=${UNIT_KIND_ID} \ --location=${LOCATION_1}
Definir e implantar a flag de recurso
Agora, crie a flag de recurso real e use o mecanismo de lançamento do App Lifecycle Manager para disponibilizar a configuração dela para as unidades que você criou.
Defina as variáveis de flag:
export FLAG_ID="standalone-flag-01" export FLAG_KEY="enable-beta-feature"Crie o recurso, a revisão e a versão da 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=globalCriar um tipo de lançamento:defina a estratégia para distribuir as mudanças de 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=globalCriar o lançamento:iniciar o processo de distribuição.
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=globalMonitore o lançamento:verifique se a implantação foi bem-sucedida antes de continuar.
gcloud beta app-lifecycle-manager rollouts describe ${ROLLOUT_ID_1} \ --project=${PROJECT_ID} \ --location=global
Configurar a infraestrutura independente
Em uma configuração independente, você gerencia sua própria hospedagem de aplicativos (por exemplo, Cloud Run ou GKE) e usa o App Lifecycle Manager apenas para Config Sync. O código do aplicativo permanece padrão em todas as implantações. Ele só exige que a variável de ambiente FLAGD_SOURCE_PROVIDER_ID esteja presente no ambiente de execução para se conectar ao serviço de configuração de SaaS.
É possível mapear as definições de unidade do App Lifecycle Manager para as definições de implantação padrão do Terraform transmitindo o caminho construído como uma variável de ambiente.
Defina sua infraestrutura:mapeie o caminho no modelo de implantação (por exemplo,
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}" } } } }Defina os valores das variáveis:forneça os parâmetros da unidade de configuração em um arquivo de variáveis associado (por exemplo,
terraform.tfvars).project_id = "PROJECT_ID" region = "LOCATION_1" unit_id = "UNIT_ID"
Integrar e executar o aplicativo de exemplo
Execute um aplicativo Python de exemplo localmente para se conectar ao serviço de sinalização do App Lifecycle Manager usando as configurações de unidade modeladas.
Crie o diretório e os arquivos do projeto:
mkdir saas_flags_standalone_app cd saas_flags_standalone_appCrie
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.0Instale as dependências:
pip install -r requirements.txtCrie o arquivo 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)Execute o aplicativo:
export FLAGD_SOURCE_PROVIDER_ID="projects/${PROJECT_ID}/locations/${LOCATION_1}/featureFlagsConfigs/${UNIT_ID}" python app.pyVerifique o valor inicial da flag:execute uma verificação no endpoint local em um terminal secundário.
curl http://localhost:8080
Atualizar a flag e distribuir a mudança
Modifique o estado de execução da definição da flag e distribua a atualização para os destinos conectados.
Atualize o recurso de 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=globalCrie um novo lançamento para a atualização:
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=globalMonitore o novo lançamento:
gcloud beta app-lifecycle-manager rollouts describe ${ROLLOUT_ID_2} \ --project=${PROJECT_ID} \ --location=globalVerifique a mudança no aplicativo em execução:
curl http://localhost:8080
Limpar
Para evitar cobranças na conta do Google Cloud pelos recursos usados nesta página, siga as etapas abaixo.
- Pressione
Ctrl+Cno terminal em queapp.pyestá em execução para interromper o aplicativo Python local. - Defina o estado da flag.
- Crie um novo lançamento para remover as flags obsoletas.
Depois que o lançamento for concluído e as flags obsoletas forem removidas, exclua os recursos do 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} --quietExclua o diretório local:
cd .. rm -rf saas_flags_standalone_app
A seguir
- Leia a visão geral das flags de recurso do App Lifecycle Manager para mais detalhes conceituais.
- Confira o guia de início rápido sobre como implantar flags de recurso para ver como as flags se integram às implantações gerenciadas pelo App Lifecycle Manager.