The azure-native:redisenterprise:Database resource, part of the Pulumi Azure Native provider, defines a database within a Redis Enterprise cluster: its clustering policy, modules, persistence settings, and optional geo-replication. This guide focuses on three capabilities: Redis module configuration, clustering and eviction policies, and active geo-replication across regions.
Databases belong to Redis Enterprise clusters and reference Azure resource groups. Geo-replication requires existing databases in other regions. The examples are intentionally small. Combine them with your own cluster infrastructure and networking configuration.
Configure a database with modules and persistence
Teams building applications that need specialized Redis capabilities often enable modules like RedisBloom, RedisTimeSeries, or RediSearch for probabilistic data structures, time-series storage, and full-text search.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const database = new azure_native.redisenterprise.Database("database", {
accessKeysAuthentication: azure_native.redisenterprise.AccessKeysAuthentication.Enabled,
clientProtocol: azure_native.redisenterprise.Protocol.Encrypted,
clusterName: "cache1",
clusteringPolicy: azure_native.redisenterprise.ClusteringPolicy.EnterpriseCluster,
databaseName: "default",
deferUpgrade: azure_native.redisenterprise.DeferUpgradeSetting.NotDeferred,
evictionPolicy: azure_native.redisenterprise.EvictionPolicy.AllKeysLRU,
modules: [
{
args: "ERROR_RATE 0.00 INITIAL_SIZE 400",
name: "RedisBloom",
},
{
args: "RETENTION_POLICY 20",
name: "RedisTimeSeries",
},
{
name: "RediSearch",
},
],
persistence: {
aofEnabled: true,
aofFrequency: azure_native.redisenterprise.AofFrequency.AofFrequency_1s,
},
port: 10000,
resourceGroupName: "rg1",
});
import pulumi
import pulumi_azure_native as azure_native
database = azure_native.redisenterprise.Database("database",
access_keys_authentication=azure_native.redisenterprise.AccessKeysAuthentication.ENABLED,
client_protocol=azure_native.redisenterprise.Protocol.ENCRYPTED,
cluster_name="cache1",
clustering_policy=azure_native.redisenterprise.ClusteringPolicy.ENTERPRISE_CLUSTER,
database_name="default",
defer_upgrade=azure_native.redisenterprise.DeferUpgradeSetting.NOT_DEFERRED,
eviction_policy=azure_native.redisenterprise.EvictionPolicy.ALL_KEYS_LRU,
modules=[
{
"args": "ERROR_RATE 0.00 INITIAL_SIZE 400",
"name": "RedisBloom",
},
{
"args": "RETENTION_POLICY 20",
"name": "RedisTimeSeries",
},
{
"name": "RediSearch",
},
],
persistence={
"aof_enabled": True,
"aof_frequency": azure_native.redisenterprise.AofFrequency.AOF_FREQUENCY_1S,
},
port=10000,
resource_group_name="rg1")
package main
import (
redisenterprise "github.com/pulumi/pulumi-azure-native-sdk/redisenterprise/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := redisenterprise.NewDatabase(ctx, "database", &redisenterprise.DatabaseArgs{
AccessKeysAuthentication: pulumi.String(redisenterprise.AccessKeysAuthenticationEnabled),
ClientProtocol: pulumi.String(redisenterprise.ProtocolEncrypted),
ClusterName: pulumi.String("cache1"),
ClusteringPolicy: pulumi.String(redisenterprise.ClusteringPolicyEnterpriseCluster),
DatabaseName: pulumi.String("default"),
DeferUpgrade: pulumi.String(redisenterprise.DeferUpgradeSettingNotDeferred),
EvictionPolicy: pulumi.String(redisenterprise.EvictionPolicyAllKeysLRU),
Modules: redisenterprise.ModuleArray{
&redisenterprise.ModuleArgs{
Args: pulumi.String("ERROR_RATE 0.00 INITIAL_SIZE 400"),
Name: pulumi.String("RedisBloom"),
},
&redisenterprise.ModuleArgs{
Args: pulumi.String("RETENTION_POLICY 20"),
Name: pulumi.String("RedisTimeSeries"),
},
&redisenterprise.ModuleArgs{
Name: pulumi.String("RediSearch"),
},
},
Persistence: &redisenterprise.PersistenceArgs{
AofEnabled: pulumi.Bool(true),
AofFrequency: pulumi.String(redisenterprise.AofFrequency_1s),
},
Port: pulumi.Int(10000),
ResourceGroupName: pulumi.String("rg1"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var database = new AzureNative.RedisEnterprise.Database("database", new()
{
AccessKeysAuthentication = AzureNative.RedisEnterprise.AccessKeysAuthentication.Enabled,
ClientProtocol = AzureNative.RedisEnterprise.Protocol.Encrypted,
ClusterName = "cache1",
ClusteringPolicy = AzureNative.RedisEnterprise.ClusteringPolicy.EnterpriseCluster,
DatabaseName = "default",
DeferUpgrade = AzureNative.RedisEnterprise.DeferUpgradeSetting.NotDeferred,
EvictionPolicy = AzureNative.RedisEnterprise.EvictionPolicy.AllKeysLRU,
Modules = new[]
{
new AzureNative.RedisEnterprise.Inputs.ModuleArgs
{
Args = "ERROR_RATE 0.00 INITIAL_SIZE 400",
Name = "RedisBloom",
},
new AzureNative.RedisEnterprise.Inputs.ModuleArgs
{
Args = "RETENTION_POLICY 20",
Name = "RedisTimeSeries",
},
new AzureNative.RedisEnterprise.Inputs.ModuleArgs
{
Name = "RediSearch",
},
},
Persistence = new AzureNative.RedisEnterprise.Inputs.PersistenceArgs
{
AofEnabled = true,
AofFrequency = AzureNative.RedisEnterprise.AofFrequency.AofFrequency_1s,
},
Port = 10000,
ResourceGroupName = "rg1",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.redisenterprise.Database;
import com.pulumi.azurenative.redisenterprise.DatabaseArgs;
import com.pulumi.azurenative.redisenterprise.inputs.ModuleArgs;
import com.pulumi.azurenative.redisenterprise.inputs.PersistenceArgs;
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 database = new Database("database", DatabaseArgs.builder()
.accessKeysAuthentication("Enabled")
.clientProtocol("Encrypted")
.clusterName("cache1")
.clusteringPolicy("EnterpriseCluster")
.databaseName("default")
.deferUpgrade("NotDeferred")
.evictionPolicy("AllKeysLRU")
.modules(
ModuleArgs.builder()
.args("ERROR_RATE 0.00 INITIAL_SIZE 400")
.name("RedisBloom")
.build(),
ModuleArgs.builder()
.args("RETENTION_POLICY 20")
.name("RedisTimeSeries")
.build(),
ModuleArgs.builder()
.name("RediSearch")
.build())
.persistence(PersistenceArgs.builder()
.aofEnabled(true)
.aofFrequency("1s")
.build())
.port(10000)
.resourceGroupName("rg1")
.build());
}
}
resources:
database:
type: azure-native:redisenterprise:Database
properties:
accessKeysAuthentication: Enabled
clientProtocol: Encrypted
clusterName: cache1
clusteringPolicy: EnterpriseCluster
databaseName: default
deferUpgrade: NotDeferred
evictionPolicy: AllKeysLRU
modules:
- args: ERROR_RATE 0.00 INITIAL_SIZE 400
name: RedisBloom
- args: RETENTION_POLICY 20
name: RedisTimeSeries
- name: RediSearch
persistence:
aofEnabled: true
aofFrequency: 1s
port: 10000
resourceGroupName: rg1
The modules array enables Redis extensions at creation time. Each module accepts initialization arguments (e.g., “ERROR_RATE 0.00 INITIAL_SIZE 400” for RedisBloom). The persistence block configures append-only file (AOF) durability: aofEnabled turns on persistence, and aofFrequency controls how often Redis writes to disk (1s means every second). The clusteringPolicy determines whether data is sharded across nodes (EnterpriseCluster) or kept on a single shard.
Create a single-shard database without clustering
Applications with smaller datasets or simpler access patterns can use a single-shard configuration that avoids cluster mode overhead.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const database = new azure_native.redisenterprise.Database("database", {
clientProtocol: azure_native.redisenterprise.Protocol.Encrypted,
clusterName: "cache1",
clusteringPolicy: azure_native.redisenterprise.ClusteringPolicy.NoCluster,
databaseName: "default",
evictionPolicy: azure_native.redisenterprise.EvictionPolicy.NoEviction,
port: 10000,
resourceGroupName: "rg1",
});
import pulumi
import pulumi_azure_native as azure_native
database = azure_native.redisenterprise.Database("database",
client_protocol=azure_native.redisenterprise.Protocol.ENCRYPTED,
cluster_name="cache1",
clustering_policy=azure_native.redisenterprise.ClusteringPolicy.NO_CLUSTER,
database_name="default",
eviction_policy=azure_native.redisenterprise.EvictionPolicy.NO_EVICTION,
port=10000,
resource_group_name="rg1")
package main
import (
redisenterprise "github.com/pulumi/pulumi-azure-native-sdk/redisenterprise/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := redisenterprise.NewDatabase(ctx, "database", &redisenterprise.DatabaseArgs{
ClientProtocol: pulumi.String(redisenterprise.ProtocolEncrypted),
ClusterName: pulumi.String("cache1"),
ClusteringPolicy: pulumi.String(redisenterprise.ClusteringPolicyNoCluster),
DatabaseName: pulumi.String("default"),
EvictionPolicy: pulumi.String(redisenterprise.EvictionPolicyNoEviction),
Port: pulumi.Int(10000),
ResourceGroupName: pulumi.String("rg1"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var database = new AzureNative.RedisEnterprise.Database("database", new()
{
ClientProtocol = AzureNative.RedisEnterprise.Protocol.Encrypted,
ClusterName = "cache1",
ClusteringPolicy = AzureNative.RedisEnterprise.ClusteringPolicy.NoCluster,
DatabaseName = "default",
EvictionPolicy = AzureNative.RedisEnterprise.EvictionPolicy.NoEviction,
Port = 10000,
ResourceGroupName = "rg1",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.redisenterprise.Database;
import com.pulumi.azurenative.redisenterprise.DatabaseArgs;
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 database = new Database("database", DatabaseArgs.builder()
.clientProtocol("Encrypted")
.clusterName("cache1")
.clusteringPolicy("NoCluster")
.databaseName("default")
.evictionPolicy("NoEviction")
.port(10000)
.resourceGroupName("rg1")
.build());
}
}
resources:
database:
type: azure-native:redisenterprise:Database
properties:
clientProtocol: Encrypted
clusterName: cache1
clusteringPolicy: NoCluster
databaseName: default
evictionPolicy: NoEviction
port: 10000
resourceGroupName: rg1
Setting clusteringPolicy to NoCluster keeps all data on one shard, simplifying client connections and eliminating cross-shard operations. The evictionPolicy of NoEviction prevents Redis from removing keys when memory fills, causing writes to fail instead. This configuration suits caching scenarios where you control data size or need predictable memory behavior.
Link databases across regions for geo-replication
Applications serving global users often replicate data across regions to reduce latency and provide disaster recovery.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const database = new azure_native.redisenterprise.Database("database", {
accessKeysAuthentication: azure_native.redisenterprise.AccessKeysAuthentication.Enabled,
clientProtocol: azure_native.redisenterprise.Protocol.Encrypted,
clusterName: "cache1",
clusteringPolicy: azure_native.redisenterprise.ClusteringPolicy.EnterpriseCluster,
databaseName: "default",
evictionPolicy: azure_native.redisenterprise.EvictionPolicy.NoEviction,
geoReplication: {
groupNickname: "groupName",
linkedDatabases: [
{
id: "/subscriptions/e7b5a9d2-6b6a-4d2f-9143-20d9a10f5b8f/resourceGroups/rg1/providers/Microsoft.Cache/redisEnterprise/cache1/databases/default",
},
{
id: "/subscriptions/e7b5a9d2-6b6a-4d2f-9143-20d9a10f5b8e/resourceGroups/rg2/providers/Microsoft.Cache/redisEnterprise/cache2/databases/default",
},
],
},
port: 10000,
resourceGroupName: "rg1",
});
import pulumi
import pulumi_azure_native as azure_native
database = azure_native.redisenterprise.Database("database",
access_keys_authentication=azure_native.redisenterprise.AccessKeysAuthentication.ENABLED,
client_protocol=azure_native.redisenterprise.Protocol.ENCRYPTED,
cluster_name="cache1",
clustering_policy=azure_native.redisenterprise.ClusteringPolicy.ENTERPRISE_CLUSTER,
database_name="default",
eviction_policy=azure_native.redisenterprise.EvictionPolicy.NO_EVICTION,
geo_replication={
"group_nickname": "groupName",
"linked_databases": [
{
"id": "/subscriptions/e7b5a9d2-6b6a-4d2f-9143-20d9a10f5b8f/resourceGroups/rg1/providers/Microsoft.Cache/redisEnterprise/cache1/databases/default",
},
{
"id": "/subscriptions/e7b5a9d2-6b6a-4d2f-9143-20d9a10f5b8e/resourceGroups/rg2/providers/Microsoft.Cache/redisEnterprise/cache2/databases/default",
},
],
},
port=10000,
resource_group_name="rg1")
package main
import (
redisenterprise "github.com/pulumi/pulumi-azure-native-sdk/redisenterprise/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := redisenterprise.NewDatabase(ctx, "database", &redisenterprise.DatabaseArgs{
AccessKeysAuthentication: pulumi.String(redisenterprise.AccessKeysAuthenticationEnabled),
ClientProtocol: pulumi.String(redisenterprise.ProtocolEncrypted),
ClusterName: pulumi.String("cache1"),
ClusteringPolicy: pulumi.String(redisenterprise.ClusteringPolicyEnterpriseCluster),
DatabaseName: pulumi.String("default"),
EvictionPolicy: pulumi.String(redisenterprise.EvictionPolicyNoEviction),
GeoReplication: &redisenterprise.DatabasePropertiesGeoReplicationArgs{
GroupNickname: pulumi.String("groupName"),
LinkedDatabases: redisenterprise.LinkedDatabaseArray{
&redisenterprise.LinkedDatabaseArgs{
Id: pulumi.String("/subscriptions/e7b5a9d2-6b6a-4d2f-9143-20d9a10f5b8f/resourceGroups/rg1/providers/Microsoft.Cache/redisEnterprise/cache1/databases/default"),
},
&redisenterprise.LinkedDatabaseArgs{
Id: pulumi.String("/subscriptions/e7b5a9d2-6b6a-4d2f-9143-20d9a10f5b8e/resourceGroups/rg2/providers/Microsoft.Cache/redisEnterprise/cache2/databases/default"),
},
},
},
Port: pulumi.Int(10000),
ResourceGroupName: pulumi.String("rg1"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var database = new AzureNative.RedisEnterprise.Database("database", new()
{
AccessKeysAuthentication = AzureNative.RedisEnterprise.AccessKeysAuthentication.Enabled,
ClientProtocol = AzureNative.RedisEnterprise.Protocol.Encrypted,
ClusterName = "cache1",
ClusteringPolicy = AzureNative.RedisEnterprise.ClusteringPolicy.EnterpriseCluster,
DatabaseName = "default",
EvictionPolicy = AzureNative.RedisEnterprise.EvictionPolicy.NoEviction,
GeoReplication = new AzureNative.RedisEnterprise.Inputs.DatabasePropertiesGeoReplicationArgs
{
GroupNickname = "groupName",
LinkedDatabases = new[]
{
new AzureNative.RedisEnterprise.Inputs.LinkedDatabaseArgs
{
Id = "/subscriptions/e7b5a9d2-6b6a-4d2f-9143-20d9a10f5b8f/resourceGroups/rg1/providers/Microsoft.Cache/redisEnterprise/cache1/databases/default",
},
new AzureNative.RedisEnterprise.Inputs.LinkedDatabaseArgs
{
Id = "/subscriptions/e7b5a9d2-6b6a-4d2f-9143-20d9a10f5b8e/resourceGroups/rg2/providers/Microsoft.Cache/redisEnterprise/cache2/databases/default",
},
},
},
Port = 10000,
ResourceGroupName = "rg1",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.redisenterprise.Database;
import com.pulumi.azurenative.redisenterprise.DatabaseArgs;
import com.pulumi.azurenative.redisenterprise.inputs.DatabasePropertiesGeoReplicationArgs;
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 database = new Database("database", DatabaseArgs.builder()
.accessKeysAuthentication("Enabled")
.clientProtocol("Encrypted")
.clusterName("cache1")
.clusteringPolicy("EnterpriseCluster")
.databaseName("default")
.evictionPolicy("NoEviction")
.geoReplication(DatabasePropertiesGeoReplicationArgs.builder()
.groupNickname("groupName")
.linkedDatabases(
LinkedDatabaseArgs.builder()
.id("/subscriptions/e7b5a9d2-6b6a-4d2f-9143-20d9a10f5b8f/resourceGroups/rg1/providers/Microsoft.Cache/redisEnterprise/cache1/databases/default")
.build(),
LinkedDatabaseArgs.builder()
.id("/subscriptions/e7b5a9d2-6b6a-4d2f-9143-20d9a10f5b8e/resourceGroups/rg2/providers/Microsoft.Cache/redisEnterprise/cache2/databases/default")
.build())
.build())
.port(10000)
.resourceGroupName("rg1")
.build());
}
}
resources:
database:
type: azure-native:redisenterprise:Database
properties:
accessKeysAuthentication: Enabled
clientProtocol: Encrypted
clusterName: cache1
clusteringPolicy: EnterpriseCluster
databaseName: default
evictionPolicy: NoEviction
geoReplication:
groupNickname: groupName
linkedDatabases:
- id: /subscriptions/e7b5a9d2-6b6a-4d2f-9143-20d9a10f5b8f/resourceGroups/rg1/providers/Microsoft.Cache/redisEnterprise/cache1/databases/default
- id: /subscriptions/e7b5a9d2-6b6a-4d2f-9143-20d9a10f5b8e/resourceGroups/rg2/providers/Microsoft.Cache/redisEnterprise/cache2/databases/default
port: 10000
resourceGroupName: rg1
The geoReplication block links databases across regions into a replication group. The groupNickname identifies the group, and linkedDatabases lists the database resource IDs to synchronize. Active geo-replication keeps all linked databases in sync, allowing reads and writes from any region. You must create the databases first, then configure replication by referencing their full Azure resource IDs.
Beyond these examples
These snippets focus on specific database-level features: Redis modules, clustering policies and eviction strategies, and persistence and geo-replication. They’re intentionally minimal rather than full cache deployments.
The examples reference pre-existing infrastructure such as Redis Enterprise clusters, Azure resource groups, and existing databases for geo-replication. They focus on configuring the database rather than provisioning the cluster or networking around it.
To keep things focused, common database patterns are omitted, including:
- Upgrade deferral (deferUpgrade)
- Access key authentication controls (accessKeysAuthentication)
- Client protocol selection (clientProtocol)
- Custom port assignment (port)
These omissions are intentional: the goal is to illustrate how each database feature is wired, not provide drop-in cache modules. See the Redis Enterprise Database resource reference for all available configuration options.
Let's configure Azure Redis Enterprise Databases
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Configuration & Immutability
clusterName, databaseName, geoReplication, modules, and port. Plan these configurations carefully, as changing them requires recreating the database.OSSCluster (default), EnterpriseCluster, and NoCluster. You can only update clusteringPolicy if the current value is NoCluster. Changing from OSSCluster or EnterpriseCluster requires deleting and recreating the database.VolatileLRU. Other options include AllKeysLRU (evicts any key using LRU) and NoEviction (returns errors when memory limit is reached).Modules & Extensions
modules array. Modules cannot be added later. Each module can have custom arguments, for example: RedisBloom with args: "ERROR_RATE 0.00 INITIAL_SIZE 400".RedisBloom (probabilistic data structures), RedisTimeSeries (time-series data), and RediSearch (full-text search and indexing).Persistence & Geo-Replication
persistence.aofEnabled to true and specify aofFrequency (e.g., 1s for 1-second intervals). AOF (Append-Only File) provides data durability by logging every write operation.geoReplication at creation time with a groupNickname and linkedDatabases array containing resource IDs of databases in different regions. Geo-replication cannot be enabled after creation.deferUpgrade to defer upgrades when the newest version is released. The default is NotDeferred, which applies upgrades automatically.Security & Access
clientProtocol to specify Encrypted (TLS, default) or Plaintext. You can also control access key authentication with accessKeysAuthentication (Enabled/Disabled), which can be updated after creation.port property is immutable and must be specified at creation time. If not specified, it defaults to an available port.