The gcp:bigquery/appProfile:AppProfile resource, part of the Pulumi GCP provider, defines how Cloud Bigtable routes traffic from an application to clusters within a Bigtable instance. This guide focuses on three capabilities: multi-cluster routing strategies, single-cluster routing for consistency, and traffic priority isolation.
App profiles belong to Bigtable instances and reference cluster IDs that must already exist. The examples are intentionally small. Combine them with your own Bigtable instances and cluster configurations.
Route requests to any available cluster
Applications that prioritize availability over strict consistency can route to the nearest cluster and fail over automatically when issues occur.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const instance = new gcp.bigtable.Instance("instance", {
name: "bt-instance",
clusters: [
{
clusterId: "cluster-1",
zone: "us-central1-a",
numNodes: 3,
storageType: "HDD",
},
{
clusterId: "cluster-2",
zone: "us-central1-b",
numNodes: 3,
storageType: "HDD",
},
{
clusterId: "cluster-3",
zone: "us-central1-c",
numNodes: 3,
storageType: "HDD",
},
],
deletionProtection: true,
});
const ap = new gcp.bigtable.AppProfile("ap", {
instance: instance.name,
appProfileId: "bt-profile",
multiClusterRoutingUseAny: true,
ignoreWarnings: true,
});
import pulumi
import pulumi_gcp as gcp
instance = gcp.bigtable.Instance("instance",
name="bt-instance",
clusters=[
{
"cluster_id": "cluster-1",
"zone": "us-central1-a",
"num_nodes": 3,
"storage_type": "HDD",
},
{
"cluster_id": "cluster-2",
"zone": "us-central1-b",
"num_nodes": 3,
"storage_type": "HDD",
},
{
"cluster_id": "cluster-3",
"zone": "us-central1-c",
"num_nodes": 3,
"storage_type": "HDD",
},
],
deletion_protection=True)
ap = gcp.bigtable.AppProfile("ap",
instance=instance.name,
app_profile_id="bt-profile",
multi_cluster_routing_use_any=True,
ignore_warnings=True)
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/bigtable"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
instance, err := bigtable.NewInstance(ctx, "instance", &bigtable.InstanceArgs{
Name: pulumi.String("bt-instance"),
Clusters: bigtable.InstanceClusterArray{
&bigtable.InstanceClusterArgs{
ClusterId: pulumi.String("cluster-1"),
Zone: pulumi.String("us-central1-a"),
NumNodes: pulumi.Int(3),
StorageType: pulumi.String("HDD"),
},
&bigtable.InstanceClusterArgs{
ClusterId: pulumi.String("cluster-2"),
Zone: pulumi.String("us-central1-b"),
NumNodes: pulumi.Int(3),
StorageType: pulumi.String("HDD"),
},
&bigtable.InstanceClusterArgs{
ClusterId: pulumi.String("cluster-3"),
Zone: pulumi.String("us-central1-c"),
NumNodes: pulumi.Int(3),
StorageType: pulumi.String("HDD"),
},
},
DeletionProtection: pulumi.Bool(true),
})
if err != nil {
return err
}
_, err = bigtable.NewAppProfile(ctx, "ap", &bigtable.AppProfileArgs{
Instance: instance.Name,
AppProfileId: pulumi.String("bt-profile"),
MultiClusterRoutingUseAny: pulumi.Bool(true),
IgnoreWarnings: pulumi.Bool(true),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var instance = new Gcp.BigTable.Instance("instance", new()
{
Name = "bt-instance",
Clusters = new[]
{
new Gcp.BigTable.Inputs.InstanceClusterArgs
{
ClusterId = "cluster-1",
Zone = "us-central1-a",
NumNodes = 3,
StorageType = "HDD",
},
new Gcp.BigTable.Inputs.InstanceClusterArgs
{
ClusterId = "cluster-2",
Zone = "us-central1-b",
NumNodes = 3,
StorageType = "HDD",
},
new Gcp.BigTable.Inputs.InstanceClusterArgs
{
ClusterId = "cluster-3",
Zone = "us-central1-c",
NumNodes = 3,
StorageType = "HDD",
},
},
DeletionProtection = true,
});
var ap = new Gcp.BigTable.AppProfile("ap", new()
{
Instance = instance.Name,
AppProfileId = "bt-profile",
MultiClusterRoutingUseAny = true,
IgnoreWarnings = true,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.bigtable.Instance;
import com.pulumi.gcp.bigtable.InstanceArgs;
import com.pulumi.gcp.bigtable.inputs.InstanceClusterArgs;
import com.pulumi.gcp.bigtable.AppProfile;
import com.pulumi.gcp.bigtable.AppProfileArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var instance = new Instance("instance", InstanceArgs.builder()
.name("bt-instance")
.clusters(
InstanceClusterArgs.builder()
.clusterId("cluster-1")
.zone("us-central1-a")
.numNodes(3)
.storageType("HDD")
.build(),
InstanceClusterArgs.builder()
.clusterId("cluster-2")
.zone("us-central1-b")
.numNodes(3)
.storageType("HDD")
.build(),
InstanceClusterArgs.builder()
.clusterId("cluster-3")
.zone("us-central1-c")
.numNodes(3)
.storageType("HDD")
.build())
.deletionProtection(true)
.build());
var ap = new AppProfile("ap", AppProfileArgs.builder()
.instance(instance.name())
.appProfileId("bt-profile")
.multiClusterRoutingUseAny(true)
.ignoreWarnings(true)
.build());
}
}
resources:
instance:
type: gcp:bigtable:Instance
properties:
name: bt-instance
clusters:
- clusterId: cluster-1
zone: us-central1-a
numNodes: 3
storageType: HDD
- clusterId: cluster-2
zone: us-central1-b
numNodes: 3
storageType: HDD
- clusterId: cluster-3
zone: us-central1-c
numNodes: 3
storageType: HDD
deletionProtection: true
ap:
type: gcp:bigtable:AppProfile
properties:
instance: ${instance.name}
appProfileId: bt-profile
multiClusterRoutingUseAny: true
ignoreWarnings: true
When multiClusterRoutingUseAny is true, Bigtable routes read and write requests to the nearest available cluster. If a cluster experiences transient errors or delays, requests fail over to the next nearest cluster. This sacrifices read-your-writes consistency for improved availability. The instance property references the Bigtable instance name, and appProfileId sets the profile’s unique identifier.
Pin requests to a single cluster
Workloads requiring strong consistency or transactional writes route all traffic to a specific cluster.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const instance = new gcp.bigtable.Instance("instance", {
name: "bt-instance",
clusters: [{
clusterId: "cluster-1",
zone: "us-central1-b",
numNodes: 3,
storageType: "HDD",
}],
deletionProtection: true,
});
const ap = new gcp.bigtable.AppProfile("ap", {
instance: instance.name,
appProfileId: "bt-profile",
singleClusterRouting: {
clusterId: "cluster-1",
allowTransactionalWrites: true,
},
ignoreWarnings: true,
});
import pulumi
import pulumi_gcp as gcp
instance = gcp.bigtable.Instance("instance",
name="bt-instance",
clusters=[{
"cluster_id": "cluster-1",
"zone": "us-central1-b",
"num_nodes": 3,
"storage_type": "HDD",
}],
deletion_protection=True)
ap = gcp.bigtable.AppProfile("ap",
instance=instance.name,
app_profile_id="bt-profile",
single_cluster_routing={
"cluster_id": "cluster-1",
"allow_transactional_writes": True,
},
ignore_warnings=True)
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/bigtable"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
instance, err := bigtable.NewInstance(ctx, "instance", &bigtable.InstanceArgs{
Name: pulumi.String("bt-instance"),
Clusters: bigtable.InstanceClusterArray{
&bigtable.InstanceClusterArgs{
ClusterId: pulumi.String("cluster-1"),
Zone: pulumi.String("us-central1-b"),
NumNodes: pulumi.Int(3),
StorageType: pulumi.String("HDD"),
},
},
DeletionProtection: pulumi.Bool(true),
})
if err != nil {
return err
}
_, err = bigtable.NewAppProfile(ctx, "ap", &bigtable.AppProfileArgs{
Instance: instance.Name,
AppProfileId: pulumi.String("bt-profile"),
SingleClusterRouting: &bigtable.AppProfileSingleClusterRoutingArgs{
ClusterId: pulumi.String("cluster-1"),
AllowTransactionalWrites: pulumi.Bool(true),
},
IgnoreWarnings: pulumi.Bool(true),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var instance = new Gcp.BigTable.Instance("instance", new()
{
Name = "bt-instance",
Clusters = new[]
{
new Gcp.BigTable.Inputs.InstanceClusterArgs
{
ClusterId = "cluster-1",
Zone = "us-central1-b",
NumNodes = 3,
StorageType = "HDD",
},
},
DeletionProtection = true,
});
var ap = new Gcp.BigTable.AppProfile("ap", new()
{
Instance = instance.Name,
AppProfileId = "bt-profile",
SingleClusterRouting = new Gcp.BigTable.Inputs.AppProfileSingleClusterRoutingArgs
{
ClusterId = "cluster-1",
AllowTransactionalWrites = true,
},
IgnoreWarnings = true,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.bigtable.Instance;
import com.pulumi.gcp.bigtable.InstanceArgs;
import com.pulumi.gcp.bigtable.inputs.InstanceClusterArgs;
import com.pulumi.gcp.bigtable.AppProfile;
import com.pulumi.gcp.bigtable.AppProfileArgs;
import com.pulumi.gcp.bigtable.inputs.AppProfileSingleClusterRoutingArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var instance = new Instance("instance", InstanceArgs.builder()
.name("bt-instance")
.clusters(InstanceClusterArgs.builder()
.clusterId("cluster-1")
.zone("us-central1-b")
.numNodes(3)
.storageType("HDD")
.build())
.deletionProtection(true)
.build());
var ap = new AppProfile("ap", AppProfileArgs.builder()
.instance(instance.name())
.appProfileId("bt-profile")
.singleClusterRouting(AppProfileSingleClusterRoutingArgs.builder()
.clusterId("cluster-1")
.allowTransactionalWrites(true)
.build())
.ignoreWarnings(true)
.build());
}
}
resources:
instance:
type: gcp:bigtable:Instance
properties:
name: bt-instance
clusters:
- clusterId: cluster-1
zone: us-central1-b
numNodes: 3
storageType: HDD
deletionProtection: true
ap:
type: gcp:bigtable:AppProfile
properties:
instance: ${instance.name}
appProfileId: bt-profile
singleClusterRouting:
clusterId: cluster-1
allowTransactionalWrites: true
ignoreWarnings: true
The singleClusterRouting property pins all requests to the specified clusterId. Setting allowTransactionalWrites to true enables transactional operations, which require single-cluster routing to maintain consistency. This configuration ensures read-your-writes consistency at the cost of availability if the cluster becomes unavailable.
Route to a subset of clusters
Some applications need multi-cluster availability but want to limit routing to specific clusters in particular regions.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const instance = new gcp.bigtable.Instance("instance", {
name: "bt-instance",
clusters: [
{
clusterId: "cluster-1",
zone: "us-central1-a",
numNodes: 3,
storageType: "HDD",
},
{
clusterId: "cluster-2",
zone: "us-central1-b",
numNodes: 3,
storageType: "HDD",
},
{
clusterId: "cluster-3",
zone: "us-central1-c",
numNodes: 3,
storageType: "HDD",
},
],
deletionProtection: true,
});
const ap = new gcp.bigtable.AppProfile("ap", {
instance: instance.name,
appProfileId: "bt-profile",
multiClusterRoutingUseAny: true,
multiClusterRoutingClusterIds: [
"cluster-1",
"cluster-2",
],
ignoreWarnings: true,
});
import pulumi
import pulumi_gcp as gcp
instance = gcp.bigtable.Instance("instance",
name="bt-instance",
clusters=[
{
"cluster_id": "cluster-1",
"zone": "us-central1-a",
"num_nodes": 3,
"storage_type": "HDD",
},
{
"cluster_id": "cluster-2",
"zone": "us-central1-b",
"num_nodes": 3,
"storage_type": "HDD",
},
{
"cluster_id": "cluster-3",
"zone": "us-central1-c",
"num_nodes": 3,
"storage_type": "HDD",
},
],
deletion_protection=True)
ap = gcp.bigtable.AppProfile("ap",
instance=instance.name,
app_profile_id="bt-profile",
multi_cluster_routing_use_any=True,
multi_cluster_routing_cluster_ids=[
"cluster-1",
"cluster-2",
],
ignore_warnings=True)
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/bigtable"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
instance, err := bigtable.NewInstance(ctx, "instance", &bigtable.InstanceArgs{
Name: pulumi.String("bt-instance"),
Clusters: bigtable.InstanceClusterArray{
&bigtable.InstanceClusterArgs{
ClusterId: pulumi.String("cluster-1"),
Zone: pulumi.String("us-central1-a"),
NumNodes: pulumi.Int(3),
StorageType: pulumi.String("HDD"),
},
&bigtable.InstanceClusterArgs{
ClusterId: pulumi.String("cluster-2"),
Zone: pulumi.String("us-central1-b"),
NumNodes: pulumi.Int(3),
StorageType: pulumi.String("HDD"),
},
&bigtable.InstanceClusterArgs{
ClusterId: pulumi.String("cluster-3"),
Zone: pulumi.String("us-central1-c"),
NumNodes: pulumi.Int(3),
StorageType: pulumi.String("HDD"),
},
},
DeletionProtection: pulumi.Bool(true),
})
if err != nil {
return err
}
_, err = bigtable.NewAppProfile(ctx, "ap", &bigtable.AppProfileArgs{
Instance: instance.Name,
AppProfileId: pulumi.String("bt-profile"),
MultiClusterRoutingUseAny: pulumi.Bool(true),
MultiClusterRoutingClusterIds: pulumi.StringArray{
pulumi.String("cluster-1"),
pulumi.String("cluster-2"),
},
IgnoreWarnings: pulumi.Bool(true),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var instance = new Gcp.BigTable.Instance("instance", new()
{
Name = "bt-instance",
Clusters = new[]
{
new Gcp.BigTable.Inputs.InstanceClusterArgs
{
ClusterId = "cluster-1",
Zone = "us-central1-a",
NumNodes = 3,
StorageType = "HDD",
},
new Gcp.BigTable.Inputs.InstanceClusterArgs
{
ClusterId = "cluster-2",
Zone = "us-central1-b",
NumNodes = 3,
StorageType = "HDD",
},
new Gcp.BigTable.Inputs.InstanceClusterArgs
{
ClusterId = "cluster-3",
Zone = "us-central1-c",
NumNodes = 3,
StorageType = "HDD",
},
},
DeletionProtection = true,
});
var ap = new Gcp.BigTable.AppProfile("ap", new()
{
Instance = instance.Name,
AppProfileId = "bt-profile",
MultiClusterRoutingUseAny = true,
MultiClusterRoutingClusterIds = new[]
{
"cluster-1",
"cluster-2",
},
IgnoreWarnings = true,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.bigtable.Instance;
import com.pulumi.gcp.bigtable.InstanceArgs;
import com.pulumi.gcp.bigtable.inputs.InstanceClusterArgs;
import com.pulumi.gcp.bigtable.AppProfile;
import com.pulumi.gcp.bigtable.AppProfileArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var instance = new Instance("instance", InstanceArgs.builder()
.name("bt-instance")
.clusters(
InstanceClusterArgs.builder()
.clusterId("cluster-1")
.zone("us-central1-a")
.numNodes(3)
.storageType("HDD")
.build(),
InstanceClusterArgs.builder()
.clusterId("cluster-2")
.zone("us-central1-b")
.numNodes(3)
.storageType("HDD")
.build(),
InstanceClusterArgs.builder()
.clusterId("cluster-3")
.zone("us-central1-c")
.numNodes(3)
.storageType("HDD")
.build())
.deletionProtection(true)
.build());
var ap = new AppProfile("ap", AppProfileArgs.builder()
.instance(instance.name())
.appProfileId("bt-profile")
.multiClusterRoutingUseAny(true)
.multiClusterRoutingClusterIds(
"cluster-1",
"cluster-2")
.ignoreWarnings(true)
.build());
}
}
resources:
instance:
type: gcp:bigtable:Instance
properties:
name: bt-instance
clusters:
- clusterId: cluster-1
zone: us-central1-a
numNodes: 3
storageType: HDD
- clusterId: cluster-2
zone: us-central1-b
numNodes: 3
storageType: HDD
- clusterId: cluster-3
zone: us-central1-c
numNodes: 3
storageType: HDD
deletionProtection: true
ap:
type: gcp:bigtable:AppProfile
properties:
instance: ${instance.name}
appProfileId: bt-profile
multiClusterRoutingUseAny: true
multiClusterRoutingClusterIds:
- cluster-1
- cluster-2
ignoreWarnings: true
Combining multiClusterRoutingUseAny with multiClusterRoutingClusterIds restricts routing to the specified clusters. Bigtable routes to the nearest cluster in the list and fails over within that subset. This balances availability with control over which clusters handle traffic.
Set traffic priority for resource isolation
Applications with different performance requirements can use priority settings to prevent lower-priority workloads from affecting critical operations.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const instance = new gcp.bigtable.Instance("instance", {
name: "bt-instance",
clusters: [{
clusterId: "cluster-1",
zone: "us-central1-b",
numNodes: 3,
storageType: "HDD",
}],
deletionProtection: true,
});
const ap = new gcp.bigtable.AppProfile("ap", {
instance: instance.name,
appProfileId: "bt-profile",
singleClusterRouting: {
clusterId: "cluster-1",
allowTransactionalWrites: true,
},
standardIsolation: {
priority: "PRIORITY_LOW",
},
ignoreWarnings: true,
});
import pulumi
import pulumi_gcp as gcp
instance = gcp.bigtable.Instance("instance",
name="bt-instance",
clusters=[{
"cluster_id": "cluster-1",
"zone": "us-central1-b",
"num_nodes": 3,
"storage_type": "HDD",
}],
deletion_protection=True)
ap = gcp.bigtable.AppProfile("ap",
instance=instance.name,
app_profile_id="bt-profile",
single_cluster_routing={
"cluster_id": "cluster-1",
"allow_transactional_writes": True,
},
standard_isolation={
"priority": "PRIORITY_LOW",
},
ignore_warnings=True)
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/bigtable"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
instance, err := bigtable.NewInstance(ctx, "instance", &bigtable.InstanceArgs{
Name: pulumi.String("bt-instance"),
Clusters: bigtable.InstanceClusterArray{
&bigtable.InstanceClusterArgs{
ClusterId: pulumi.String("cluster-1"),
Zone: pulumi.String("us-central1-b"),
NumNodes: pulumi.Int(3),
StorageType: pulumi.String("HDD"),
},
},
DeletionProtection: pulumi.Bool(true),
})
if err != nil {
return err
}
_, err = bigtable.NewAppProfile(ctx, "ap", &bigtable.AppProfileArgs{
Instance: instance.Name,
AppProfileId: pulumi.String("bt-profile"),
SingleClusterRouting: &bigtable.AppProfileSingleClusterRoutingArgs{
ClusterId: pulumi.String("cluster-1"),
AllowTransactionalWrites: pulumi.Bool(true),
},
StandardIsolation: &bigtable.AppProfileStandardIsolationArgs{
Priority: pulumi.String("PRIORITY_LOW"),
},
IgnoreWarnings: pulumi.Bool(true),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var instance = new Gcp.BigTable.Instance("instance", new()
{
Name = "bt-instance",
Clusters = new[]
{
new Gcp.BigTable.Inputs.InstanceClusterArgs
{
ClusterId = "cluster-1",
Zone = "us-central1-b",
NumNodes = 3,
StorageType = "HDD",
},
},
DeletionProtection = true,
});
var ap = new Gcp.BigTable.AppProfile("ap", new()
{
Instance = instance.Name,
AppProfileId = "bt-profile",
SingleClusterRouting = new Gcp.BigTable.Inputs.AppProfileSingleClusterRoutingArgs
{
ClusterId = "cluster-1",
AllowTransactionalWrites = true,
},
StandardIsolation = new Gcp.BigTable.Inputs.AppProfileStandardIsolationArgs
{
Priority = "PRIORITY_LOW",
},
IgnoreWarnings = true,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.bigtable.Instance;
import com.pulumi.gcp.bigtable.InstanceArgs;
import com.pulumi.gcp.bigtable.inputs.InstanceClusterArgs;
import com.pulumi.gcp.bigtable.AppProfile;
import com.pulumi.gcp.bigtable.AppProfileArgs;
import com.pulumi.gcp.bigtable.inputs.AppProfileSingleClusterRoutingArgs;
import com.pulumi.gcp.bigtable.inputs.AppProfileStandardIsolationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var instance = new Instance("instance", InstanceArgs.builder()
.name("bt-instance")
.clusters(InstanceClusterArgs.builder()
.clusterId("cluster-1")
.zone("us-central1-b")
.numNodes(3)
.storageType("HDD")
.build())
.deletionProtection(true)
.build());
var ap = new AppProfile("ap", AppProfileArgs.builder()
.instance(instance.name())
.appProfileId("bt-profile")
.singleClusterRouting(AppProfileSingleClusterRoutingArgs.builder()
.clusterId("cluster-1")
.allowTransactionalWrites(true)
.build())
.standardIsolation(AppProfileStandardIsolationArgs.builder()
.priority("PRIORITY_LOW")
.build())
.ignoreWarnings(true)
.build());
}
}
resources:
instance:
type: gcp:bigtable:Instance
properties:
name: bt-instance
clusters:
- clusterId: cluster-1
zone: us-central1-b
numNodes: 3
storageType: HDD
deletionProtection: true
ap:
type: gcp:bigtable:AppProfile
properties:
instance: ${instance.name}
appProfileId: bt-profile
singleClusterRouting:
clusterId: cluster-1
allowTransactionalWrites: true
standardIsolation:
priority: PRIORITY_LOW
ignoreWarnings: true
The standardIsolation property with priority set to PRIORITY_LOW marks this app profile’s traffic as lower priority. Bigtable uses this to isolate batch or analytical workloads from production traffic, preventing resource contention. This works with both single-cluster and multi-cluster routing policies.
Beyond these examples
These snippets focus on specific app profile features: multi-cluster and single-cluster routing, cluster subset selection, and traffic priority isolation. They’re intentionally minimal rather than full Bigtable deployments.
The examples reference pre-existing infrastructure such as Bigtable instances with one or more clusters. They focus on configuring routing policies rather than provisioning the underlying instance infrastructure.
To keep things focused, common app profile patterns are omitted, including:
- Data Boost isolation for read-only workloads (dataBoostIsolationReadOnly)
- Row affinity sticky routing (rowAffinity)
- App profile descriptions and metadata
These omissions are intentional: the goal is to illustrate how each routing policy is wired, not provide drop-in Bigtable modules. See the Bigtable AppProfile resource reference for all available configuration options.
Let's configure GCP Bigtable App Profiles
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Routing Configuration
singleClusterRouting to route all traffic to one cluster with guaranteed consistency. Use multiClusterRoutingUseAny to route to the nearest available cluster with automatic failover, which improves availability but sacrifices read-your-writes consistency.singleClusterRouting or multiClusterRoutingUseAny, never both.multiClusterRoutingUseAny to true and specify cluster IDs in multiClusterRoutingClusterIds. For example, you can route to only cluster-1 and cluster-2 even if cluster-3 exists.Consistency & Performance
rowAffinity to improve consistency or singleClusterRouting for guaranteed consistency.Resource Configuration
appProfileId must match the format [_a-zA-Z0-9][-_.a-zA-Z0-9]*, meaning it can start with underscore, letter, or number, followed by hyphens, underscores, letters, or numbers.appProfileId, project, and instance properties cannot be changed after the app profile is created.ignoreWarnings to true bypasses safety checks when deleting or updating the app profile. All examples in the schema use this flag.