The gcp:redis/cluster:Cluster resource, part of the Pulumi GCP provider, provisions a Google Cloud Memorystore Redis Cluster: a managed, distributed Redis deployment with configurable sharding, replication, and persistence. This guide focuses on four capabilities: high availability with zone distribution, cross-region replication for disaster recovery, persistence strategies (RDB and AOF), and customer-managed encryption keys.
Redis clusters require VPC networks with ServiceConnectionPolicy for Private Service Connect connectivity. They may also reference KMS keys for encryption or other clusters for cross-region replication. The examples are intentionally small. Combine them with your own network infrastructure and security policies.
Deploy a multi-zone cluster with high availability
Most Redis deployments start with a highly available cluster that distributes shards across multiple zones to survive zone failures.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const consumerNet = new gcp.compute.Network("consumer_net", {
name: "my-network",
autoCreateSubnetworks: false,
});
const consumerSubnet = new gcp.compute.Subnetwork("consumer_subnet", {
name: "my-subnet",
ipCidrRange: "10.0.0.248/29",
region: "us-central1",
network: consumerNet.id,
});
const _default = new gcp.networkconnectivity.ServiceConnectionPolicy("default", {
name: "my-policy",
location: "us-central1",
serviceClass: "gcp-memorystore-redis",
description: "my basic service connection policy",
network: consumerNet.id,
pscConfig: {
subnetworks: [consumerSubnet.id],
},
});
const cluster_ha = new gcp.redis.Cluster("cluster-ha", {
name: "ha-cluster",
shardCount: 3,
pscConfigs: [{
network: consumerNet.id,
}],
region: "us-central1",
replicaCount: 1,
nodeType: "REDIS_SHARED_CORE_NANO",
transitEncryptionMode: "TRANSIT_ENCRYPTION_MODE_DISABLED",
authorizationMode: "AUTH_MODE_DISABLED",
redisConfigs: {
"maxmemory-policy": "volatile-ttl",
},
deletionProtectionEnabled: true,
zoneDistributionConfig: {
mode: "MULTI_ZONE",
},
maintenancePolicy: {
weeklyMaintenanceWindows: [{
day: "MONDAY",
startTime: {
hours: 1,
minutes: 0,
seconds: 0,
nanos: 0,
},
}],
},
}, {
dependsOn: [_default],
});
import pulumi
import pulumi_gcp as gcp
consumer_net = gcp.compute.Network("consumer_net",
name="my-network",
auto_create_subnetworks=False)
consumer_subnet = gcp.compute.Subnetwork("consumer_subnet",
name="my-subnet",
ip_cidr_range="10.0.0.248/29",
region="us-central1",
network=consumer_net.id)
default = gcp.networkconnectivity.ServiceConnectionPolicy("default",
name="my-policy",
location="us-central1",
service_class="gcp-memorystore-redis",
description="my basic service connection policy",
network=consumer_net.id,
psc_config={
"subnetworks": [consumer_subnet.id],
})
cluster_ha = gcp.redis.Cluster("cluster-ha",
name="ha-cluster",
shard_count=3,
psc_configs=[{
"network": consumer_net.id,
}],
region="us-central1",
replica_count=1,
node_type="REDIS_SHARED_CORE_NANO",
transit_encryption_mode="TRANSIT_ENCRYPTION_MODE_DISABLED",
authorization_mode="AUTH_MODE_DISABLED",
redis_configs={
"maxmemory-policy": "volatile-ttl",
},
deletion_protection_enabled=True,
zone_distribution_config={
"mode": "MULTI_ZONE",
},
maintenance_policy={
"weekly_maintenance_windows": [{
"day": "MONDAY",
"start_time": {
"hours": 1,
"minutes": 0,
"seconds": 0,
"nanos": 0,
},
}],
},
opts = pulumi.ResourceOptions(depends_on=[default]))
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networkconnectivity"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/redis"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
consumerNet, err := compute.NewNetwork(ctx, "consumer_net", &compute.NetworkArgs{
Name: pulumi.String("my-network"),
AutoCreateSubnetworks: pulumi.Bool(false),
})
if err != nil {
return err
}
consumerSubnet, err := compute.NewSubnetwork(ctx, "consumer_subnet", &compute.SubnetworkArgs{
Name: pulumi.String("my-subnet"),
IpCidrRange: pulumi.String("10.0.0.248/29"),
Region: pulumi.String("us-central1"),
Network: consumerNet.ID(),
})
if err != nil {
return err
}
_default, err := networkconnectivity.NewServiceConnectionPolicy(ctx, "default", &networkconnectivity.ServiceConnectionPolicyArgs{
Name: pulumi.String("my-policy"),
Location: pulumi.String("us-central1"),
ServiceClass: pulumi.String("gcp-memorystore-redis"),
Description: pulumi.String("my basic service connection policy"),
Network: consumerNet.ID(),
PscConfig: &networkconnectivity.ServiceConnectionPolicyPscConfigArgs{
Subnetworks: pulumi.StringArray{
consumerSubnet.ID(),
},
},
})
if err != nil {
return err
}
_, err = redis.NewCluster(ctx, "cluster-ha", &redis.ClusterArgs{
Name: pulumi.String("ha-cluster"),
ShardCount: pulumi.Int(3),
PscConfigs: redis.ClusterPscConfigArray{
&redis.ClusterPscConfigArgs{
Network: consumerNet.ID(),
},
},
Region: pulumi.String("us-central1"),
ReplicaCount: pulumi.Int(1),
NodeType: pulumi.String("REDIS_SHARED_CORE_NANO"),
TransitEncryptionMode: pulumi.String("TRANSIT_ENCRYPTION_MODE_DISABLED"),
AuthorizationMode: pulumi.String("AUTH_MODE_DISABLED"),
RedisConfigs: pulumi.StringMap{
"maxmemory-policy": pulumi.String("volatile-ttl"),
},
DeletionProtectionEnabled: pulumi.Bool(true),
ZoneDistributionConfig: &redis.ClusterZoneDistributionConfigArgs{
Mode: pulumi.String("MULTI_ZONE"),
},
MaintenancePolicy: &redis.ClusterMaintenancePolicyArgs{
WeeklyMaintenanceWindows: redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowArray{
&redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs{
Day: pulumi.String("MONDAY"),
StartTime: &redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs{
Hours: pulumi.Int(1),
Minutes: pulumi.Int(0),
Seconds: pulumi.Int(0),
Nanos: pulumi.Int(0),
},
},
},
},
}, pulumi.DependsOn([]pulumi.Resource{
_default,
}))
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 consumerNet = new Gcp.Compute.Network("consumer_net", new()
{
Name = "my-network",
AutoCreateSubnetworks = false,
});
var consumerSubnet = new Gcp.Compute.Subnetwork("consumer_subnet", new()
{
Name = "my-subnet",
IpCidrRange = "10.0.0.248/29",
Region = "us-central1",
Network = consumerNet.Id,
});
var @default = new Gcp.NetworkConnectivity.ServiceConnectionPolicy("default", new()
{
Name = "my-policy",
Location = "us-central1",
ServiceClass = "gcp-memorystore-redis",
Description = "my basic service connection policy",
Network = consumerNet.Id,
PscConfig = new Gcp.NetworkConnectivity.Inputs.ServiceConnectionPolicyPscConfigArgs
{
Subnetworks = new[]
{
consumerSubnet.Id,
},
},
});
var cluster_ha = new Gcp.Redis.Cluster("cluster-ha", new()
{
Name = "ha-cluster",
ShardCount = 3,
PscConfigs = new[]
{
new Gcp.Redis.Inputs.ClusterPscConfigArgs
{
Network = consumerNet.Id,
},
},
Region = "us-central1",
ReplicaCount = 1,
NodeType = "REDIS_SHARED_CORE_NANO",
TransitEncryptionMode = "TRANSIT_ENCRYPTION_MODE_DISABLED",
AuthorizationMode = "AUTH_MODE_DISABLED",
RedisConfigs =
{
{ "maxmemory-policy", "volatile-ttl" },
},
DeletionProtectionEnabled = true,
ZoneDistributionConfig = new Gcp.Redis.Inputs.ClusterZoneDistributionConfigArgs
{
Mode = "MULTI_ZONE",
},
MaintenancePolicy = new Gcp.Redis.Inputs.ClusterMaintenancePolicyArgs
{
WeeklyMaintenanceWindows = new[]
{
new Gcp.Redis.Inputs.ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs
{
Day = "MONDAY",
StartTime = new Gcp.Redis.Inputs.ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs
{
Hours = 1,
Minutes = 0,
Seconds = 0,
Nanos = 0,
},
},
},
},
}, new CustomResourceOptions
{
DependsOn =
{
@default,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.Network;
import com.pulumi.gcp.compute.NetworkArgs;
import com.pulumi.gcp.compute.Subnetwork;
import com.pulumi.gcp.compute.SubnetworkArgs;
import com.pulumi.gcp.networkconnectivity.ServiceConnectionPolicy;
import com.pulumi.gcp.networkconnectivity.ServiceConnectionPolicyArgs;
import com.pulumi.gcp.networkconnectivity.inputs.ServiceConnectionPolicyPscConfigArgs;
import com.pulumi.gcp.redis.Cluster;
import com.pulumi.gcp.redis.ClusterArgs;
import com.pulumi.gcp.redis.inputs.ClusterPscConfigArgs;
import com.pulumi.gcp.redis.inputs.ClusterZoneDistributionConfigArgs;
import com.pulumi.gcp.redis.inputs.ClusterMaintenancePolicyArgs;
import com.pulumi.resources.CustomResourceOptions;
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 consumerNet = new Network("consumerNet", NetworkArgs.builder()
.name("my-network")
.autoCreateSubnetworks(false)
.build());
var consumerSubnet = new Subnetwork("consumerSubnet", SubnetworkArgs.builder()
.name("my-subnet")
.ipCidrRange("10.0.0.248/29")
.region("us-central1")
.network(consumerNet.id())
.build());
var default_ = new ServiceConnectionPolicy("default", ServiceConnectionPolicyArgs.builder()
.name("my-policy")
.location("us-central1")
.serviceClass("gcp-memorystore-redis")
.description("my basic service connection policy")
.network(consumerNet.id())
.pscConfig(ServiceConnectionPolicyPscConfigArgs.builder()
.subnetworks(consumerSubnet.id())
.build())
.build());
var cluster_ha = new Cluster("cluster-ha", ClusterArgs.builder()
.name("ha-cluster")
.shardCount(3)
.pscConfigs(ClusterPscConfigArgs.builder()
.network(consumerNet.id())
.build())
.region("us-central1")
.replicaCount(1)
.nodeType("REDIS_SHARED_CORE_NANO")
.transitEncryptionMode("TRANSIT_ENCRYPTION_MODE_DISABLED")
.authorizationMode("AUTH_MODE_DISABLED")
.redisConfigs(Map.of("maxmemory-policy", "volatile-ttl"))
.deletionProtectionEnabled(true)
.zoneDistributionConfig(ClusterZoneDistributionConfigArgs.builder()
.mode("MULTI_ZONE")
.build())
.maintenancePolicy(ClusterMaintenancePolicyArgs.builder()
.weeklyMaintenanceWindows(ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs.builder()
.day("MONDAY")
.startTime(ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs.builder()
.hours(1)
.minutes(0)
.seconds(0)
.nanos(0)
.build())
.build())
.build())
.build(), CustomResourceOptions.builder()
.dependsOn(default_)
.build());
}
}
resources:
cluster-ha:
type: gcp:redis:Cluster
properties:
name: ha-cluster
shardCount: 3
pscConfigs:
- network: ${consumerNet.id}
region: us-central1
replicaCount: 1
nodeType: REDIS_SHARED_CORE_NANO
transitEncryptionMode: TRANSIT_ENCRYPTION_MODE_DISABLED
authorizationMode: AUTH_MODE_DISABLED
redisConfigs:
maxmemory-policy: volatile-ttl
deletionProtectionEnabled: true
zoneDistributionConfig:
mode: MULTI_ZONE
maintenancePolicy:
weeklyMaintenanceWindows:
- day: MONDAY
startTime:
hours: 1
minutes: 0
seconds: 0
nanos: 0
options:
dependsOn:
- ${default}
default:
type: gcp:networkconnectivity:ServiceConnectionPolicy
properties:
name: my-policy
location: us-central1
serviceClass: gcp-memorystore-redis
description: my basic service connection policy
network: ${consumerNet.id}
pscConfig:
subnetworks:
- ${consumerSubnet.id}
consumerSubnet:
type: gcp:compute:Subnetwork
name: consumer_subnet
properties:
name: my-subnet
ipCidrRange: 10.0.0.248/29
region: us-central1
network: ${consumerNet.id}
consumerNet:
type: gcp:compute:Network
name: consumer_net
properties:
name: my-network
autoCreateSubnetworks: false
The cluster spreads data across shardCount shards, each with replicaCount replicas. The zoneDistributionConfig with mode MULTI_ZONE places shards and replicas across zones automatically. The pscConfigs property connects the cluster to your VPC via Private Service Connect. The nodeType determines compute and memory capacity per node.
Pin a cluster to a single availability zone
Some workloads prioritize low latency over zone-level redundancy and benefit from keeping all cluster nodes in the same zone.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const consumerNet = new gcp.compute.Network("consumer_net", {
name: "my-network",
autoCreateSubnetworks: false,
});
const consumerSubnet = new gcp.compute.Subnetwork("consumer_subnet", {
name: "my-subnet",
ipCidrRange: "10.0.0.248/29",
region: "us-central1",
network: consumerNet.id,
});
const _default = new gcp.networkconnectivity.ServiceConnectionPolicy("default", {
name: "my-policy",
location: "us-central1",
serviceClass: "gcp-memorystore-redis",
description: "my basic service connection policy",
network: consumerNet.id,
pscConfig: {
subnetworks: [consumerSubnet.id],
},
});
const cluster_ha_single_zone = new gcp.redis.Cluster("cluster-ha-single-zone", {
name: "ha-cluster-single-zone",
shardCount: 3,
pscConfigs: [{
network: consumerNet.id,
}],
region: "us-central1",
zoneDistributionConfig: {
mode: "SINGLE_ZONE",
zone: "us-central1-f",
},
maintenancePolicy: {
weeklyMaintenanceWindows: [{
day: "MONDAY",
startTime: {
hours: 1,
minutes: 0,
seconds: 0,
nanos: 0,
},
}],
},
deletionProtectionEnabled: true,
}, {
dependsOn: [_default],
});
import pulumi
import pulumi_gcp as gcp
consumer_net = gcp.compute.Network("consumer_net",
name="my-network",
auto_create_subnetworks=False)
consumer_subnet = gcp.compute.Subnetwork("consumer_subnet",
name="my-subnet",
ip_cidr_range="10.0.0.248/29",
region="us-central1",
network=consumer_net.id)
default = gcp.networkconnectivity.ServiceConnectionPolicy("default",
name="my-policy",
location="us-central1",
service_class="gcp-memorystore-redis",
description="my basic service connection policy",
network=consumer_net.id,
psc_config={
"subnetworks": [consumer_subnet.id],
})
cluster_ha_single_zone = gcp.redis.Cluster("cluster-ha-single-zone",
name="ha-cluster-single-zone",
shard_count=3,
psc_configs=[{
"network": consumer_net.id,
}],
region="us-central1",
zone_distribution_config={
"mode": "SINGLE_ZONE",
"zone": "us-central1-f",
},
maintenance_policy={
"weekly_maintenance_windows": [{
"day": "MONDAY",
"start_time": {
"hours": 1,
"minutes": 0,
"seconds": 0,
"nanos": 0,
},
}],
},
deletion_protection_enabled=True,
opts = pulumi.ResourceOptions(depends_on=[default]))
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networkconnectivity"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/redis"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
consumerNet, err := compute.NewNetwork(ctx, "consumer_net", &compute.NetworkArgs{
Name: pulumi.String("my-network"),
AutoCreateSubnetworks: pulumi.Bool(false),
})
if err != nil {
return err
}
consumerSubnet, err := compute.NewSubnetwork(ctx, "consumer_subnet", &compute.SubnetworkArgs{
Name: pulumi.String("my-subnet"),
IpCidrRange: pulumi.String("10.0.0.248/29"),
Region: pulumi.String("us-central1"),
Network: consumerNet.ID(),
})
if err != nil {
return err
}
_default, err := networkconnectivity.NewServiceConnectionPolicy(ctx, "default", &networkconnectivity.ServiceConnectionPolicyArgs{
Name: pulumi.String("my-policy"),
Location: pulumi.String("us-central1"),
ServiceClass: pulumi.String("gcp-memorystore-redis"),
Description: pulumi.String("my basic service connection policy"),
Network: consumerNet.ID(),
PscConfig: &networkconnectivity.ServiceConnectionPolicyPscConfigArgs{
Subnetworks: pulumi.StringArray{
consumerSubnet.ID(),
},
},
})
if err != nil {
return err
}
_, err = redis.NewCluster(ctx, "cluster-ha-single-zone", &redis.ClusterArgs{
Name: pulumi.String("ha-cluster-single-zone"),
ShardCount: pulumi.Int(3),
PscConfigs: redis.ClusterPscConfigArray{
&redis.ClusterPscConfigArgs{
Network: consumerNet.ID(),
},
},
Region: pulumi.String("us-central1"),
ZoneDistributionConfig: &redis.ClusterZoneDistributionConfigArgs{
Mode: pulumi.String("SINGLE_ZONE"),
Zone: pulumi.String("us-central1-f"),
},
MaintenancePolicy: &redis.ClusterMaintenancePolicyArgs{
WeeklyMaintenanceWindows: redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowArray{
&redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs{
Day: pulumi.String("MONDAY"),
StartTime: &redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs{
Hours: pulumi.Int(1),
Minutes: pulumi.Int(0),
Seconds: pulumi.Int(0),
Nanos: pulumi.Int(0),
},
},
},
},
DeletionProtectionEnabled: pulumi.Bool(true),
}, pulumi.DependsOn([]pulumi.Resource{
_default,
}))
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 consumerNet = new Gcp.Compute.Network("consumer_net", new()
{
Name = "my-network",
AutoCreateSubnetworks = false,
});
var consumerSubnet = new Gcp.Compute.Subnetwork("consumer_subnet", new()
{
Name = "my-subnet",
IpCidrRange = "10.0.0.248/29",
Region = "us-central1",
Network = consumerNet.Id,
});
var @default = new Gcp.NetworkConnectivity.ServiceConnectionPolicy("default", new()
{
Name = "my-policy",
Location = "us-central1",
ServiceClass = "gcp-memorystore-redis",
Description = "my basic service connection policy",
Network = consumerNet.Id,
PscConfig = new Gcp.NetworkConnectivity.Inputs.ServiceConnectionPolicyPscConfigArgs
{
Subnetworks = new[]
{
consumerSubnet.Id,
},
},
});
var cluster_ha_single_zone = new Gcp.Redis.Cluster("cluster-ha-single-zone", new()
{
Name = "ha-cluster-single-zone",
ShardCount = 3,
PscConfigs = new[]
{
new Gcp.Redis.Inputs.ClusterPscConfigArgs
{
Network = consumerNet.Id,
},
},
Region = "us-central1",
ZoneDistributionConfig = new Gcp.Redis.Inputs.ClusterZoneDistributionConfigArgs
{
Mode = "SINGLE_ZONE",
Zone = "us-central1-f",
},
MaintenancePolicy = new Gcp.Redis.Inputs.ClusterMaintenancePolicyArgs
{
WeeklyMaintenanceWindows = new[]
{
new Gcp.Redis.Inputs.ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs
{
Day = "MONDAY",
StartTime = new Gcp.Redis.Inputs.ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs
{
Hours = 1,
Minutes = 0,
Seconds = 0,
Nanos = 0,
},
},
},
},
DeletionProtectionEnabled = true,
}, new CustomResourceOptions
{
DependsOn =
{
@default,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.Network;
import com.pulumi.gcp.compute.NetworkArgs;
import com.pulumi.gcp.compute.Subnetwork;
import com.pulumi.gcp.compute.SubnetworkArgs;
import com.pulumi.gcp.networkconnectivity.ServiceConnectionPolicy;
import com.pulumi.gcp.networkconnectivity.ServiceConnectionPolicyArgs;
import com.pulumi.gcp.networkconnectivity.inputs.ServiceConnectionPolicyPscConfigArgs;
import com.pulumi.gcp.redis.Cluster;
import com.pulumi.gcp.redis.ClusterArgs;
import com.pulumi.gcp.redis.inputs.ClusterPscConfigArgs;
import com.pulumi.gcp.redis.inputs.ClusterZoneDistributionConfigArgs;
import com.pulumi.gcp.redis.inputs.ClusterMaintenancePolicyArgs;
import com.pulumi.resources.CustomResourceOptions;
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 consumerNet = new Network("consumerNet", NetworkArgs.builder()
.name("my-network")
.autoCreateSubnetworks(false)
.build());
var consumerSubnet = new Subnetwork("consumerSubnet", SubnetworkArgs.builder()
.name("my-subnet")
.ipCidrRange("10.0.0.248/29")
.region("us-central1")
.network(consumerNet.id())
.build());
var default_ = new ServiceConnectionPolicy("default", ServiceConnectionPolicyArgs.builder()
.name("my-policy")
.location("us-central1")
.serviceClass("gcp-memorystore-redis")
.description("my basic service connection policy")
.network(consumerNet.id())
.pscConfig(ServiceConnectionPolicyPscConfigArgs.builder()
.subnetworks(consumerSubnet.id())
.build())
.build());
var cluster_ha_single_zone = new Cluster("cluster-ha-single-zone", ClusterArgs.builder()
.name("ha-cluster-single-zone")
.shardCount(3)
.pscConfigs(ClusterPscConfigArgs.builder()
.network(consumerNet.id())
.build())
.region("us-central1")
.zoneDistributionConfig(ClusterZoneDistributionConfigArgs.builder()
.mode("SINGLE_ZONE")
.zone("us-central1-f")
.build())
.maintenancePolicy(ClusterMaintenancePolicyArgs.builder()
.weeklyMaintenanceWindows(ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs.builder()
.day("MONDAY")
.startTime(ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs.builder()
.hours(1)
.minutes(0)
.seconds(0)
.nanos(0)
.build())
.build())
.build())
.deletionProtectionEnabled(true)
.build(), CustomResourceOptions.builder()
.dependsOn(default_)
.build());
}
}
resources:
cluster-ha-single-zone:
type: gcp:redis:Cluster
properties:
name: ha-cluster-single-zone
shardCount: 3
pscConfigs:
- network: ${consumerNet.id}
region: us-central1
zoneDistributionConfig:
mode: SINGLE_ZONE
zone: us-central1-f
maintenancePolicy:
weeklyMaintenanceWindows:
- day: MONDAY
startTime:
hours: 1
minutes: 0
seconds: 0
nanos: 0
deletionProtectionEnabled: true
options:
dependsOn:
- ${default}
default:
type: gcp:networkconnectivity:ServiceConnectionPolicy
properties:
name: my-policy
location: us-central1
serviceClass: gcp-memorystore-redis
description: my basic service connection policy
network: ${consumerNet.id}
pscConfig:
subnetworks:
- ${consumerSubnet.id}
consumerSubnet:
type: gcp:compute:Subnetwork
name: consumer_subnet
properties:
name: my-subnet
ipCidrRange: 10.0.0.248/29
region: us-central1
network: ${consumerNet.id}
consumerNet:
type: gcp:compute:Network
name: consumer_net
properties:
name: my-network
autoCreateSubnetworks: false
Setting zoneDistributionConfig.mode to SINGLE_ZONE and specifying a zone pins all shards and replicas to that zone. This reduces cross-zone network latency but eliminates automatic failover during zone outages. Use this for development environments or latency-critical workloads that have other redundancy strategies.
Configure cross-region replication with primary and secondary
Applications requiring disaster recovery or global read distribution deploy clusters across regions with automatic replication from primary to secondary.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const consumerNet = new gcp.compute.Network("consumer_net", {
name: "mynetwork",
autoCreateSubnetworks: false,
});
const primaryClusterConsumerSubnet = new gcp.compute.Subnetwork("primary_cluster_consumer_subnet", {
name: "mysubnet-primary-cluster",
ipCidrRange: "10.0.1.0/29",
region: "us-east1",
network: consumerNet.id,
});
const primaryClusterRegionScp = new gcp.networkconnectivity.ServiceConnectionPolicy("primary_cluster_region_scp", {
name: "mypolicy-primary-cluster",
location: "us-east1",
serviceClass: "gcp-memorystore-redis",
description: "Primary cluster service connection policy",
network: consumerNet.id,
pscConfig: {
subnetworks: [primaryClusterConsumerSubnet.id],
},
});
// Primary cluster
const primaryCluster = new gcp.redis.Cluster("primary_cluster", {
name: "my-primary-cluster",
region: "us-east1",
pscConfigs: [{
network: consumerNet.id,
}],
authorizationMode: "AUTH_MODE_DISABLED",
transitEncryptionMode: "TRANSIT_ENCRYPTION_MODE_DISABLED",
shardCount: 3,
redisConfigs: {
"maxmemory-policy": "volatile-ttl",
},
nodeType: "REDIS_HIGHMEM_MEDIUM",
persistenceConfig: {
mode: "RDB",
rdbConfig: {
rdbSnapshotPeriod: "ONE_HOUR",
rdbSnapshotStartTime: "2024-10-02T15:01:23Z",
},
},
zoneDistributionConfig: {
mode: "MULTI_ZONE",
},
replicaCount: 1,
maintenancePolicy: {
weeklyMaintenanceWindows: [{
day: "MONDAY",
startTime: {
hours: 1,
minutes: 0,
seconds: 0,
nanos: 0,
},
}],
},
deletionProtectionEnabled: true,
}, {
dependsOn: [primaryClusterRegionScp],
});
const secondaryClusterConsumerSubnet = new gcp.compute.Subnetwork("secondary_cluster_consumer_subnet", {
name: "mysubnet-secondary-cluster",
ipCidrRange: "10.0.2.0/29",
region: "europe-west1",
network: consumerNet.id,
});
const secondaryClusterRegionScp = new gcp.networkconnectivity.ServiceConnectionPolicy("secondary_cluster_region_scp", {
name: "mypolicy-secondary-cluster",
location: "europe-west1",
serviceClass: "gcp-memorystore-redis",
description: "Secondary cluster service connection policy",
network: consumerNet.id,
pscConfig: {
subnetworks: [secondaryClusterConsumerSubnet.id],
},
});
// Secondary cluster
const secondaryCluster = new gcp.redis.Cluster("secondary_cluster", {
name: "my-secondary-cluster",
region: "europe-west1",
pscConfigs: [{
network: consumerNet.id,
}],
authorizationMode: "AUTH_MODE_DISABLED",
transitEncryptionMode: "TRANSIT_ENCRYPTION_MODE_DISABLED",
shardCount: 3,
redisConfigs: {
"maxmemory-policy": "volatile-ttl",
},
nodeType: "REDIS_HIGHMEM_MEDIUM",
persistenceConfig: {
mode: "RDB",
rdbConfig: {
rdbSnapshotPeriod: "ONE_HOUR",
rdbSnapshotStartTime: "2024-10-02T15:01:23Z",
},
},
zoneDistributionConfig: {
mode: "MULTI_ZONE",
},
replicaCount: 2,
maintenancePolicy: {
weeklyMaintenanceWindows: [{
day: "WEDNESDAY",
startTime: {
hours: 1,
minutes: 0,
seconds: 0,
nanos: 0,
},
}],
},
deletionProtectionEnabled: true,
crossClusterReplicationConfig: {
clusterRole: "SECONDARY",
primaryCluster: {
cluster: primaryCluster.id,
},
},
}, {
dependsOn: [secondaryClusterRegionScp],
});
import pulumi
import pulumi_gcp as gcp
consumer_net = gcp.compute.Network("consumer_net",
name="mynetwork",
auto_create_subnetworks=False)
primary_cluster_consumer_subnet = gcp.compute.Subnetwork("primary_cluster_consumer_subnet",
name="mysubnet-primary-cluster",
ip_cidr_range="10.0.1.0/29",
region="us-east1",
network=consumer_net.id)
primary_cluster_region_scp = gcp.networkconnectivity.ServiceConnectionPolicy("primary_cluster_region_scp",
name="mypolicy-primary-cluster",
location="us-east1",
service_class="gcp-memorystore-redis",
description="Primary cluster service connection policy",
network=consumer_net.id,
psc_config={
"subnetworks": [primary_cluster_consumer_subnet.id],
})
# Primary cluster
primary_cluster = gcp.redis.Cluster("primary_cluster",
name="my-primary-cluster",
region="us-east1",
psc_configs=[{
"network": consumer_net.id,
}],
authorization_mode="AUTH_MODE_DISABLED",
transit_encryption_mode="TRANSIT_ENCRYPTION_MODE_DISABLED",
shard_count=3,
redis_configs={
"maxmemory-policy": "volatile-ttl",
},
node_type="REDIS_HIGHMEM_MEDIUM",
persistence_config={
"mode": "RDB",
"rdb_config": {
"rdb_snapshot_period": "ONE_HOUR",
"rdb_snapshot_start_time": "2024-10-02T15:01:23Z",
},
},
zone_distribution_config={
"mode": "MULTI_ZONE",
},
replica_count=1,
maintenance_policy={
"weekly_maintenance_windows": [{
"day": "MONDAY",
"start_time": {
"hours": 1,
"minutes": 0,
"seconds": 0,
"nanos": 0,
},
}],
},
deletion_protection_enabled=True,
opts = pulumi.ResourceOptions(depends_on=[primary_cluster_region_scp]))
secondary_cluster_consumer_subnet = gcp.compute.Subnetwork("secondary_cluster_consumer_subnet",
name="mysubnet-secondary-cluster",
ip_cidr_range="10.0.2.0/29",
region="europe-west1",
network=consumer_net.id)
secondary_cluster_region_scp = gcp.networkconnectivity.ServiceConnectionPolicy("secondary_cluster_region_scp",
name="mypolicy-secondary-cluster",
location="europe-west1",
service_class="gcp-memorystore-redis",
description="Secondary cluster service connection policy",
network=consumer_net.id,
psc_config={
"subnetworks": [secondary_cluster_consumer_subnet.id],
})
# Secondary cluster
secondary_cluster = gcp.redis.Cluster("secondary_cluster",
name="my-secondary-cluster",
region="europe-west1",
psc_configs=[{
"network": consumer_net.id,
}],
authorization_mode="AUTH_MODE_DISABLED",
transit_encryption_mode="TRANSIT_ENCRYPTION_MODE_DISABLED",
shard_count=3,
redis_configs={
"maxmemory-policy": "volatile-ttl",
},
node_type="REDIS_HIGHMEM_MEDIUM",
persistence_config={
"mode": "RDB",
"rdb_config": {
"rdb_snapshot_period": "ONE_HOUR",
"rdb_snapshot_start_time": "2024-10-02T15:01:23Z",
},
},
zone_distribution_config={
"mode": "MULTI_ZONE",
},
replica_count=2,
maintenance_policy={
"weekly_maintenance_windows": [{
"day": "WEDNESDAY",
"start_time": {
"hours": 1,
"minutes": 0,
"seconds": 0,
"nanos": 0,
},
}],
},
deletion_protection_enabled=True,
cross_cluster_replication_config={
"cluster_role": "SECONDARY",
"primary_cluster": {
"cluster": primary_cluster.id,
},
},
opts = pulumi.ResourceOptions(depends_on=[secondary_cluster_region_scp]))
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networkconnectivity"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/redis"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
consumerNet, err := compute.NewNetwork(ctx, "consumer_net", &compute.NetworkArgs{
Name: pulumi.String("mynetwork"),
AutoCreateSubnetworks: pulumi.Bool(false),
})
if err != nil {
return err
}
primaryClusterConsumerSubnet, err := compute.NewSubnetwork(ctx, "primary_cluster_consumer_subnet", &compute.SubnetworkArgs{
Name: pulumi.String("mysubnet-primary-cluster"),
IpCidrRange: pulumi.String("10.0.1.0/29"),
Region: pulumi.String("us-east1"),
Network: consumerNet.ID(),
})
if err != nil {
return err
}
primaryClusterRegionScp, err := networkconnectivity.NewServiceConnectionPolicy(ctx, "primary_cluster_region_scp", &networkconnectivity.ServiceConnectionPolicyArgs{
Name: pulumi.String("mypolicy-primary-cluster"),
Location: pulumi.String("us-east1"),
ServiceClass: pulumi.String("gcp-memorystore-redis"),
Description: pulumi.String("Primary cluster service connection policy"),
Network: consumerNet.ID(),
PscConfig: &networkconnectivity.ServiceConnectionPolicyPscConfigArgs{
Subnetworks: pulumi.StringArray{
primaryClusterConsumerSubnet.ID(),
},
},
})
if err != nil {
return err
}
// Primary cluster
primaryCluster, err := redis.NewCluster(ctx, "primary_cluster", &redis.ClusterArgs{
Name: pulumi.String("my-primary-cluster"),
Region: pulumi.String("us-east1"),
PscConfigs: redis.ClusterPscConfigArray{
&redis.ClusterPscConfigArgs{
Network: consumerNet.ID(),
},
},
AuthorizationMode: pulumi.String("AUTH_MODE_DISABLED"),
TransitEncryptionMode: pulumi.String("TRANSIT_ENCRYPTION_MODE_DISABLED"),
ShardCount: pulumi.Int(3),
RedisConfigs: pulumi.StringMap{
"maxmemory-policy": pulumi.String("volatile-ttl"),
},
NodeType: pulumi.String("REDIS_HIGHMEM_MEDIUM"),
PersistenceConfig: &redis.ClusterPersistenceConfigArgs{
Mode: pulumi.String("RDB"),
RdbConfig: &redis.ClusterPersistenceConfigRdbConfigArgs{
RdbSnapshotPeriod: pulumi.String("ONE_HOUR"),
RdbSnapshotStartTime: pulumi.String("2024-10-02T15:01:23Z"),
},
},
ZoneDistributionConfig: &redis.ClusterZoneDistributionConfigArgs{
Mode: pulumi.String("MULTI_ZONE"),
},
ReplicaCount: pulumi.Int(1),
MaintenancePolicy: &redis.ClusterMaintenancePolicyArgs{
WeeklyMaintenanceWindows: redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowArray{
&redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs{
Day: pulumi.String("MONDAY"),
StartTime: &redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs{
Hours: pulumi.Int(1),
Minutes: pulumi.Int(0),
Seconds: pulumi.Int(0),
Nanos: pulumi.Int(0),
},
},
},
},
DeletionProtectionEnabled: pulumi.Bool(true),
}, pulumi.DependsOn([]pulumi.Resource{
primaryClusterRegionScp,
}))
if err != nil {
return err
}
secondaryClusterConsumerSubnet, err := compute.NewSubnetwork(ctx, "secondary_cluster_consumer_subnet", &compute.SubnetworkArgs{
Name: pulumi.String("mysubnet-secondary-cluster"),
IpCidrRange: pulumi.String("10.0.2.0/29"),
Region: pulumi.String("europe-west1"),
Network: consumerNet.ID(),
})
if err != nil {
return err
}
secondaryClusterRegionScp, err := networkconnectivity.NewServiceConnectionPolicy(ctx, "secondary_cluster_region_scp", &networkconnectivity.ServiceConnectionPolicyArgs{
Name: pulumi.String("mypolicy-secondary-cluster"),
Location: pulumi.String("europe-west1"),
ServiceClass: pulumi.String("gcp-memorystore-redis"),
Description: pulumi.String("Secondary cluster service connection policy"),
Network: consumerNet.ID(),
PscConfig: &networkconnectivity.ServiceConnectionPolicyPscConfigArgs{
Subnetworks: pulumi.StringArray{
secondaryClusterConsumerSubnet.ID(),
},
},
})
if err != nil {
return err
}
// Secondary cluster
_, err = redis.NewCluster(ctx, "secondary_cluster", &redis.ClusterArgs{
Name: pulumi.String("my-secondary-cluster"),
Region: pulumi.String("europe-west1"),
PscConfigs: redis.ClusterPscConfigArray{
&redis.ClusterPscConfigArgs{
Network: consumerNet.ID(),
},
},
AuthorizationMode: pulumi.String("AUTH_MODE_DISABLED"),
TransitEncryptionMode: pulumi.String("TRANSIT_ENCRYPTION_MODE_DISABLED"),
ShardCount: pulumi.Int(3),
RedisConfigs: pulumi.StringMap{
"maxmemory-policy": pulumi.String("volatile-ttl"),
},
NodeType: pulumi.String("REDIS_HIGHMEM_MEDIUM"),
PersistenceConfig: &redis.ClusterPersistenceConfigArgs{
Mode: pulumi.String("RDB"),
RdbConfig: &redis.ClusterPersistenceConfigRdbConfigArgs{
RdbSnapshotPeriod: pulumi.String("ONE_HOUR"),
RdbSnapshotStartTime: pulumi.String("2024-10-02T15:01:23Z"),
},
},
ZoneDistributionConfig: &redis.ClusterZoneDistributionConfigArgs{
Mode: pulumi.String("MULTI_ZONE"),
},
ReplicaCount: pulumi.Int(2),
MaintenancePolicy: &redis.ClusterMaintenancePolicyArgs{
WeeklyMaintenanceWindows: redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowArray{
&redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs{
Day: pulumi.String("WEDNESDAY"),
StartTime: &redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs{
Hours: pulumi.Int(1),
Minutes: pulumi.Int(0),
Seconds: pulumi.Int(0),
Nanos: pulumi.Int(0),
},
},
},
},
DeletionProtectionEnabled: pulumi.Bool(true),
CrossClusterReplicationConfig: &redis.ClusterCrossClusterReplicationConfigArgs{
ClusterRole: pulumi.String("SECONDARY"),
PrimaryCluster: &redis.ClusterCrossClusterReplicationConfigPrimaryClusterArgs{
Cluster: primaryCluster.ID(),
},
},
}, pulumi.DependsOn([]pulumi.Resource{
secondaryClusterRegionScp,
}))
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 consumerNet = new Gcp.Compute.Network("consumer_net", new()
{
Name = "mynetwork",
AutoCreateSubnetworks = false,
});
var primaryClusterConsumerSubnet = new Gcp.Compute.Subnetwork("primary_cluster_consumer_subnet", new()
{
Name = "mysubnet-primary-cluster",
IpCidrRange = "10.0.1.0/29",
Region = "us-east1",
Network = consumerNet.Id,
});
var primaryClusterRegionScp = new Gcp.NetworkConnectivity.ServiceConnectionPolicy("primary_cluster_region_scp", new()
{
Name = "mypolicy-primary-cluster",
Location = "us-east1",
ServiceClass = "gcp-memorystore-redis",
Description = "Primary cluster service connection policy",
Network = consumerNet.Id,
PscConfig = new Gcp.NetworkConnectivity.Inputs.ServiceConnectionPolicyPscConfigArgs
{
Subnetworks = new[]
{
primaryClusterConsumerSubnet.Id,
},
},
});
// Primary cluster
var primaryCluster = new Gcp.Redis.Cluster("primary_cluster", new()
{
Name = "my-primary-cluster",
Region = "us-east1",
PscConfigs = new[]
{
new Gcp.Redis.Inputs.ClusterPscConfigArgs
{
Network = consumerNet.Id,
},
},
AuthorizationMode = "AUTH_MODE_DISABLED",
TransitEncryptionMode = "TRANSIT_ENCRYPTION_MODE_DISABLED",
ShardCount = 3,
RedisConfigs =
{
{ "maxmemory-policy", "volatile-ttl" },
},
NodeType = "REDIS_HIGHMEM_MEDIUM",
PersistenceConfig = new Gcp.Redis.Inputs.ClusterPersistenceConfigArgs
{
Mode = "RDB",
RdbConfig = new Gcp.Redis.Inputs.ClusterPersistenceConfigRdbConfigArgs
{
RdbSnapshotPeriod = "ONE_HOUR",
RdbSnapshotStartTime = "2024-10-02T15:01:23Z",
},
},
ZoneDistributionConfig = new Gcp.Redis.Inputs.ClusterZoneDistributionConfigArgs
{
Mode = "MULTI_ZONE",
},
ReplicaCount = 1,
MaintenancePolicy = new Gcp.Redis.Inputs.ClusterMaintenancePolicyArgs
{
WeeklyMaintenanceWindows = new[]
{
new Gcp.Redis.Inputs.ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs
{
Day = "MONDAY",
StartTime = new Gcp.Redis.Inputs.ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs
{
Hours = 1,
Minutes = 0,
Seconds = 0,
Nanos = 0,
},
},
},
},
DeletionProtectionEnabled = true,
}, new CustomResourceOptions
{
DependsOn =
{
primaryClusterRegionScp,
},
});
var secondaryClusterConsumerSubnet = new Gcp.Compute.Subnetwork("secondary_cluster_consumer_subnet", new()
{
Name = "mysubnet-secondary-cluster",
IpCidrRange = "10.0.2.0/29",
Region = "europe-west1",
Network = consumerNet.Id,
});
var secondaryClusterRegionScp = new Gcp.NetworkConnectivity.ServiceConnectionPolicy("secondary_cluster_region_scp", new()
{
Name = "mypolicy-secondary-cluster",
Location = "europe-west1",
ServiceClass = "gcp-memorystore-redis",
Description = "Secondary cluster service connection policy",
Network = consumerNet.Id,
PscConfig = new Gcp.NetworkConnectivity.Inputs.ServiceConnectionPolicyPscConfigArgs
{
Subnetworks = new[]
{
secondaryClusterConsumerSubnet.Id,
},
},
});
// Secondary cluster
var secondaryCluster = new Gcp.Redis.Cluster("secondary_cluster", new()
{
Name = "my-secondary-cluster",
Region = "europe-west1",
PscConfigs = new[]
{
new Gcp.Redis.Inputs.ClusterPscConfigArgs
{
Network = consumerNet.Id,
},
},
AuthorizationMode = "AUTH_MODE_DISABLED",
TransitEncryptionMode = "TRANSIT_ENCRYPTION_MODE_DISABLED",
ShardCount = 3,
RedisConfigs =
{
{ "maxmemory-policy", "volatile-ttl" },
},
NodeType = "REDIS_HIGHMEM_MEDIUM",
PersistenceConfig = new Gcp.Redis.Inputs.ClusterPersistenceConfigArgs
{
Mode = "RDB",
RdbConfig = new Gcp.Redis.Inputs.ClusterPersistenceConfigRdbConfigArgs
{
RdbSnapshotPeriod = "ONE_HOUR",
RdbSnapshotStartTime = "2024-10-02T15:01:23Z",
},
},
ZoneDistributionConfig = new Gcp.Redis.Inputs.ClusterZoneDistributionConfigArgs
{
Mode = "MULTI_ZONE",
},
ReplicaCount = 2,
MaintenancePolicy = new Gcp.Redis.Inputs.ClusterMaintenancePolicyArgs
{
WeeklyMaintenanceWindows = new[]
{
new Gcp.Redis.Inputs.ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs
{
Day = "WEDNESDAY",
StartTime = new Gcp.Redis.Inputs.ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs
{
Hours = 1,
Minutes = 0,
Seconds = 0,
Nanos = 0,
},
},
},
},
DeletionProtectionEnabled = true,
CrossClusterReplicationConfig = new Gcp.Redis.Inputs.ClusterCrossClusterReplicationConfigArgs
{
ClusterRole = "SECONDARY",
PrimaryCluster = new Gcp.Redis.Inputs.ClusterCrossClusterReplicationConfigPrimaryClusterArgs
{
Cluster = primaryCluster.Id,
},
},
}, new CustomResourceOptions
{
DependsOn =
{
secondaryClusterRegionScp,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.Network;
import com.pulumi.gcp.compute.NetworkArgs;
import com.pulumi.gcp.compute.Subnetwork;
import com.pulumi.gcp.compute.SubnetworkArgs;
import com.pulumi.gcp.networkconnectivity.ServiceConnectionPolicy;
import com.pulumi.gcp.networkconnectivity.ServiceConnectionPolicyArgs;
import com.pulumi.gcp.networkconnectivity.inputs.ServiceConnectionPolicyPscConfigArgs;
import com.pulumi.gcp.redis.Cluster;
import com.pulumi.gcp.redis.ClusterArgs;
import com.pulumi.gcp.redis.inputs.ClusterPscConfigArgs;
import com.pulumi.gcp.redis.inputs.ClusterPersistenceConfigArgs;
import com.pulumi.gcp.redis.inputs.ClusterPersistenceConfigRdbConfigArgs;
import com.pulumi.gcp.redis.inputs.ClusterZoneDistributionConfigArgs;
import com.pulumi.gcp.redis.inputs.ClusterMaintenancePolicyArgs;
import com.pulumi.gcp.redis.inputs.ClusterCrossClusterReplicationConfigArgs;
import com.pulumi.gcp.redis.inputs.ClusterCrossClusterReplicationConfigPrimaryClusterArgs;
import com.pulumi.resources.CustomResourceOptions;
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 consumerNet = new Network("consumerNet", NetworkArgs.builder()
.name("mynetwork")
.autoCreateSubnetworks(false)
.build());
var primaryClusterConsumerSubnet = new Subnetwork("primaryClusterConsumerSubnet", SubnetworkArgs.builder()
.name("mysubnet-primary-cluster")
.ipCidrRange("10.0.1.0/29")
.region("us-east1")
.network(consumerNet.id())
.build());
var primaryClusterRegionScp = new ServiceConnectionPolicy("primaryClusterRegionScp", ServiceConnectionPolicyArgs.builder()
.name("mypolicy-primary-cluster")
.location("us-east1")
.serviceClass("gcp-memorystore-redis")
.description("Primary cluster service connection policy")
.network(consumerNet.id())
.pscConfig(ServiceConnectionPolicyPscConfigArgs.builder()
.subnetworks(primaryClusterConsumerSubnet.id())
.build())
.build());
// Primary cluster
var primaryCluster = new Cluster("primaryCluster", ClusterArgs.builder()
.name("my-primary-cluster")
.region("us-east1")
.pscConfigs(ClusterPscConfigArgs.builder()
.network(consumerNet.id())
.build())
.authorizationMode("AUTH_MODE_DISABLED")
.transitEncryptionMode("TRANSIT_ENCRYPTION_MODE_DISABLED")
.shardCount(3)
.redisConfigs(Map.of("maxmemory-policy", "volatile-ttl"))
.nodeType("REDIS_HIGHMEM_MEDIUM")
.persistenceConfig(ClusterPersistenceConfigArgs.builder()
.mode("RDB")
.rdbConfig(ClusterPersistenceConfigRdbConfigArgs.builder()
.rdbSnapshotPeriod("ONE_HOUR")
.rdbSnapshotStartTime("2024-10-02T15:01:23Z")
.build())
.build())
.zoneDistributionConfig(ClusterZoneDistributionConfigArgs.builder()
.mode("MULTI_ZONE")
.build())
.replicaCount(1)
.maintenancePolicy(ClusterMaintenancePolicyArgs.builder()
.weeklyMaintenanceWindows(ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs.builder()
.day("MONDAY")
.startTime(ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs.builder()
.hours(1)
.minutes(0)
.seconds(0)
.nanos(0)
.build())
.build())
.build())
.deletionProtectionEnabled(true)
.build(), CustomResourceOptions.builder()
.dependsOn(primaryClusterRegionScp)
.build());
var secondaryClusterConsumerSubnet = new Subnetwork("secondaryClusterConsumerSubnet", SubnetworkArgs.builder()
.name("mysubnet-secondary-cluster")
.ipCidrRange("10.0.2.0/29")
.region("europe-west1")
.network(consumerNet.id())
.build());
var secondaryClusterRegionScp = new ServiceConnectionPolicy("secondaryClusterRegionScp", ServiceConnectionPolicyArgs.builder()
.name("mypolicy-secondary-cluster")
.location("europe-west1")
.serviceClass("gcp-memorystore-redis")
.description("Secondary cluster service connection policy")
.network(consumerNet.id())
.pscConfig(ServiceConnectionPolicyPscConfigArgs.builder()
.subnetworks(secondaryClusterConsumerSubnet.id())
.build())
.build());
// Secondary cluster
var secondaryCluster = new Cluster("secondaryCluster", ClusterArgs.builder()
.name("my-secondary-cluster")
.region("europe-west1")
.pscConfigs(ClusterPscConfigArgs.builder()
.network(consumerNet.id())
.build())
.authorizationMode("AUTH_MODE_DISABLED")
.transitEncryptionMode("TRANSIT_ENCRYPTION_MODE_DISABLED")
.shardCount(3)
.redisConfigs(Map.of("maxmemory-policy", "volatile-ttl"))
.nodeType("REDIS_HIGHMEM_MEDIUM")
.persistenceConfig(ClusterPersistenceConfigArgs.builder()
.mode("RDB")
.rdbConfig(ClusterPersistenceConfigRdbConfigArgs.builder()
.rdbSnapshotPeriod("ONE_HOUR")
.rdbSnapshotStartTime("2024-10-02T15:01:23Z")
.build())
.build())
.zoneDistributionConfig(ClusterZoneDistributionConfigArgs.builder()
.mode("MULTI_ZONE")
.build())
.replicaCount(2)
.maintenancePolicy(ClusterMaintenancePolicyArgs.builder()
.weeklyMaintenanceWindows(ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs.builder()
.day("WEDNESDAY")
.startTime(ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs.builder()
.hours(1)
.minutes(0)
.seconds(0)
.nanos(0)
.build())
.build())
.build())
.deletionProtectionEnabled(true)
.crossClusterReplicationConfig(ClusterCrossClusterReplicationConfigArgs.builder()
.clusterRole("SECONDARY")
.primaryCluster(ClusterCrossClusterReplicationConfigPrimaryClusterArgs.builder()
.cluster(primaryCluster.id())
.build())
.build())
.build(), CustomResourceOptions.builder()
.dependsOn(secondaryClusterRegionScp)
.build());
}
}
resources:
# Primary cluster
primaryCluster:
type: gcp:redis:Cluster
name: primary_cluster
properties:
name: my-primary-cluster
region: us-east1
pscConfigs:
- network: ${consumerNet.id}
authorizationMode: AUTH_MODE_DISABLED
transitEncryptionMode: TRANSIT_ENCRYPTION_MODE_DISABLED
shardCount: 3
redisConfigs:
maxmemory-policy: volatile-ttl
nodeType: REDIS_HIGHMEM_MEDIUM
persistenceConfig:
mode: RDB
rdbConfig:
rdbSnapshotPeriod: ONE_HOUR
rdbSnapshotStartTime: 2024-10-02T15:01:23Z
zoneDistributionConfig:
mode: MULTI_ZONE
replicaCount: 1
maintenancePolicy:
weeklyMaintenanceWindows:
- day: MONDAY
startTime:
hours: 1
minutes: 0
seconds: 0
nanos: 0
deletionProtectionEnabled: true
options:
dependsOn:
- ${primaryClusterRegionScp}
# Secondary cluster
secondaryCluster:
type: gcp:redis:Cluster
name: secondary_cluster
properties:
name: my-secondary-cluster
region: europe-west1
pscConfigs:
- network: ${consumerNet.id}
authorizationMode: AUTH_MODE_DISABLED
transitEncryptionMode: TRANSIT_ENCRYPTION_MODE_DISABLED
shardCount: 3
redisConfigs:
maxmemory-policy: volatile-ttl
nodeType: REDIS_HIGHMEM_MEDIUM
persistenceConfig:
mode: RDB
rdbConfig:
rdbSnapshotPeriod: ONE_HOUR
rdbSnapshotStartTime: 2024-10-02T15:01:23Z
zoneDistributionConfig:
mode: MULTI_ZONE
replicaCount: 2
maintenancePolicy:
weeklyMaintenanceWindows:
- day: WEDNESDAY
startTime:
hours: 1
minutes: 0
seconds: 0
nanos: 0
deletionProtectionEnabled: true # Cross cluster replication config
crossClusterReplicationConfig:
clusterRole: SECONDARY
primaryCluster:
cluster: ${primaryCluster.id}
options:
dependsOn:
- ${secondaryClusterRegionScp}
primaryClusterRegionScp:
type: gcp:networkconnectivity:ServiceConnectionPolicy
name: primary_cluster_region_scp
properties:
name: mypolicy-primary-cluster
location: us-east1
serviceClass: gcp-memorystore-redis
description: Primary cluster service connection policy
network: ${consumerNet.id}
pscConfig:
subnetworks:
- ${primaryClusterConsumerSubnet.id}
primaryClusterConsumerSubnet:
type: gcp:compute:Subnetwork
name: primary_cluster_consumer_subnet
properties:
name: mysubnet-primary-cluster
ipCidrRange: 10.0.1.0/29
region: us-east1
network: ${consumerNet.id}
secondaryClusterRegionScp:
type: gcp:networkconnectivity:ServiceConnectionPolicy
name: secondary_cluster_region_scp
properties:
name: mypolicy-secondary-cluster
location: europe-west1
serviceClass: gcp-memorystore-redis
description: Secondary cluster service connection policy
network: ${consumerNet.id}
pscConfig:
subnetworks:
- ${secondaryClusterConsumerSubnet.id}
secondaryClusterConsumerSubnet:
type: gcp:compute:Subnetwork
name: secondary_cluster_consumer_subnet
properties:
name: mysubnet-secondary-cluster
ipCidrRange: 10.0.2.0/29
region: europe-west1
network: ${consumerNet.id}
consumerNet:
type: gcp:compute:Network
name: consumer_net
properties:
name: mynetwork
autoCreateSubnetworks: false
The crossClusterReplicationConfig property establishes the replication relationship. The secondary cluster sets clusterRole to SECONDARY and references the primary cluster ID. Changes to the primary propagate automatically to secondaries. Each cluster requires its own VPC network and ServiceConnectionPolicy in its region. The documentation includes detailed procedures for switchover and detachment operations.
Enable RDB snapshots for point-in-time recovery
Clusters storing critical data enable RDB persistence to create periodic snapshots that can restore data after failures or accidental deletions.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const consumerNet = new gcp.compute.Network("consumer_net", {
name: "my-network",
autoCreateSubnetworks: false,
});
const consumerSubnet = new gcp.compute.Subnetwork("consumer_subnet", {
name: "my-subnet",
ipCidrRange: "10.0.0.248/29",
region: "us-central1",
network: consumerNet.id,
});
const _default = new gcp.networkconnectivity.ServiceConnectionPolicy("default", {
name: "my-policy",
location: "us-central1",
serviceClass: "gcp-memorystore-redis",
description: "my basic service connection policy",
network: consumerNet.id,
pscConfig: {
subnetworks: [consumerSubnet.id],
},
});
const cluster_rdb = new gcp.redis.Cluster("cluster-rdb", {
name: "rdb-cluster",
shardCount: 3,
pscConfigs: [{
network: consumerNet.id,
}],
region: "us-central1",
replicaCount: 0,
nodeType: "REDIS_SHARED_CORE_NANO",
transitEncryptionMode: "TRANSIT_ENCRYPTION_MODE_DISABLED",
authorizationMode: "AUTH_MODE_DISABLED",
redisConfigs: {
"maxmemory-policy": "volatile-ttl",
},
deletionProtectionEnabled: true,
zoneDistributionConfig: {
mode: "MULTI_ZONE",
},
maintenancePolicy: {
weeklyMaintenanceWindows: [{
day: "MONDAY",
startTime: {
hours: 1,
minutes: 0,
seconds: 0,
nanos: 0,
},
}],
},
persistenceConfig: {
mode: "RDB",
rdbConfig: {
rdbSnapshotPeriod: "ONE_HOUR",
rdbSnapshotStartTime: "2024-10-02T15:01:23Z",
},
},
}, {
dependsOn: [_default],
});
import pulumi
import pulumi_gcp as gcp
consumer_net = gcp.compute.Network("consumer_net",
name="my-network",
auto_create_subnetworks=False)
consumer_subnet = gcp.compute.Subnetwork("consumer_subnet",
name="my-subnet",
ip_cidr_range="10.0.0.248/29",
region="us-central1",
network=consumer_net.id)
default = gcp.networkconnectivity.ServiceConnectionPolicy("default",
name="my-policy",
location="us-central1",
service_class="gcp-memorystore-redis",
description="my basic service connection policy",
network=consumer_net.id,
psc_config={
"subnetworks": [consumer_subnet.id],
})
cluster_rdb = gcp.redis.Cluster("cluster-rdb",
name="rdb-cluster",
shard_count=3,
psc_configs=[{
"network": consumer_net.id,
}],
region="us-central1",
replica_count=0,
node_type="REDIS_SHARED_CORE_NANO",
transit_encryption_mode="TRANSIT_ENCRYPTION_MODE_DISABLED",
authorization_mode="AUTH_MODE_DISABLED",
redis_configs={
"maxmemory-policy": "volatile-ttl",
},
deletion_protection_enabled=True,
zone_distribution_config={
"mode": "MULTI_ZONE",
},
maintenance_policy={
"weekly_maintenance_windows": [{
"day": "MONDAY",
"start_time": {
"hours": 1,
"minutes": 0,
"seconds": 0,
"nanos": 0,
},
}],
},
persistence_config={
"mode": "RDB",
"rdb_config": {
"rdb_snapshot_period": "ONE_HOUR",
"rdb_snapshot_start_time": "2024-10-02T15:01:23Z",
},
},
opts = pulumi.ResourceOptions(depends_on=[default]))
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networkconnectivity"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/redis"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
consumerNet, err := compute.NewNetwork(ctx, "consumer_net", &compute.NetworkArgs{
Name: pulumi.String("my-network"),
AutoCreateSubnetworks: pulumi.Bool(false),
})
if err != nil {
return err
}
consumerSubnet, err := compute.NewSubnetwork(ctx, "consumer_subnet", &compute.SubnetworkArgs{
Name: pulumi.String("my-subnet"),
IpCidrRange: pulumi.String("10.0.0.248/29"),
Region: pulumi.String("us-central1"),
Network: consumerNet.ID(),
})
if err != nil {
return err
}
_default, err := networkconnectivity.NewServiceConnectionPolicy(ctx, "default", &networkconnectivity.ServiceConnectionPolicyArgs{
Name: pulumi.String("my-policy"),
Location: pulumi.String("us-central1"),
ServiceClass: pulumi.String("gcp-memorystore-redis"),
Description: pulumi.String("my basic service connection policy"),
Network: consumerNet.ID(),
PscConfig: &networkconnectivity.ServiceConnectionPolicyPscConfigArgs{
Subnetworks: pulumi.StringArray{
consumerSubnet.ID(),
},
},
})
if err != nil {
return err
}
_, err = redis.NewCluster(ctx, "cluster-rdb", &redis.ClusterArgs{
Name: pulumi.String("rdb-cluster"),
ShardCount: pulumi.Int(3),
PscConfigs: redis.ClusterPscConfigArray{
&redis.ClusterPscConfigArgs{
Network: consumerNet.ID(),
},
},
Region: pulumi.String("us-central1"),
ReplicaCount: pulumi.Int(0),
NodeType: pulumi.String("REDIS_SHARED_CORE_NANO"),
TransitEncryptionMode: pulumi.String("TRANSIT_ENCRYPTION_MODE_DISABLED"),
AuthorizationMode: pulumi.String("AUTH_MODE_DISABLED"),
RedisConfigs: pulumi.StringMap{
"maxmemory-policy": pulumi.String("volatile-ttl"),
},
DeletionProtectionEnabled: pulumi.Bool(true),
ZoneDistributionConfig: &redis.ClusterZoneDistributionConfigArgs{
Mode: pulumi.String("MULTI_ZONE"),
},
MaintenancePolicy: &redis.ClusterMaintenancePolicyArgs{
WeeklyMaintenanceWindows: redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowArray{
&redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs{
Day: pulumi.String("MONDAY"),
StartTime: &redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs{
Hours: pulumi.Int(1),
Minutes: pulumi.Int(0),
Seconds: pulumi.Int(0),
Nanos: pulumi.Int(0),
},
},
},
},
PersistenceConfig: &redis.ClusterPersistenceConfigArgs{
Mode: pulumi.String("RDB"),
RdbConfig: &redis.ClusterPersistenceConfigRdbConfigArgs{
RdbSnapshotPeriod: pulumi.String("ONE_HOUR"),
RdbSnapshotStartTime: pulumi.String("2024-10-02T15:01:23Z"),
},
},
}, pulumi.DependsOn([]pulumi.Resource{
_default,
}))
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 consumerNet = new Gcp.Compute.Network("consumer_net", new()
{
Name = "my-network",
AutoCreateSubnetworks = false,
});
var consumerSubnet = new Gcp.Compute.Subnetwork("consumer_subnet", new()
{
Name = "my-subnet",
IpCidrRange = "10.0.0.248/29",
Region = "us-central1",
Network = consumerNet.Id,
});
var @default = new Gcp.NetworkConnectivity.ServiceConnectionPolicy("default", new()
{
Name = "my-policy",
Location = "us-central1",
ServiceClass = "gcp-memorystore-redis",
Description = "my basic service connection policy",
Network = consumerNet.Id,
PscConfig = new Gcp.NetworkConnectivity.Inputs.ServiceConnectionPolicyPscConfigArgs
{
Subnetworks = new[]
{
consumerSubnet.Id,
},
},
});
var cluster_rdb = new Gcp.Redis.Cluster("cluster-rdb", new()
{
Name = "rdb-cluster",
ShardCount = 3,
PscConfigs = new[]
{
new Gcp.Redis.Inputs.ClusterPscConfigArgs
{
Network = consumerNet.Id,
},
},
Region = "us-central1",
ReplicaCount = 0,
NodeType = "REDIS_SHARED_CORE_NANO",
TransitEncryptionMode = "TRANSIT_ENCRYPTION_MODE_DISABLED",
AuthorizationMode = "AUTH_MODE_DISABLED",
RedisConfigs =
{
{ "maxmemory-policy", "volatile-ttl" },
},
DeletionProtectionEnabled = true,
ZoneDistributionConfig = new Gcp.Redis.Inputs.ClusterZoneDistributionConfigArgs
{
Mode = "MULTI_ZONE",
},
MaintenancePolicy = new Gcp.Redis.Inputs.ClusterMaintenancePolicyArgs
{
WeeklyMaintenanceWindows = new[]
{
new Gcp.Redis.Inputs.ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs
{
Day = "MONDAY",
StartTime = new Gcp.Redis.Inputs.ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs
{
Hours = 1,
Minutes = 0,
Seconds = 0,
Nanos = 0,
},
},
},
},
PersistenceConfig = new Gcp.Redis.Inputs.ClusterPersistenceConfigArgs
{
Mode = "RDB",
RdbConfig = new Gcp.Redis.Inputs.ClusterPersistenceConfigRdbConfigArgs
{
RdbSnapshotPeriod = "ONE_HOUR",
RdbSnapshotStartTime = "2024-10-02T15:01:23Z",
},
},
}, new CustomResourceOptions
{
DependsOn =
{
@default,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.Network;
import com.pulumi.gcp.compute.NetworkArgs;
import com.pulumi.gcp.compute.Subnetwork;
import com.pulumi.gcp.compute.SubnetworkArgs;
import com.pulumi.gcp.networkconnectivity.ServiceConnectionPolicy;
import com.pulumi.gcp.networkconnectivity.ServiceConnectionPolicyArgs;
import com.pulumi.gcp.networkconnectivity.inputs.ServiceConnectionPolicyPscConfigArgs;
import com.pulumi.gcp.redis.Cluster;
import com.pulumi.gcp.redis.ClusterArgs;
import com.pulumi.gcp.redis.inputs.ClusterPscConfigArgs;
import com.pulumi.gcp.redis.inputs.ClusterZoneDistributionConfigArgs;
import com.pulumi.gcp.redis.inputs.ClusterMaintenancePolicyArgs;
import com.pulumi.gcp.redis.inputs.ClusterPersistenceConfigArgs;
import com.pulumi.gcp.redis.inputs.ClusterPersistenceConfigRdbConfigArgs;
import com.pulumi.resources.CustomResourceOptions;
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 consumerNet = new Network("consumerNet", NetworkArgs.builder()
.name("my-network")
.autoCreateSubnetworks(false)
.build());
var consumerSubnet = new Subnetwork("consumerSubnet", SubnetworkArgs.builder()
.name("my-subnet")
.ipCidrRange("10.0.0.248/29")
.region("us-central1")
.network(consumerNet.id())
.build());
var default_ = new ServiceConnectionPolicy("default", ServiceConnectionPolicyArgs.builder()
.name("my-policy")
.location("us-central1")
.serviceClass("gcp-memorystore-redis")
.description("my basic service connection policy")
.network(consumerNet.id())
.pscConfig(ServiceConnectionPolicyPscConfigArgs.builder()
.subnetworks(consumerSubnet.id())
.build())
.build());
var cluster_rdb = new Cluster("cluster-rdb", ClusterArgs.builder()
.name("rdb-cluster")
.shardCount(3)
.pscConfigs(ClusterPscConfigArgs.builder()
.network(consumerNet.id())
.build())
.region("us-central1")
.replicaCount(0)
.nodeType("REDIS_SHARED_CORE_NANO")
.transitEncryptionMode("TRANSIT_ENCRYPTION_MODE_DISABLED")
.authorizationMode("AUTH_MODE_DISABLED")
.redisConfigs(Map.of("maxmemory-policy", "volatile-ttl"))
.deletionProtectionEnabled(true)
.zoneDistributionConfig(ClusterZoneDistributionConfigArgs.builder()
.mode("MULTI_ZONE")
.build())
.maintenancePolicy(ClusterMaintenancePolicyArgs.builder()
.weeklyMaintenanceWindows(ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs.builder()
.day("MONDAY")
.startTime(ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs.builder()
.hours(1)
.minutes(0)
.seconds(0)
.nanos(0)
.build())
.build())
.build())
.persistenceConfig(ClusterPersistenceConfigArgs.builder()
.mode("RDB")
.rdbConfig(ClusterPersistenceConfigRdbConfigArgs.builder()
.rdbSnapshotPeriod("ONE_HOUR")
.rdbSnapshotStartTime("2024-10-02T15:01:23Z")
.build())
.build())
.build(), CustomResourceOptions.builder()
.dependsOn(default_)
.build());
}
}
resources:
cluster-rdb:
type: gcp:redis:Cluster
properties:
name: rdb-cluster
shardCount: 3
pscConfigs:
- network: ${consumerNet.id}
region: us-central1
replicaCount: 0
nodeType: REDIS_SHARED_CORE_NANO
transitEncryptionMode: TRANSIT_ENCRYPTION_MODE_DISABLED
authorizationMode: AUTH_MODE_DISABLED
redisConfigs:
maxmemory-policy: volatile-ttl
deletionProtectionEnabled: true
zoneDistributionConfig:
mode: MULTI_ZONE
maintenancePolicy:
weeklyMaintenanceWindows:
- day: MONDAY
startTime:
hours: 1
minutes: 0
seconds: 0
nanos: 0
persistenceConfig:
mode: RDB
rdbConfig:
rdbSnapshotPeriod: ONE_HOUR
rdbSnapshotStartTime: 2024-10-02T15:01:23Z
options:
dependsOn:
- ${default}
default:
type: gcp:networkconnectivity:ServiceConnectionPolicy
properties:
name: my-policy
location: us-central1
serviceClass: gcp-memorystore-redis
description: my basic service connection policy
network: ${consumerNet.id}
pscConfig:
subnetworks:
- ${consumerSubnet.id}
consumerSubnet:
type: gcp:compute:Subnetwork
name: consumer_subnet
properties:
name: my-subnet
ipCidrRange: 10.0.0.248/29
region: us-central1
network: ${consumerNet.id}
consumerNet:
type: gcp:compute:Network
name: consumer_net
properties:
name: my-network
autoCreateSubnetworks: false
The persistenceConfig property with mode RDB enables snapshot-based persistence. The rdbSnapshotPeriod controls how frequently snapshots occur (ONE_HOUR, SIX_HOURS, TWELVE_HOURS, or TWENTY_FOUR_HOURS). The rdbSnapshotStartTime sets when the first snapshot begins. RDB provides good durability with minimal performance impact but may lose writes between snapshots.
Enable AOF logging for maximum durability
Workloads that cannot tolerate any data loss use AOF persistence to log every write operation, providing stronger durability guarantees than RDB snapshots.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const consumerNet = new gcp.compute.Network("consumer_net", {
name: "my-network",
autoCreateSubnetworks: false,
});
const consumerSubnet = new gcp.compute.Subnetwork("consumer_subnet", {
name: "my-subnet",
ipCidrRange: "10.0.0.248/29",
region: "us-central1",
network: consumerNet.id,
});
const _default = new gcp.networkconnectivity.ServiceConnectionPolicy("default", {
name: "my-policy",
location: "us-central1",
serviceClass: "gcp-memorystore-redis",
description: "my basic service connection policy",
network: consumerNet.id,
pscConfig: {
subnetworks: [consumerSubnet.id],
},
});
const cluster_aof = new gcp.redis.Cluster("cluster-aof", {
name: "aof-cluster",
shardCount: 3,
pscConfigs: [{
network: consumerNet.id,
}],
region: "us-central1",
replicaCount: 0,
nodeType: "REDIS_SHARED_CORE_NANO",
transitEncryptionMode: "TRANSIT_ENCRYPTION_MODE_DISABLED",
authorizationMode: "AUTH_MODE_DISABLED",
redisConfigs: {
"maxmemory-policy": "volatile-ttl",
},
deletionProtectionEnabled: true,
zoneDistributionConfig: {
mode: "MULTI_ZONE",
},
maintenancePolicy: {
weeklyMaintenanceWindows: [{
day: "MONDAY",
startTime: {
hours: 1,
minutes: 0,
seconds: 0,
nanos: 0,
},
}],
},
persistenceConfig: {
mode: "AOF",
aofConfig: {
appendFsync: "EVERYSEC",
},
},
}, {
dependsOn: [_default],
});
import pulumi
import pulumi_gcp as gcp
consumer_net = gcp.compute.Network("consumer_net",
name="my-network",
auto_create_subnetworks=False)
consumer_subnet = gcp.compute.Subnetwork("consumer_subnet",
name="my-subnet",
ip_cidr_range="10.0.0.248/29",
region="us-central1",
network=consumer_net.id)
default = gcp.networkconnectivity.ServiceConnectionPolicy("default",
name="my-policy",
location="us-central1",
service_class="gcp-memorystore-redis",
description="my basic service connection policy",
network=consumer_net.id,
psc_config={
"subnetworks": [consumer_subnet.id],
})
cluster_aof = gcp.redis.Cluster("cluster-aof",
name="aof-cluster",
shard_count=3,
psc_configs=[{
"network": consumer_net.id,
}],
region="us-central1",
replica_count=0,
node_type="REDIS_SHARED_CORE_NANO",
transit_encryption_mode="TRANSIT_ENCRYPTION_MODE_DISABLED",
authorization_mode="AUTH_MODE_DISABLED",
redis_configs={
"maxmemory-policy": "volatile-ttl",
},
deletion_protection_enabled=True,
zone_distribution_config={
"mode": "MULTI_ZONE",
},
maintenance_policy={
"weekly_maintenance_windows": [{
"day": "MONDAY",
"start_time": {
"hours": 1,
"minutes": 0,
"seconds": 0,
"nanos": 0,
},
}],
},
persistence_config={
"mode": "AOF",
"aof_config": {
"append_fsync": "EVERYSEC",
},
},
opts = pulumi.ResourceOptions(depends_on=[default]))
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networkconnectivity"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/redis"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
consumerNet, err := compute.NewNetwork(ctx, "consumer_net", &compute.NetworkArgs{
Name: pulumi.String("my-network"),
AutoCreateSubnetworks: pulumi.Bool(false),
})
if err != nil {
return err
}
consumerSubnet, err := compute.NewSubnetwork(ctx, "consumer_subnet", &compute.SubnetworkArgs{
Name: pulumi.String("my-subnet"),
IpCidrRange: pulumi.String("10.0.0.248/29"),
Region: pulumi.String("us-central1"),
Network: consumerNet.ID(),
})
if err != nil {
return err
}
_default, err := networkconnectivity.NewServiceConnectionPolicy(ctx, "default", &networkconnectivity.ServiceConnectionPolicyArgs{
Name: pulumi.String("my-policy"),
Location: pulumi.String("us-central1"),
ServiceClass: pulumi.String("gcp-memorystore-redis"),
Description: pulumi.String("my basic service connection policy"),
Network: consumerNet.ID(),
PscConfig: &networkconnectivity.ServiceConnectionPolicyPscConfigArgs{
Subnetworks: pulumi.StringArray{
consumerSubnet.ID(),
},
},
})
if err != nil {
return err
}
_, err = redis.NewCluster(ctx, "cluster-aof", &redis.ClusterArgs{
Name: pulumi.String("aof-cluster"),
ShardCount: pulumi.Int(3),
PscConfigs: redis.ClusterPscConfigArray{
&redis.ClusterPscConfigArgs{
Network: consumerNet.ID(),
},
},
Region: pulumi.String("us-central1"),
ReplicaCount: pulumi.Int(0),
NodeType: pulumi.String("REDIS_SHARED_CORE_NANO"),
TransitEncryptionMode: pulumi.String("TRANSIT_ENCRYPTION_MODE_DISABLED"),
AuthorizationMode: pulumi.String("AUTH_MODE_DISABLED"),
RedisConfigs: pulumi.StringMap{
"maxmemory-policy": pulumi.String("volatile-ttl"),
},
DeletionProtectionEnabled: pulumi.Bool(true),
ZoneDistributionConfig: &redis.ClusterZoneDistributionConfigArgs{
Mode: pulumi.String("MULTI_ZONE"),
},
MaintenancePolicy: &redis.ClusterMaintenancePolicyArgs{
WeeklyMaintenanceWindows: redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowArray{
&redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs{
Day: pulumi.String("MONDAY"),
StartTime: &redis.ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs{
Hours: pulumi.Int(1),
Minutes: pulumi.Int(0),
Seconds: pulumi.Int(0),
Nanos: pulumi.Int(0),
},
},
},
},
PersistenceConfig: &redis.ClusterPersistenceConfigArgs{
Mode: pulumi.String("AOF"),
AofConfig: &redis.ClusterPersistenceConfigAofConfigArgs{
AppendFsync: pulumi.String("EVERYSEC"),
},
},
}, pulumi.DependsOn([]pulumi.Resource{
_default,
}))
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 consumerNet = new Gcp.Compute.Network("consumer_net", new()
{
Name = "my-network",
AutoCreateSubnetworks = false,
});
var consumerSubnet = new Gcp.Compute.Subnetwork("consumer_subnet", new()
{
Name = "my-subnet",
IpCidrRange = "10.0.0.248/29",
Region = "us-central1",
Network = consumerNet.Id,
});
var @default = new Gcp.NetworkConnectivity.ServiceConnectionPolicy("default", new()
{
Name = "my-policy",
Location = "us-central1",
ServiceClass = "gcp-memorystore-redis",
Description = "my basic service connection policy",
Network = consumerNet.Id,
PscConfig = new Gcp.NetworkConnectivity.Inputs.ServiceConnectionPolicyPscConfigArgs
{
Subnetworks = new[]
{
consumerSubnet.Id,
},
},
});
var cluster_aof = new Gcp.Redis.Cluster("cluster-aof", new()
{
Name = "aof-cluster",
ShardCount = 3,
PscConfigs = new[]
{
new Gcp.Redis.Inputs.ClusterPscConfigArgs
{
Network = consumerNet.Id,
},
},
Region = "us-central1",
ReplicaCount = 0,
NodeType = "REDIS_SHARED_CORE_NANO",
TransitEncryptionMode = "TRANSIT_ENCRYPTION_MODE_DISABLED",
AuthorizationMode = "AUTH_MODE_DISABLED",
RedisConfigs =
{
{ "maxmemory-policy", "volatile-ttl" },
},
DeletionProtectionEnabled = true,
ZoneDistributionConfig = new Gcp.Redis.Inputs.ClusterZoneDistributionConfigArgs
{
Mode = "MULTI_ZONE",
},
MaintenancePolicy = new Gcp.Redis.Inputs.ClusterMaintenancePolicyArgs
{
WeeklyMaintenanceWindows = new[]
{
new Gcp.Redis.Inputs.ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs
{
Day = "MONDAY",
StartTime = new Gcp.Redis.Inputs.ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs
{
Hours = 1,
Minutes = 0,
Seconds = 0,
Nanos = 0,
},
},
},
},
PersistenceConfig = new Gcp.Redis.Inputs.ClusterPersistenceConfigArgs
{
Mode = "AOF",
AofConfig = new Gcp.Redis.Inputs.ClusterPersistenceConfigAofConfigArgs
{
AppendFsync = "EVERYSEC",
},
},
}, new CustomResourceOptions
{
DependsOn =
{
@default,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.Network;
import com.pulumi.gcp.compute.NetworkArgs;
import com.pulumi.gcp.compute.Subnetwork;
import com.pulumi.gcp.compute.SubnetworkArgs;
import com.pulumi.gcp.networkconnectivity.ServiceConnectionPolicy;
import com.pulumi.gcp.networkconnectivity.ServiceConnectionPolicyArgs;
import com.pulumi.gcp.networkconnectivity.inputs.ServiceConnectionPolicyPscConfigArgs;
import com.pulumi.gcp.redis.Cluster;
import com.pulumi.gcp.redis.ClusterArgs;
import com.pulumi.gcp.redis.inputs.ClusterPscConfigArgs;
import com.pulumi.gcp.redis.inputs.ClusterZoneDistributionConfigArgs;
import com.pulumi.gcp.redis.inputs.ClusterMaintenancePolicyArgs;
import com.pulumi.gcp.redis.inputs.ClusterPersistenceConfigArgs;
import com.pulumi.gcp.redis.inputs.ClusterPersistenceConfigAofConfigArgs;
import com.pulumi.resources.CustomResourceOptions;
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 consumerNet = new Network("consumerNet", NetworkArgs.builder()
.name("my-network")
.autoCreateSubnetworks(false)
.build());
var consumerSubnet = new Subnetwork("consumerSubnet", SubnetworkArgs.builder()
.name("my-subnet")
.ipCidrRange("10.0.0.248/29")
.region("us-central1")
.network(consumerNet.id())
.build());
var default_ = new ServiceConnectionPolicy("default", ServiceConnectionPolicyArgs.builder()
.name("my-policy")
.location("us-central1")
.serviceClass("gcp-memorystore-redis")
.description("my basic service connection policy")
.network(consumerNet.id())
.pscConfig(ServiceConnectionPolicyPscConfigArgs.builder()
.subnetworks(consumerSubnet.id())
.build())
.build());
var cluster_aof = new Cluster("cluster-aof", ClusterArgs.builder()
.name("aof-cluster")
.shardCount(3)
.pscConfigs(ClusterPscConfigArgs.builder()
.network(consumerNet.id())
.build())
.region("us-central1")
.replicaCount(0)
.nodeType("REDIS_SHARED_CORE_NANO")
.transitEncryptionMode("TRANSIT_ENCRYPTION_MODE_DISABLED")
.authorizationMode("AUTH_MODE_DISABLED")
.redisConfigs(Map.of("maxmemory-policy", "volatile-ttl"))
.deletionProtectionEnabled(true)
.zoneDistributionConfig(ClusterZoneDistributionConfigArgs.builder()
.mode("MULTI_ZONE")
.build())
.maintenancePolicy(ClusterMaintenancePolicyArgs.builder()
.weeklyMaintenanceWindows(ClusterMaintenancePolicyWeeklyMaintenanceWindowArgs.builder()
.day("MONDAY")
.startTime(ClusterMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs.builder()
.hours(1)
.minutes(0)
.seconds(0)
.nanos(0)
.build())
.build())
.build())
.persistenceConfig(ClusterPersistenceConfigArgs.builder()
.mode("AOF")
.aofConfig(ClusterPersistenceConfigAofConfigArgs.builder()
.appendFsync("EVERYSEC")
.build())
.build())
.build(), CustomResourceOptions.builder()
.dependsOn(default_)
.build());
}
}
resources:
cluster-aof:
type: gcp:redis:Cluster
properties:
name: aof-cluster
shardCount: 3
pscConfigs:
- network: ${consumerNet.id}
region: us-central1
replicaCount: 0
nodeType: REDIS_SHARED_CORE_NANO
transitEncryptionMode: TRANSIT_ENCRYPTION_MODE_DISABLED
authorizationMode: AUTH_MODE_DISABLED
redisConfigs:
maxmemory-policy: volatile-ttl
deletionProtectionEnabled: true
zoneDistributionConfig:
mode: MULTI_ZONE
maintenancePolicy:
weeklyMaintenanceWindows:
- day: MONDAY
startTime:
hours: 1
minutes: 0
seconds: 0
nanos: 0
persistenceConfig:
mode: AOF
aofConfig:
appendFsync: EVERYSEC
options:
dependsOn:
- ${default}
default:
type: gcp:networkconnectivity:ServiceConnectionPolicy
properties:
name: my-policy
location: us-central1
serviceClass: gcp-memorystore-redis
description: my basic service connection policy
network: ${consumerNet.id}
pscConfig:
subnetworks:
- ${consumerSubnet.id}
consumerSubnet:
type: gcp:compute:Subnetwork
name: consumer_subnet
properties:
name: my-subnet
ipCidrRange: 10.0.0.248/29
region: us-central1
network: ${consumerNet.id}
consumerNet:
type: gcp:compute:Network
name: consumer_net
properties:
name: my-network
autoCreateSubnetworks: false
Setting persistenceConfig.mode to AOF enables append-only file logging. The appendFsync property controls when writes are flushed to disk: EVERYSEC flushes every second (balancing durability and performance), while ALWAYS flushes after every write (maximum durability, higher latency). AOF provides stronger guarantees than RDB but uses more disk I/O.
Encrypt data with customer-managed keys
Organizations with strict compliance requirements use customer-managed encryption keys to maintain control over data encryption and key rotation policies.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const consumerNet = new gcp.compute.Network("consumer_net", {
name: "my-network",
autoCreateSubnetworks: false,
});
const consumerSubnet = new gcp.compute.Subnetwork("consumer_subnet", {
name: "my-subnet",
ipCidrRange: "10.0.0.248/29",
region: "us-central1",
network: consumerNet.id,
});
const _default = new gcp.networkconnectivity.ServiceConnectionPolicy("default", {
name: "my-policy",
location: "us-central1",
serviceClass: "gcp-memorystore-redis",
description: "my basic service connection policy",
network: consumerNet.id,
pscConfig: {
subnetworks: [consumerSubnet.id],
},
});
const cluster_cmek = new gcp.redis.Cluster("cluster-cmek", {
name: "cmek-cluster",
shardCount: 3,
pscConfigs: [{
network: consumerNet.id,
}],
kmsKey: "my-key",
region: "us-central1",
deletionProtectionEnabled: true,
}, {
dependsOn: [_default],
});
const project = gcp.organizations.getProject({});
import pulumi
import pulumi_gcp as gcp
consumer_net = gcp.compute.Network("consumer_net",
name="my-network",
auto_create_subnetworks=False)
consumer_subnet = gcp.compute.Subnetwork("consumer_subnet",
name="my-subnet",
ip_cidr_range="10.0.0.248/29",
region="us-central1",
network=consumer_net.id)
default = gcp.networkconnectivity.ServiceConnectionPolicy("default",
name="my-policy",
location="us-central1",
service_class="gcp-memorystore-redis",
description="my basic service connection policy",
network=consumer_net.id,
psc_config={
"subnetworks": [consumer_subnet.id],
})
cluster_cmek = gcp.redis.Cluster("cluster-cmek",
name="cmek-cluster",
shard_count=3,
psc_configs=[{
"network": consumer_net.id,
}],
kms_key="my-key",
region="us-central1",
deletion_protection_enabled=True,
opts = pulumi.ResourceOptions(depends_on=[default]))
project = gcp.organizations.get_project()
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networkconnectivity"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/organizations"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/redis"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
consumerNet, err := compute.NewNetwork(ctx, "consumer_net", &compute.NetworkArgs{
Name: pulumi.String("my-network"),
AutoCreateSubnetworks: pulumi.Bool(false),
})
if err != nil {
return err
}
consumerSubnet, err := compute.NewSubnetwork(ctx, "consumer_subnet", &compute.SubnetworkArgs{
Name: pulumi.String("my-subnet"),
IpCidrRange: pulumi.String("10.0.0.248/29"),
Region: pulumi.String("us-central1"),
Network: consumerNet.ID(),
})
if err != nil {
return err
}
_default, err := networkconnectivity.NewServiceConnectionPolicy(ctx, "default", &networkconnectivity.ServiceConnectionPolicyArgs{
Name: pulumi.String("my-policy"),
Location: pulumi.String("us-central1"),
ServiceClass: pulumi.String("gcp-memorystore-redis"),
Description: pulumi.String("my basic service connection policy"),
Network: consumerNet.ID(),
PscConfig: &networkconnectivity.ServiceConnectionPolicyPscConfigArgs{
Subnetworks: pulumi.StringArray{
consumerSubnet.ID(),
},
},
})
if err != nil {
return err
}
_, err = redis.NewCluster(ctx, "cluster-cmek", &redis.ClusterArgs{
Name: pulumi.String("cmek-cluster"),
ShardCount: pulumi.Int(3),
PscConfigs: redis.ClusterPscConfigArray{
&redis.ClusterPscConfigArgs{
Network: consumerNet.ID(),
},
},
KmsKey: pulumi.String("my-key"),
Region: pulumi.String("us-central1"),
DeletionProtectionEnabled: pulumi.Bool(true),
}, pulumi.DependsOn([]pulumi.Resource{
_default,
}))
if err != nil {
return err
}
_, err = organizations.LookupProject(ctx, &organizations.LookupProjectArgs{}, nil)
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 consumerNet = new Gcp.Compute.Network("consumer_net", new()
{
Name = "my-network",
AutoCreateSubnetworks = false,
});
var consumerSubnet = new Gcp.Compute.Subnetwork("consumer_subnet", new()
{
Name = "my-subnet",
IpCidrRange = "10.0.0.248/29",
Region = "us-central1",
Network = consumerNet.Id,
});
var @default = new Gcp.NetworkConnectivity.ServiceConnectionPolicy("default", new()
{
Name = "my-policy",
Location = "us-central1",
ServiceClass = "gcp-memorystore-redis",
Description = "my basic service connection policy",
Network = consumerNet.Id,
PscConfig = new Gcp.NetworkConnectivity.Inputs.ServiceConnectionPolicyPscConfigArgs
{
Subnetworks = new[]
{
consumerSubnet.Id,
},
},
});
var cluster_cmek = new Gcp.Redis.Cluster("cluster-cmek", new()
{
Name = "cmek-cluster",
ShardCount = 3,
PscConfigs = new[]
{
new Gcp.Redis.Inputs.ClusterPscConfigArgs
{
Network = consumerNet.Id,
},
},
KmsKey = "my-key",
Region = "us-central1",
DeletionProtectionEnabled = true,
}, new CustomResourceOptions
{
DependsOn =
{
@default,
},
});
var project = Gcp.Organizations.GetProject.Invoke();
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.Network;
import com.pulumi.gcp.compute.NetworkArgs;
import com.pulumi.gcp.compute.Subnetwork;
import com.pulumi.gcp.compute.SubnetworkArgs;
import com.pulumi.gcp.networkconnectivity.ServiceConnectionPolicy;
import com.pulumi.gcp.networkconnectivity.ServiceConnectionPolicyArgs;
import com.pulumi.gcp.networkconnectivity.inputs.ServiceConnectionPolicyPscConfigArgs;
import com.pulumi.gcp.redis.Cluster;
import com.pulumi.gcp.redis.ClusterArgs;
import com.pulumi.gcp.redis.inputs.ClusterPscConfigArgs;
import com.pulumi.gcp.organizations.OrganizationsFunctions;
import com.pulumi.gcp.organizations.inputs.GetProjectArgs;
import com.pulumi.resources.CustomResourceOptions;
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 consumerNet = new Network("consumerNet", NetworkArgs.builder()
.name("my-network")
.autoCreateSubnetworks(false)
.build());
var consumerSubnet = new Subnetwork("consumerSubnet", SubnetworkArgs.builder()
.name("my-subnet")
.ipCidrRange("10.0.0.248/29")
.region("us-central1")
.network(consumerNet.id())
.build());
var default_ = new ServiceConnectionPolicy("default", ServiceConnectionPolicyArgs.builder()
.name("my-policy")
.location("us-central1")
.serviceClass("gcp-memorystore-redis")
.description("my basic service connection policy")
.network(consumerNet.id())
.pscConfig(ServiceConnectionPolicyPscConfigArgs.builder()
.subnetworks(consumerSubnet.id())
.build())
.build());
var cluster_cmek = new Cluster("cluster-cmek", ClusterArgs.builder()
.name("cmek-cluster")
.shardCount(3)
.pscConfigs(ClusterPscConfigArgs.builder()
.network(consumerNet.id())
.build())
.kmsKey("my-key")
.region("us-central1")
.deletionProtectionEnabled(true)
.build(), CustomResourceOptions.builder()
.dependsOn(default_)
.build());
final var project = OrganizationsFunctions.getProject(GetProjectArgs.builder()
.build());
}
}
resources:
cluster-cmek:
type: gcp:redis:Cluster
properties:
name: cmek-cluster
shardCount: 3
pscConfigs:
- network: ${consumerNet.id}
kmsKey: my-key
region: us-central1
deletionProtectionEnabled: true
options:
dependsOn:
- ${default}
default:
type: gcp:networkconnectivity:ServiceConnectionPolicy
properties:
name: my-policy
location: us-central1
serviceClass: gcp-memorystore-redis
description: my basic service connection policy
network: ${consumerNet.id}
pscConfig:
subnetworks:
- ${consumerSubnet.id}
consumerSubnet:
type: gcp:compute:Subnetwork
name: consumer_subnet
properties:
name: my-subnet
ipCidrRange: 10.0.0.248/29
region: us-central1
network: ${consumerNet.id}
consumerNet:
type: gcp:compute:Network
name: consumer_net
properties:
name: my-network
autoCreateSubnetworks: false
variables:
project:
fn::invoke:
function: gcp:organizations:getProject
arguments: {}
The kmsKey property references a Cloud KMS key for encrypting cluster data at rest. You control key rotation, access policies, and audit logging through Cloud KMS. The cluster service account needs cryptoKeyEncrypterDecrypter permissions on the key. This satisfies compliance requirements that prohibit Google-managed encryption keys.
Beyond these examples
These snippets focus on specific cluster-level features: high availability and zone distribution, cross-region replication, persistence (RDB snapshots and AOF logging), and customer-managed encryption. They’re intentionally minimal rather than full Redis deployments.
The examples reference pre-existing infrastructure such as VPC networks and subnets, ServiceConnectionPolicy for PSC connectivity, KMS keys (for CMEK example), and primary clusters (for secondary cluster example). They focus on configuring the cluster rather than provisioning the surrounding network infrastructure.
To keep things focused, common cluster patterns are omitted, including:
- Labels and resource tagging
- Redis configuration parameters (redisConfigs)
- Maintenance windows and version management
- Authorization modes (IAM vs disabled)
- Transit encryption and TLS configuration
- Automated backup configuration
These omissions are intentional: the goal is to illustrate how each cluster feature is wired, not provide drop-in Redis modules. See the Redis Cluster resource reference for all available configuration options.
Let's deploy GCP Cloud Memorystore Redis Clusters
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Cross-Region Replication
crossClusterReplicationConfig: change clusterRole from SECONDARY to PRIMARY, remove primaryCluster, and set secondaryCluster list with the new secondaries. Run pulumi up, then manually sync configuration drift on other clusters by updating their config files with values from state.crossClusterReplicationConfig by changing clusterRole to NONE and removing primaryCluster, or (2) Update the primary’s secondaryCluster list to remove the secondary. After running pulumi up, manually reconcile configuration drift on affected clusters.pulumi preview will show drift that must be resolved by manually updating configuration files with the latest values from state.Networking & Connectivity
gcp.networkconnectivity.ServiceConnectionPolicy for Private Service Connect (PSC) networking. All examples show this as a dependency using dependsOn.pscConfig is supported per cluster, even though the property accepts an array.gcp.redis.ClusterUserCreatedConnections when you need User-registered PSC Connections for Multiple VPC Networking scenarios.Security & Encryption
authorizationMode (e.g., AUTH_MODE_IAM_AUTH) and transitEncryptionMode (e.g., TRANSIT_ENCRYPTION_MODE_SERVER_AUTHENTICATION). Both are immutable and default to disabled, so configure them during initial creation.kmsKey property to your Cloud KMS key resource name.transitEncryptionMode to TRANSIT_ENCRYPTION_MODE_SERVER_AUTHENTICATION, serverCaMode to SERVER_CA_MODE_CUSTOMER_MANAGED_CAS_CA, and serverCaPool to your Certificate Authority Service pool ID.High Availability & Persistence
rdbSnapshotPeriod (e.g., ONE_HOUR), while AOF appends every write operation with configurable sync frequency via appendFsync (e.g., EVERYSEC).replicaCount to the desired number of replica nodes per shard (e.g., 1 or 2). Configure zoneDistributionConfig with mode: MULTI_ZONE to distribute replicas across zones.Configuration & Maintenance
name, project, region, zoneDistributionConfig, authorizationMode, transitEncryptionMode, gcsSource, and managedBackupSource. Plan these carefully during initial creation.maintenanceVersion field only supports upgrades to newer versions. Downgrades are not currently supported.deletionProtectionEnabled defaults to true. Any delete operation will fail unless you explicitly set this to false.