The gcp:redis/instance:Instance resource, part of the Pulumi GCP provider, provisions a Google Cloud Memorystore Redis instance: its tier, memory size, networking, and optional features like persistence and encryption. This guide focuses on four capabilities: basic and highly available deployments, data persistence with RDB snapshots, private networking and read replicas, and customer-managed encryption keys.
Redis instances run in a VPC network and may reference KMS keys or VPC peering configurations. The examples are intentionally small. Combine them with your own VPC networks, security policies, and monitoring.
Create a basic Redis instance with minimal configuration
Most deployments start with a minimal instance for caching or session storage. The BASIC tier provides a single-node instance suitable for development or non-critical workloads.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const cache = new gcp.redis.Instance("cache", {
name: "memory-cache",
memorySizeGb: 1,
deletionProtection: false,
});
import pulumi
import pulumi_gcp as gcp
cache = gcp.redis.Instance("cache",
name="memory-cache",
memory_size_gb=1,
deletion_protection=False)
package main
import (
"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 {
_, err := redis.NewInstance(ctx, "cache", &redis.InstanceArgs{
Name: pulumi.String("memory-cache"),
MemorySizeGb: pulumi.Int(1),
DeletionProtection: pulumi.Bool(false),
})
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 cache = new Gcp.Redis.Instance("cache", new()
{
Name = "memory-cache",
MemorySizeGb = 1,
DeletionProtection = false,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.redis.Instance;
import com.pulumi.gcp.redis.InstanceArgs;
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 cache = new Instance("cache", InstanceArgs.builder()
.name("memory-cache")
.memorySizeGb(1)
.deletionProtection(false)
.build());
}
}
resources:
cache:
type: gcp:redis:Instance
properties:
name: memory-cache
memorySizeGb: 1
deletionProtection: false
The name property sets the instance identifier. The memorySizeGb property allocates memory capacity. Without specifying tier, the instance defaults to BASIC (single-node). The instance uses the default VPC network and GCP selects a zone automatically.
Deploy a highly available instance with maintenance windows
Production workloads require high availability across zones and scheduled maintenance to minimize disruption during updates.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
// This example assumes this network already exists.
// The API creates a tenant network per network authorized for a
// Redis instance and that network is not deleted when the user-created
// network (authorized_network) is deleted, so this prevents issues
// with tenant network quota.
// If this network hasn't been created and you are using this example in your
// config, add an additional network resource or change
// this from "data"to "resource"
const redis_network = gcp.compute.getNetwork({
name: "redis-test-network",
});
const cache = new gcp.redis.Instance("cache", {
name: "ha-memory-cache",
tier: "STANDARD_HA",
memorySizeGb: 1,
locationId: "us-central1-a",
alternativeLocationId: "us-central1-f",
authorizedNetwork: redis_network.then(redis_network => redis_network.id),
redisVersion: "REDIS_7_2",
displayName: "Test Instance",
reservedIpRange: "192.168.0.0/29",
labels: {
my_key: "my_val",
other_key: "other_val",
},
maintenancePolicy: {
weeklyMaintenanceWindows: [{
day: "TUESDAY",
startTime: {
hours: 0,
minutes: 30,
seconds: 0,
nanos: 0,
},
}],
},
});
import pulumi
import pulumi_gcp as gcp
# This example assumes this network already exists.
# The API creates a tenant network per network authorized for a
# Redis instance and that network is not deleted when the user-created
# network (authorized_network) is deleted, so this prevents issues
# with tenant network quota.
# If this network hasn't been created and you are using this example in your
# config, add an additional network resource or change
# this from "data"to "resource"
redis_network = gcp.compute.get_network(name="redis-test-network")
cache = gcp.redis.Instance("cache",
name="ha-memory-cache",
tier="STANDARD_HA",
memory_size_gb=1,
location_id="us-central1-a",
alternative_location_id="us-central1-f",
authorized_network=redis_network.id,
redis_version="REDIS_7_2",
display_name="Test Instance",
reserved_ip_range="192.168.0.0/29",
labels={
"my_key": "my_val",
"other_key": "other_val",
},
maintenance_policy={
"weekly_maintenance_windows": [{
"day": "TUESDAY",
"start_time": {
"hours": 0,
"minutes": 30,
"seconds": 0,
"nanos": 0,
},
}],
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"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 {
// This example assumes this network already exists.
// The API creates a tenant network per network authorized for a
// Redis instance and that network is not deleted when the user-created
// network (authorized_network) is deleted, so this prevents issues
// with tenant network quota.
// If this network hasn't been created and you are using this example in your
// config, add an additional network resource or change
// this from "data"to "resource"
redis_network, err := compute.LookupNetwork(ctx, &compute.LookupNetworkArgs{
Name: "redis-test-network",
}, nil)
if err != nil {
return err
}
_, err = redis.NewInstance(ctx, "cache", &redis.InstanceArgs{
Name: pulumi.String("ha-memory-cache"),
Tier: pulumi.String("STANDARD_HA"),
MemorySizeGb: pulumi.Int(1),
LocationId: pulumi.String("us-central1-a"),
AlternativeLocationId: pulumi.String("us-central1-f"),
AuthorizedNetwork: pulumi.String(redis_network.Id),
RedisVersion: pulumi.String("REDIS_7_2"),
DisplayName: pulumi.String("Test Instance"),
ReservedIpRange: pulumi.String("192.168.0.0/29"),
Labels: pulumi.StringMap{
"my_key": pulumi.String("my_val"),
"other_key": pulumi.String("other_val"),
},
MaintenancePolicy: &redis.InstanceMaintenancePolicyArgs{
WeeklyMaintenanceWindows: redis.InstanceMaintenancePolicyWeeklyMaintenanceWindowArray{
&redis.InstanceMaintenancePolicyWeeklyMaintenanceWindowArgs{
Day: pulumi.String("TUESDAY"),
StartTime: &redis.InstanceMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs{
Hours: pulumi.Int(0),
Minutes: pulumi.Int(30),
Seconds: pulumi.Int(0),
Nanos: pulumi.Int(0),
},
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
// This example assumes this network already exists.
// The API creates a tenant network per network authorized for a
// Redis instance and that network is not deleted when the user-created
// network (authorized_network) is deleted, so this prevents issues
// with tenant network quota.
// If this network hasn't been created and you are using this example in your
// config, add an additional network resource or change
// this from "data"to "resource"
var redis_network = Gcp.Compute.GetNetwork.Invoke(new()
{
Name = "redis-test-network",
});
var cache = new Gcp.Redis.Instance("cache", new()
{
Name = "ha-memory-cache",
Tier = "STANDARD_HA",
MemorySizeGb = 1,
LocationId = "us-central1-a",
AlternativeLocationId = "us-central1-f",
AuthorizedNetwork = redis_network.Apply(redis_network => redis_network.Apply(getNetworkResult => getNetworkResult.Id)),
RedisVersion = "REDIS_7_2",
DisplayName = "Test Instance",
ReservedIpRange = "192.168.0.0/29",
Labels =
{
{ "my_key", "my_val" },
{ "other_key", "other_val" },
},
MaintenancePolicy = new Gcp.Redis.Inputs.InstanceMaintenancePolicyArgs
{
WeeklyMaintenanceWindows = new[]
{
new Gcp.Redis.Inputs.InstanceMaintenancePolicyWeeklyMaintenanceWindowArgs
{
Day = "TUESDAY",
StartTime = new Gcp.Redis.Inputs.InstanceMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs
{
Hours = 0,
Minutes = 30,
Seconds = 0,
Nanos = 0,
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.ComputeFunctions;
import com.pulumi.gcp.compute.inputs.GetNetworkArgs;
import com.pulumi.gcp.redis.Instance;
import com.pulumi.gcp.redis.InstanceArgs;
import com.pulumi.gcp.redis.inputs.InstanceMaintenancePolicyArgs;
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) {
// This example assumes this network already exists.
// The API creates a tenant network per network authorized for a
// Redis instance and that network is not deleted when the user-created
// network (authorized_network) is deleted, so this prevents issues
// with tenant network quota.
// If this network hasn't been created and you are using this example in your
// config, add an additional network resource or change
// this from "data"to "resource"
final var redis-network = ComputeFunctions.getNetwork(GetNetworkArgs.builder()
.name("redis-test-network")
.build());
var cache = new Instance("cache", InstanceArgs.builder()
.name("ha-memory-cache")
.tier("STANDARD_HA")
.memorySizeGb(1)
.locationId("us-central1-a")
.alternativeLocationId("us-central1-f")
.authorizedNetwork(redis_network.id())
.redisVersion("REDIS_7_2")
.displayName("Test Instance")
.reservedIpRange("192.168.0.0/29")
.labels(Map.ofEntries(
Map.entry("my_key", "my_val"),
Map.entry("other_key", "other_val")
))
.maintenancePolicy(InstanceMaintenancePolicyArgs.builder()
.weeklyMaintenanceWindows(InstanceMaintenancePolicyWeeklyMaintenanceWindowArgs.builder()
.day("TUESDAY")
.startTime(InstanceMaintenancePolicyWeeklyMaintenanceWindowStartTimeArgs.builder()
.hours(0)
.minutes(30)
.seconds(0)
.nanos(0)
.build())
.build())
.build())
.build());
}
}
resources:
cache:
type: gcp:redis:Instance
properties:
name: ha-memory-cache
tier: STANDARD_HA
memorySizeGb: 1
locationId: us-central1-a
alternativeLocationId: us-central1-f
authorizedNetwork: ${["redis-network"].id}
redisVersion: REDIS_7_2
displayName: Test Instance
reservedIpRange: 192.168.0.0/29
labels:
my_key: my_val
other_key: other_val
maintenancePolicy:
weeklyMaintenanceWindows:
- day: TUESDAY
startTime:
hours: 0
minutes: 30
seconds: 0
nanos: 0
variables:
# This example assumes this network already exists.
# // The API creates a tenant network per network authorized for a
# // Redis instance and that network is not deleted when the user-created
# // network (authorized_network) is deleted, so this prevents issues
# // with tenant network quota.
# // If this network hasn't been created and you are using this example in your
# // config, add an additional network resource or change
# // this from "data"to "resource"
redis-network:
fn::invoke:
function: gcp:compute:getNetwork
arguments:
name: redis-test-network
The tier property set to STANDARD_HA creates a primary-replica pair across two zones specified by locationId and alternativeLocationId. The authorizedNetwork property connects the instance to your VPC. The maintenancePolicy block schedules updates during low-traffic windows, controlling when patches are applied.
Enable RDB snapshots for data durability
Applications that cannot tolerate data loss on restart need persistence to write snapshots to disk at regular intervals.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const cache_persis = new gcp.redis.Instance("cache-persis", {
name: "ha-memory-cache-persis",
tier: "STANDARD_HA",
memorySizeGb: 1,
locationId: "us-central1-a",
alternativeLocationId: "us-central1-f",
persistenceConfig: {
persistenceMode: "RDB",
rdbSnapshotPeriod: "TWELVE_HOURS",
},
});
import pulumi
import pulumi_gcp as gcp
cache_persis = gcp.redis.Instance("cache-persis",
name="ha-memory-cache-persis",
tier="STANDARD_HA",
memory_size_gb=1,
location_id="us-central1-a",
alternative_location_id="us-central1-f",
persistence_config={
"persistence_mode": "RDB",
"rdb_snapshot_period": "TWELVE_HOURS",
})
package main
import (
"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 {
_, err := redis.NewInstance(ctx, "cache-persis", &redis.InstanceArgs{
Name: pulumi.String("ha-memory-cache-persis"),
Tier: pulumi.String("STANDARD_HA"),
MemorySizeGb: pulumi.Int(1),
LocationId: pulumi.String("us-central1-a"),
AlternativeLocationId: pulumi.String("us-central1-f"),
PersistenceConfig: &redis.InstancePersistenceConfigArgs{
PersistenceMode: pulumi.String("RDB"),
RdbSnapshotPeriod: pulumi.String("TWELVE_HOURS"),
},
})
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 cache_persis = new Gcp.Redis.Instance("cache-persis", new()
{
Name = "ha-memory-cache-persis",
Tier = "STANDARD_HA",
MemorySizeGb = 1,
LocationId = "us-central1-a",
AlternativeLocationId = "us-central1-f",
PersistenceConfig = new Gcp.Redis.Inputs.InstancePersistenceConfigArgs
{
PersistenceMode = "RDB",
RdbSnapshotPeriod = "TWELVE_HOURS",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.redis.Instance;
import com.pulumi.gcp.redis.InstanceArgs;
import com.pulumi.gcp.redis.inputs.InstancePersistenceConfigArgs;
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 cache_persis = new Instance("cache-persis", InstanceArgs.builder()
.name("ha-memory-cache-persis")
.tier("STANDARD_HA")
.memorySizeGb(1)
.locationId("us-central1-a")
.alternativeLocationId("us-central1-f")
.persistenceConfig(InstancePersistenceConfigArgs.builder()
.persistenceMode("RDB")
.rdbSnapshotPeriod("TWELVE_HOURS")
.build())
.build());
}
}
resources:
cache-persis:
type: gcp:redis:Instance
properties:
name: ha-memory-cache-persis
tier: STANDARD_HA
memorySizeGb: 1
locationId: us-central1-a
alternativeLocationId: us-central1-f
persistenceConfig:
persistenceMode: RDB
rdbSnapshotPeriod: TWELVE_HOURS
The persistenceConfig block enables RDB (Redis Database) snapshots. The persistenceMode property activates snapshot-based persistence, and rdbSnapshotPeriod controls how often Redis writes data to disk. Snapshots preserve data across instance restarts or failures.
Connect via Private Service Access for isolated networking
Some organizations require Redis instances reachable only through private IP addresses without exposing endpoints to the internet.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
// This example assumes this network already exists.
// The API creates a tenant network per network authorized for a
// Redis instance and that network is not deleted when the user-created
// network (authorized_network) is deleted, so this prevents issues
// with tenant network quota.
// If this network hasn't been created and you are using this example in your
// config, add an additional network resource or change
// this from "data"to "resource"
const redis_network = new gcp.compute.Network("redis-network", {name: "redis-test-network"});
const serviceRange = new gcp.compute.GlobalAddress("service_range", {
name: "address",
purpose: "VPC_PEERING",
addressType: "INTERNAL",
prefixLength: 16,
network: redis_network.id,
});
const privateServiceConnection = new gcp.servicenetworking.Connection("private_service_connection", {
network: redis_network.id,
service: "servicenetworking.googleapis.com",
reservedPeeringRanges: [serviceRange.name],
});
const cache = new gcp.redis.Instance("cache", {
name: "private-cache",
tier: "STANDARD_HA",
memorySizeGb: 1,
locationId: "us-central1-a",
alternativeLocationId: "us-central1-f",
authorizedNetwork: redis_network.id,
connectMode: "PRIVATE_SERVICE_ACCESS",
redisVersion: "REDIS_7_2",
displayName: "Test Instance",
}, {
dependsOn: [privateServiceConnection],
});
import pulumi
import pulumi_gcp as gcp
# This example assumes this network already exists.
# The API creates a tenant network per network authorized for a
# Redis instance and that network is not deleted when the user-created
# network (authorized_network) is deleted, so this prevents issues
# with tenant network quota.
# If this network hasn't been created and you are using this example in your
# config, add an additional network resource or change
# this from "data"to "resource"
redis_network = gcp.compute.Network("redis-network", name="redis-test-network")
service_range = gcp.compute.GlobalAddress("service_range",
name="address",
purpose="VPC_PEERING",
address_type="INTERNAL",
prefix_length=16,
network=redis_network.id)
private_service_connection = gcp.servicenetworking.Connection("private_service_connection",
network=redis_network.id,
service="servicenetworking.googleapis.com",
reserved_peering_ranges=[service_range.name])
cache = gcp.redis.Instance("cache",
name="private-cache",
tier="STANDARD_HA",
memory_size_gb=1,
location_id="us-central1-a",
alternative_location_id="us-central1-f",
authorized_network=redis_network.id,
connect_mode="PRIVATE_SERVICE_ACCESS",
redis_version="REDIS_7_2",
display_name="Test Instance",
opts = pulumi.ResourceOptions(depends_on=[private_service_connection]))
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/redis"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/servicenetworking"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
// This example assumes this network already exists.
// The API creates a tenant network per network authorized for a
// Redis instance and that network is not deleted when the user-created
// network (authorized_network) is deleted, so this prevents issues
// with tenant network quota.
// If this network hasn't been created and you are using this example in your
// config, add an additional network resource or change
// this from "data"to "resource"
redis_network, err := compute.NewNetwork(ctx, "redis-network", &compute.NetworkArgs{
Name: pulumi.String("redis-test-network"),
})
if err != nil {
return err
}
serviceRange, err := compute.NewGlobalAddress(ctx, "service_range", &compute.GlobalAddressArgs{
Name: pulumi.String("address"),
Purpose: pulumi.String("VPC_PEERING"),
AddressType: pulumi.String("INTERNAL"),
PrefixLength: pulumi.Int(16),
Network: redis_network.ID(),
})
if err != nil {
return err
}
privateServiceConnection, err := servicenetworking.NewConnection(ctx, "private_service_connection", &servicenetworking.ConnectionArgs{
Network: redis_network.ID(),
Service: pulumi.String("servicenetworking.googleapis.com"),
ReservedPeeringRanges: pulumi.StringArray{
serviceRange.Name,
},
})
if err != nil {
return err
}
_, err = redis.NewInstance(ctx, "cache", &redis.InstanceArgs{
Name: pulumi.String("private-cache"),
Tier: pulumi.String("STANDARD_HA"),
MemorySizeGb: pulumi.Int(1),
LocationId: pulumi.String("us-central1-a"),
AlternativeLocationId: pulumi.String("us-central1-f"),
AuthorizedNetwork: redis_network.ID(),
ConnectMode: pulumi.String("PRIVATE_SERVICE_ACCESS"),
RedisVersion: pulumi.String("REDIS_7_2"),
DisplayName: pulumi.String("Test Instance"),
}, pulumi.DependsOn([]pulumi.Resource{
privateServiceConnection,
}))
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
// This example assumes this network already exists.
// The API creates a tenant network per network authorized for a
// Redis instance and that network is not deleted when the user-created
// network (authorized_network) is deleted, so this prevents issues
// with tenant network quota.
// If this network hasn't been created and you are using this example in your
// config, add an additional network resource or change
// this from "data"to "resource"
var redis_network = new Gcp.Compute.Network("redis-network", new()
{
Name = "redis-test-network",
});
var serviceRange = new Gcp.Compute.GlobalAddress("service_range", new()
{
Name = "address",
Purpose = "VPC_PEERING",
AddressType = "INTERNAL",
PrefixLength = 16,
Network = redis_network.Id,
});
var privateServiceConnection = new Gcp.ServiceNetworking.Connection("private_service_connection", new()
{
Network = redis_network.Id,
Service = "servicenetworking.googleapis.com",
ReservedPeeringRanges = new[]
{
serviceRange.Name,
},
});
var cache = new Gcp.Redis.Instance("cache", new()
{
Name = "private-cache",
Tier = "STANDARD_HA",
MemorySizeGb = 1,
LocationId = "us-central1-a",
AlternativeLocationId = "us-central1-f",
AuthorizedNetwork = redis_network.Id,
ConnectMode = "PRIVATE_SERVICE_ACCESS",
RedisVersion = "REDIS_7_2",
DisplayName = "Test Instance",
}, new CustomResourceOptions
{
DependsOn =
{
privateServiceConnection,
},
});
});
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.GlobalAddress;
import com.pulumi.gcp.compute.GlobalAddressArgs;
import com.pulumi.gcp.servicenetworking.Connection;
import com.pulumi.gcp.servicenetworking.ConnectionArgs;
import com.pulumi.gcp.redis.Instance;
import com.pulumi.gcp.redis.InstanceArgs;
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) {
// This example assumes this network already exists.
// The API creates a tenant network per network authorized for a
// Redis instance and that network is not deleted when the user-created
// network (authorized_network) is deleted, so this prevents issues
// with tenant network quota.
// If this network hasn't been created and you are using this example in your
// config, add an additional network resource or change
// this from "data"to "resource"
var redis_network = new Network("redis-network", NetworkArgs.builder()
.name("redis-test-network")
.build());
var serviceRange = new GlobalAddress("serviceRange", GlobalAddressArgs.builder()
.name("address")
.purpose("VPC_PEERING")
.addressType("INTERNAL")
.prefixLength(16)
.network(redis_network.id())
.build());
var privateServiceConnection = new Connection("privateServiceConnection", ConnectionArgs.builder()
.network(redis_network.id())
.service("servicenetworking.googleapis.com")
.reservedPeeringRanges(serviceRange.name())
.build());
var cache = new Instance("cache", InstanceArgs.builder()
.name("private-cache")
.tier("STANDARD_HA")
.memorySizeGb(1)
.locationId("us-central1-a")
.alternativeLocationId("us-central1-f")
.authorizedNetwork(redis_network.id())
.connectMode("PRIVATE_SERVICE_ACCESS")
.redisVersion("REDIS_7_2")
.displayName("Test Instance")
.build(), CustomResourceOptions.builder()
.dependsOn(privateServiceConnection)
.build());
}
}
resources:
# This example assumes this network already exists.
# // The API creates a tenant network per network authorized for a
# // Redis instance and that network is not deleted when the user-created
# // network (authorized_network) is deleted, so this prevents issues
# // with tenant network quota.
# // If this network hasn't been created and you are using this example in your
# // config, add an additional network resource or change
# // this from "data"to "resource"
redis-network:
type: gcp:compute:Network
properties:
name: redis-test-network
serviceRange:
type: gcp:compute:GlobalAddress
name: service_range
properties:
name: address
purpose: VPC_PEERING
addressType: INTERNAL
prefixLength: 16
network: ${["redis-network"].id}
privateServiceConnection:
type: gcp:servicenetworking:Connection
name: private_service_connection
properties:
network: ${["redis-network"].id}
service: servicenetworking.googleapis.com
reservedPeeringRanges:
- ${serviceRange.name}
cache:
type: gcp:redis:Instance
properties:
name: private-cache
tier: STANDARD_HA
memorySizeGb: 1
locationId: us-central1-a
alternativeLocationId: us-central1-f
authorizedNetwork: ${["redis-network"].id}
connectMode: PRIVATE_SERVICE_ACCESS
redisVersion: REDIS_7_2
displayName: Test Instance
options:
dependsOn:
- ${privateServiceConnection}
The connectMode property set to PRIVATE_SERVICE_ACCESS routes traffic through VPC peering instead of direct peering. This requires a GlobalAddress to allocate an IP range and a servicenetworking.Connection to establish peering with Google’s service producer network. The dependsOn ensures peering completes before creating the instance.
Scale read capacity with multiple read replicas
Read-heavy workloads benefit from distributing queries across multiple replica nodes while maintaining a single primary for writes.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
// This example assumes this network already exists.
// The API creates a tenant network per network authorized for a
// Redis instance and that network is not deleted when the user-created
// network (authorized_network) is deleted, so this prevents issues
// with tenant network quota.
// If this network hasn't been created and you are using this example in your
// config, add an additional network resource or change
// this from "data"to "resource"
const redis_network = gcp.compute.getNetwork({
name: "redis-test-network",
});
const cache = new gcp.redis.Instance("cache", {
name: "mrr-memory-cache",
tier: "STANDARD_HA",
memorySizeGb: 5,
locationId: "us-central1-a",
alternativeLocationId: "us-central1-f",
authorizedNetwork: redis_network.then(redis_network => redis_network.id),
redisVersion: "REDIS_7_2",
displayName: "Terraform Test Instance",
replicaCount: 5,
readReplicasMode: "READ_REPLICAS_ENABLED",
labels: {
my_key: "my_val",
other_key: "other_val",
},
});
import pulumi
import pulumi_gcp as gcp
# This example assumes this network already exists.
# The API creates a tenant network per network authorized for a
# Redis instance and that network is not deleted when the user-created
# network (authorized_network) is deleted, so this prevents issues
# with tenant network quota.
# If this network hasn't been created and you are using this example in your
# config, add an additional network resource or change
# this from "data"to "resource"
redis_network = gcp.compute.get_network(name="redis-test-network")
cache = gcp.redis.Instance("cache",
name="mrr-memory-cache",
tier="STANDARD_HA",
memory_size_gb=5,
location_id="us-central1-a",
alternative_location_id="us-central1-f",
authorized_network=redis_network.id,
redis_version="REDIS_7_2",
display_name="Terraform Test Instance",
replica_count=5,
read_replicas_mode="READ_REPLICAS_ENABLED",
labels={
"my_key": "my_val",
"other_key": "other_val",
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"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 {
// This example assumes this network already exists.
// The API creates a tenant network per network authorized for a
// Redis instance and that network is not deleted when the user-created
// network (authorized_network) is deleted, so this prevents issues
// with tenant network quota.
// If this network hasn't been created and you are using this example in your
// config, add an additional network resource or change
// this from "data"to "resource"
redis_network, err := compute.LookupNetwork(ctx, &compute.LookupNetworkArgs{
Name: "redis-test-network",
}, nil)
if err != nil {
return err
}
_, err = redis.NewInstance(ctx, "cache", &redis.InstanceArgs{
Name: pulumi.String("mrr-memory-cache"),
Tier: pulumi.String("STANDARD_HA"),
MemorySizeGb: pulumi.Int(5),
LocationId: pulumi.String("us-central1-a"),
AlternativeLocationId: pulumi.String("us-central1-f"),
AuthorizedNetwork: pulumi.String(redis_network.Id),
RedisVersion: pulumi.String("REDIS_7_2"),
DisplayName: pulumi.String("Terraform Test Instance"),
ReplicaCount: pulumi.Int(5),
ReadReplicasMode: pulumi.String("READ_REPLICAS_ENABLED"),
Labels: pulumi.StringMap{
"my_key": pulumi.String("my_val"),
"other_key": pulumi.String("other_val"),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
// This example assumes this network already exists.
// The API creates a tenant network per network authorized for a
// Redis instance and that network is not deleted when the user-created
// network (authorized_network) is deleted, so this prevents issues
// with tenant network quota.
// If this network hasn't been created and you are using this example in your
// config, add an additional network resource or change
// this from "data"to "resource"
var redis_network = Gcp.Compute.GetNetwork.Invoke(new()
{
Name = "redis-test-network",
});
var cache = new Gcp.Redis.Instance("cache", new()
{
Name = "mrr-memory-cache",
Tier = "STANDARD_HA",
MemorySizeGb = 5,
LocationId = "us-central1-a",
AlternativeLocationId = "us-central1-f",
AuthorizedNetwork = redis_network.Apply(redis_network => redis_network.Apply(getNetworkResult => getNetworkResult.Id)),
RedisVersion = "REDIS_7_2",
DisplayName = "Terraform Test Instance",
ReplicaCount = 5,
ReadReplicasMode = "READ_REPLICAS_ENABLED",
Labels =
{
{ "my_key", "my_val" },
{ "other_key", "other_val" },
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.ComputeFunctions;
import com.pulumi.gcp.compute.inputs.GetNetworkArgs;
import com.pulumi.gcp.redis.Instance;
import com.pulumi.gcp.redis.InstanceArgs;
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) {
// This example assumes this network already exists.
// The API creates a tenant network per network authorized for a
// Redis instance and that network is not deleted when the user-created
// network (authorized_network) is deleted, so this prevents issues
// with tenant network quota.
// If this network hasn't been created and you are using this example in your
// config, add an additional network resource or change
// this from "data"to "resource"
final var redis-network = ComputeFunctions.getNetwork(GetNetworkArgs.builder()
.name("redis-test-network")
.build());
var cache = new Instance("cache", InstanceArgs.builder()
.name("mrr-memory-cache")
.tier("STANDARD_HA")
.memorySizeGb(5)
.locationId("us-central1-a")
.alternativeLocationId("us-central1-f")
.authorizedNetwork(redis_network.id())
.redisVersion("REDIS_7_2")
.displayName("Terraform Test Instance")
.replicaCount(5)
.readReplicasMode("READ_REPLICAS_ENABLED")
.labels(Map.ofEntries(
Map.entry("my_key", "my_val"),
Map.entry("other_key", "other_val")
))
.build());
}
}
resources:
cache:
type: gcp:redis:Instance
properties:
name: mrr-memory-cache
tier: STANDARD_HA
memorySizeGb: 5
locationId: us-central1-a
alternativeLocationId: us-central1-f
authorizedNetwork: ${["redis-network"].id}
redisVersion: REDIS_7_2
displayName: Terraform Test Instance
replicaCount: 5
readReplicasMode: READ_REPLICAS_ENABLED
labels:
my_key: my_val
other_key: other_val
variables:
# This example assumes this network already exists.
# // The API creates a tenant network per network authorized for a
# // Redis instance and that network is not deleted when the user-created
# // network (authorized_network) is deleted, so this prevents issues
# // with tenant network quota.
# // If this network hasn't been created and you are using this example in your
# // config, add an additional network resource or change
# // this from "data"to "resource"
redis-network:
fn::invoke:
function: gcp:compute:getNetwork
arguments:
name: redis-test-network
The replicaCount property adds replica nodes (valid range 1-5 for STANDARD_HA). The readReplicasMode property set to READ_REPLICAS_ENABLED exposes a read endpoint that distributes queries across replicas. Write requests still target the primary instance.
Encrypt data at rest with customer-managed keys
Compliance requirements often mandate encryption with keys you control rather than Google-managed keys.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const redisKeyring = new gcp.kms.KeyRing("redis_keyring", {
name: "redis-keyring",
location: "us-central1",
});
const redisKey = new gcp.kms.CryptoKey("redis_key", {
name: "redis-key",
keyRing: redisKeyring.id,
});
// This example assumes this network already exists.
// The API creates a tenant network per network authorized for a
// Redis instance and that network is not deleted when the user-created
// network (authorized_network) is deleted, so this prevents issues
// with tenant network quota.
// If this network hasn't been created and you are using this example in your
// config, add an additional network resource or change
// this from "data"to "resource"
const redis_network = gcp.compute.getNetwork({
name: "redis-test-network",
});
const cache = new gcp.redis.Instance("cache", {
name: "cmek-memory-cache",
tier: "STANDARD_HA",
memorySizeGb: 1,
locationId: "us-central1-a",
alternativeLocationId: "us-central1-f",
authorizedNetwork: redis_network.then(redis_network => redis_network.id),
redisVersion: "REDIS_7_2",
displayName: "Terraform Test Instance",
labels: {
my_key: "my_val",
other_key: "other_val",
},
customerManagedKey: redisKey.id,
});
import pulumi
import pulumi_gcp as gcp
redis_keyring = gcp.kms.KeyRing("redis_keyring",
name="redis-keyring",
location="us-central1")
redis_key = gcp.kms.CryptoKey("redis_key",
name="redis-key",
key_ring=redis_keyring.id)
# This example assumes this network already exists.
# The API creates a tenant network per network authorized for a
# Redis instance and that network is not deleted when the user-created
# network (authorized_network) is deleted, so this prevents issues
# with tenant network quota.
# If this network hasn't been created and you are using this example in your
# config, add an additional network resource or change
# this from "data"to "resource"
redis_network = gcp.compute.get_network(name="redis-test-network")
cache = gcp.redis.Instance("cache",
name="cmek-memory-cache",
tier="STANDARD_HA",
memory_size_gb=1,
location_id="us-central1-a",
alternative_location_id="us-central1-f",
authorized_network=redis_network.id,
redis_version="REDIS_7_2",
display_name="Terraform Test Instance",
labels={
"my_key": "my_val",
"other_key": "other_val",
},
customer_managed_key=redis_key.id)
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/kms"
"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 {
redisKeyring, err := kms.NewKeyRing(ctx, "redis_keyring", &kms.KeyRingArgs{
Name: pulumi.String("redis-keyring"),
Location: pulumi.String("us-central1"),
})
if err != nil {
return err
}
redisKey, err := kms.NewCryptoKey(ctx, "redis_key", &kms.CryptoKeyArgs{
Name: pulumi.String("redis-key"),
KeyRing: redisKeyring.ID(),
})
if err != nil {
return err
}
// This example assumes this network already exists.
// The API creates a tenant network per network authorized for a
// Redis instance and that network is not deleted when the user-created
// network (authorized_network) is deleted, so this prevents issues
// with tenant network quota.
// If this network hasn't been created and you are using this example in your
// config, add an additional network resource or change
// this from "data"to "resource"
redis_network, err := compute.LookupNetwork(ctx, &compute.LookupNetworkArgs{
Name: "redis-test-network",
}, nil)
if err != nil {
return err
}
_, err = redis.NewInstance(ctx, "cache", &redis.InstanceArgs{
Name: pulumi.String("cmek-memory-cache"),
Tier: pulumi.String("STANDARD_HA"),
MemorySizeGb: pulumi.Int(1),
LocationId: pulumi.String("us-central1-a"),
AlternativeLocationId: pulumi.String("us-central1-f"),
AuthorizedNetwork: pulumi.String(redis_network.Id),
RedisVersion: pulumi.String("REDIS_7_2"),
DisplayName: pulumi.String("Terraform Test Instance"),
Labels: pulumi.StringMap{
"my_key": pulumi.String("my_val"),
"other_key": pulumi.String("other_val"),
},
CustomerManagedKey: redisKey.ID(),
})
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 redisKeyring = new Gcp.Kms.KeyRing("redis_keyring", new()
{
Name = "redis-keyring",
Location = "us-central1",
});
var redisKey = new Gcp.Kms.CryptoKey("redis_key", new()
{
Name = "redis-key",
KeyRing = redisKeyring.Id,
});
// This example assumes this network already exists.
// The API creates a tenant network per network authorized for a
// Redis instance and that network is not deleted when the user-created
// network (authorized_network) is deleted, so this prevents issues
// with tenant network quota.
// If this network hasn't been created and you are using this example in your
// config, add an additional network resource or change
// this from "data"to "resource"
var redis_network = Gcp.Compute.GetNetwork.Invoke(new()
{
Name = "redis-test-network",
});
var cache = new Gcp.Redis.Instance("cache", new()
{
Name = "cmek-memory-cache",
Tier = "STANDARD_HA",
MemorySizeGb = 1,
LocationId = "us-central1-a",
AlternativeLocationId = "us-central1-f",
AuthorizedNetwork = redis_network.Apply(redis_network => redis_network.Apply(getNetworkResult => getNetworkResult.Id)),
RedisVersion = "REDIS_7_2",
DisplayName = "Terraform Test Instance",
Labels =
{
{ "my_key", "my_val" },
{ "other_key", "other_val" },
},
CustomerManagedKey = redisKey.Id,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.kms.KeyRing;
import com.pulumi.gcp.kms.KeyRingArgs;
import com.pulumi.gcp.kms.CryptoKey;
import com.pulumi.gcp.kms.CryptoKeyArgs;
import com.pulumi.gcp.compute.ComputeFunctions;
import com.pulumi.gcp.compute.inputs.GetNetworkArgs;
import com.pulumi.gcp.redis.Instance;
import com.pulumi.gcp.redis.InstanceArgs;
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 redisKeyring = new KeyRing("redisKeyring", KeyRingArgs.builder()
.name("redis-keyring")
.location("us-central1")
.build());
var redisKey = new CryptoKey("redisKey", CryptoKeyArgs.builder()
.name("redis-key")
.keyRing(redisKeyring.id())
.build());
// This example assumes this network already exists.
// The API creates a tenant network per network authorized for a
// Redis instance and that network is not deleted when the user-created
// network (authorized_network) is deleted, so this prevents issues
// with tenant network quota.
// If this network hasn't been created and you are using this example in your
// config, add an additional network resource or change
// this from "data"to "resource"
final var redis-network = ComputeFunctions.getNetwork(GetNetworkArgs.builder()
.name("redis-test-network")
.build());
var cache = new Instance("cache", InstanceArgs.builder()
.name("cmek-memory-cache")
.tier("STANDARD_HA")
.memorySizeGb(1)
.locationId("us-central1-a")
.alternativeLocationId("us-central1-f")
.authorizedNetwork(redis_network.id())
.redisVersion("REDIS_7_2")
.displayName("Terraform Test Instance")
.labels(Map.ofEntries(
Map.entry("my_key", "my_val"),
Map.entry("other_key", "other_val")
))
.customerManagedKey(redisKey.id())
.build());
}
}
resources:
cache:
type: gcp:redis:Instance
properties:
name: cmek-memory-cache
tier: STANDARD_HA
memorySizeGb: 1
locationId: us-central1-a
alternativeLocationId: us-central1-f
authorizedNetwork: ${["redis-network"].id}
redisVersion: REDIS_7_2
displayName: Terraform Test Instance
labels:
my_key: my_val
other_key: other_val
customerManagedKey: ${redisKey.id}
redisKeyring:
type: gcp:kms:KeyRing
name: redis_keyring
properties:
name: redis-keyring
location: us-central1
redisKey:
type: gcp:kms:CryptoKey
name: redis_key
properties:
name: redis-key
keyRing: ${redisKeyring.id}
variables:
# This example assumes this network already exists.
# // The API creates a tenant network per network authorized for a
# // Redis instance and that network is not deleted when the user-created
# // network (authorized_network) is deleted, so this prevents issues
# // with tenant network quota.
# // If this network hasn't been created and you are using this example in your
# // config, add an additional network resource or change
# // this from "data"to "resource"
redis-network:
fn::invoke:
function: gcp:compute:getNetwork
arguments:
name: redis-test-network
The customerManagedKey property references a KMS CryptoKey for encryption. You create a KeyRing and CryptoKey first, then pass the key ID to the instance. This enables CMEK (Customer-Managed Encryption Keys), giving you control over key rotation and access policies.
Beyond these examples
These snippets focus on specific Redis instance features: tier selection and high availability, persistence and encryption, and read replicas and private networking. They’re intentionally minimal rather than full caching solutions.
The examples may reference pre-existing infrastructure such as VPC networks (authorizedNetwork references), KMS key rings and crypto keys (for CMEK), and VPC peering setup (for Private Service Access). They focus on configuring the instance rather than provisioning everything around it.
To keep things focused, common Redis patterns are omitted, including:
- Redis configuration parameters (redisConfigs)
- Authentication enablement (authEnabled)
- Transit encryption (transitEncryptionMode)
- IP range reservation (reservedIpRange, secondaryIpRange)
These omissions are intentional: the goal is to illustrate how each Redis feature is wired, not provide drop-in caching modules. See the Redis Instance resource reference for all available configuration options.
Let's create Google Cloud Memorystore Redis Instances
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
High Availability & Replication
alternativeLocationId (a different zone from locationId) and supports read replicas. The tier property defaults to BASIC and is immutable after creation.readReplicasMode to READ_REPLICAS_ENABLED and configure replicaCount (1-5 for STANDARD_HA tier). This provides a readEndpoint output and allows scaling the number of replicas. If readReplicasMode is not set, it defaults to READ_REPLICAS_DISABLED.secondaryIpRange. For DIRECT_PEERING mode, use a /28 CIDR or “auto”. For PRIVATE_SERVICE_ACCESS mode, use an allocated address range name or “auto”.Networking & Connectivity
authorizedNetwork) is deleted, which can cause quota issues. The examples recommend reusing existing networks via data sources rather than creating new ones.gcp.compute.GlobalAddress with purpose: "VPC_PEERING", then create a gcp.servicenetworking.Connection. Set connectMode: "PRIVATE_SERVICE_ACCESS" on your Redis instance and use dependsOn to ensure the connection exists before instance creation.DIRECT_PEERING (default) connects directly to the VPC network. PRIVATE_SERVICE_ACCESS uses a private service connection for connectivity. The connectMode property is immutable after creation.Security & Encryption
authEnabled defaults to false, meaning AUTH is disabled. Set authEnabled: true to enable OSS Redis AUTH. The authString output is only populated when AUTH is enabled.transitEncryptionMode defaults to DISABLED. Set it to SERVER_AUTHENTICATION to enable client-to-server traffic encryption with server authentication. This property is immutable after creation.gcp.kms.CryptoKey and set customerManagedKey to the key’s ID. This enables CMEK encryption for data at rest. The customerManagedKey property is immutable after creation.Configuration & Limitations
tier, connectMode, locationId, alternativeLocationId, authorizedNetwork, reservedIpRange, customerManagedKey, transitEncryptionMode, name, project, and region. Changes to these properties require recreating the instance.persistenceConfig with persistenceMode (e.g., "RDB") and rdbSnapshotPeriod (e.g., "TWELVE_HOURS"). The persistenceIamIdentity output provides the Cloud IAM identity used for import/export operations to Cloud Storage.