This guide explains how to implement App Lifecycle Manager feature flags in a multi-tenant environment without modifying your existing binary deployment process.
Prerequisites
Before you begin, ensure you have:
- Completed the Deploy feature flags quickstart.
- A
gcloudenvironment configured to manage App Lifecycle Manager resources. - An existing SaaS offering. For more information about how to create a SaaS offering, see Create a SaaS offering.
Resource modeling
In a multi-tenant setup, we recommend that you define a unit kind for your service or application, and a unit for every instance of the service or application (representing a tenant or deployment).
To implement feature flags in a multi-tenant environment, define Common Expression Language (CEL) attributes that identify your tenants, configure your application to inject tenant identifiers at runtime, and use evaluation rules to affect features for specific tenants.
For simpler cases, you can also manually create separate rollouts for each customer.
1. Create SaaS offering (if not already done)
gcloud beta app-lifecycle-manager saas create "SAAS_NAME" \
--project="PROJECT_ID" \
--location="global" \
--locations=name="LOCATION_1"
2. Create UnitKind
gcloud beta app-lifecycle-manager unit-kinds create "tenant-service-kind" \
--project="PROJECT_ID" \
--location="global" \
--saas="SAAS_NAME"
3. Create units for tenants
When creating units, use Labels to categorize tenant services into groups (e.g., group=beta, group=preview, group=all).
# Create a unit for Tenant A (Beta group)
gcloud beta app-lifecycle-manager units create "tenant-a-service" \
--unit-kind="tenant-service-kind" \
--location="LOCATION_1" \
--labels="group=beta"
# Create a unit for Tenant B (Standard group)
gcloud beta app-lifecycle-manager units create "tenant-b-service" \
--unit-kind="tenant-service-kind" \
--location="LOCATION_1" \
--labels="group=all"
Define attributes and flags
You must formally define attributes (like customerID) to ensure type safety
in evaluation rules.
1. Create the customerID attribute
gcloud beta app-lifecycle-manager flags attributes create "customer-id-attr" \
--key="customerID" \
--attribute-value-type="STRING" \
--location=global
2. Create the feature flag
gcloud beta app-lifecycle-manager flags create "enhanced-search" \
--key="enhanced-search" \
--flag-value-type=BOOL \
--unit-kind="tenant-service-kind"
Application integration
Integrate the OpenFeature SDK into your service. Your application must inject
the customerID into the context at runtime.
Go Example:
// Inject customerID into the evaluation context
evalCtx := map[string]any{
"customerID": currentTenant.ID,
}
// Evaluate the flag
isEnabled, err := client.BooleanValue(
context.Background(),
"enhanced-search",
false,
evalCtx,
)
Configure tenant-specific targeting
Use evaluation rules to enable a feature for specific customers.
gcloud beta app-lifecycle-manager flags update "enhanced-search" \
--location="global"
--evaluation-spec='{
"rules": [{
"id": "allowlist-for-premium-tenants",
"condition": "customerID in [\"tenant-xyz-123\", \"tenant-abc-789\"]",
"target": "Enabled"
}],
"defaultTarget": "Disabled",
"attributes": ["projects/PROJECT_ID/locations/global/flagAttributes/customer-id-attr"]
}'
Manual gradual rollout with filters
For simpler use cases, you can emulate waves by triggering separate rollouts manually for each customer label.
1. Create revision and release
# Create a Revision (Snapshot)
gcloud beta app-lifecycle-manager flags revisions create "enhanced-search-rev-1" \
--location=global \
--flag="enhanced-search"
# Create a Release
gcloud beta app-lifecycle-manager flags releases create "release-of-enhanced-search" \
--location=global \
--unit-kind="tenant-service-kind" \
--revisions="enhanced-search-rev-1"
2. Trigger manual rollouts
You can manually orchestrate the rollout by triggering separate operations per target group using --unit-filter.
# Rollout to Beta group first
gcloud beta app-lifecycle-manager rollouts create "beta-rollout" \
--flag-release="release-of-enhanced-search" \
--rollout-kind="rollout-kind-of-enhanced-search" \
--location=global \
--rollout-orchestration-strategy="Google.Cloud.Simple.AllAtOnce" \
--unit-filter="labels.group == beta"
# After verification, rollout to the rest of the fleet
gcloud beta app-lifecycle-manager rollouts create "full-rollout" \
--flag-release="release-of-enhanced-search" \
--rollout-kind="rollout-kind-of-enhanced-search" \
--location=global \
--rollout-orchestration-strategy="Google.Cloud.Production" \
--unit-filter="labels.group == all"
What's next
- Learn about Experimentation and A/B Testing.
- Learn about Troubleshooting.