Skip to content

Commit

Permalink
Add RDB & AOF Persistence support to Memorystore for Redis Cluster (G…
Browse files Browse the repository at this point in the history
  • Loading branch information
fewtrell authored and amanMahendroo committed Dec 17, 2024
1 parent 0b5a61a commit edfc70b
Show file tree
Hide file tree
Showing 4 changed files with 273 additions and 3 deletions.
92 changes: 92 additions & 0 deletions mmv1/products/redis/Cluster.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,30 @@ examples:
'deletion_protection_enabled': 'false'
oics_vars_overrides:
'deletion_protection_enabled': 'false'
- name: "redis_cluster_rdb"
primary_resource_id: "cluster-rdb"
vars:
cluster_name: "rdb-cluster"
policy_name: "mypolicy"
subnet_name: "mysubnet"
network_name: "mynetwork"
deletion_protection_enabled: 'true'
test_vars_overrides:
'deletion_protection_enabled': 'false'
oics_vars_overrides:
'deletion_protection_enabled': 'false'
- name: "redis_cluster_aof"
primary_resource_id: "cluster-aof"
vars:
cluster_name: "aof-cluster"
policy_name: "mypolicy"
subnet_name: "mysubnet"
network_name: "mynetwork"
deletion_protection_enabled: 'true'
test_vars_overrides:
'deletion_protection_enabled': 'false'
oics_vars_overrides:
'deletion_protection_enabled': 'false'
parameters:
- name: 'name'
type: String
Expand Down Expand Up @@ -286,6 +310,74 @@ properties:
Configure Redis Cluster behavior using a subset of native Redis configuration parameters.
Please check Memorystore documentation for the list of supported parameters:
https://cloud.google.com/memorystore/docs/cluster/supported-instance-configurations
- name: 'persistenceConfig'
type: NestedObject
description: Persistence config (RDB, AOF) for the cluster.
default_from_api: true
properties:
- name: 'mode'
type: Enum
description: |
Optional. Controls whether Persistence features are enabled. If not provided, the existing value will be used.
- DISABLED: Persistence (both backup and restore) is disabled for the cluster.
- RDB: RDB based Persistence is enabled.
- AOF: AOF based Persistence is enabled.
enum_values:
- 'PERSISTENCE_MODE_UNSPECIFIED'
- 'DISABLED'
- 'RDB'
- 'AOF'
default_from_api: true
- name: 'rdbConfig'
type: NestedObject
description: |
RDB configuration. This field will be ignored if mode is not RDB.
default_from_api: true
properties:
- name: 'rdbSnapshotPeriod'
type: Enum
default_from_api: true
description: |
Optional. Available snapshot periods for scheduling.
- ONE_HOUR: Snapshot every 1 hour.
- SIX_HOURS: Snapshot every 6 hours.
- TWELVE_HOURS: Snapshot every 12 hours.
- TWENTY_FOUR_HOURS: Snapshot every 24 hours.
enum_values:
- 'SNAPSHOT_PERIOD_UNSPECIFIED'
- 'ONE_HOUR'
- 'SIX_HOURS'
- 'TWELVE_HOURS'
- 'TWENTY_FOUR_HOURS'
- name: 'rdbSnapshotStartTime'
type: Time
description: |
The time that the first snapshot was/will be attempted, and to which
future snapshots will be aligned.
If not provided, the current time will be used.
default_from_api: true
- name: 'aofConfig'
type: NestedObject
description: |
AOF configuration. This field will be ignored if mode is not AOF.
default_from_api: true
properties:
- name: 'appendFsync'
type: Enum
default_from_api: true
description: |
Optional. Available fsync modes.
- NO - Do not explicilty call fsync(). Rely on OS defaults.
- EVERYSEC - Call fsync() once per second in a background thread. A balance between performance and durability.
- ALWAYS - Call fsync() for earch write command.
enum_values:
- 'APPEND_FSYNC_UNSPECIFIED'
- 'NO'
- 'EVERYSEC'
- 'ALWAYS'
- name: 'maintenancePolicy'
type: NestedObject
description: Maintenance policy for a cluster
Expand Down
63 changes: 63 additions & 0 deletions mmv1/templates/terraform/examples/redis_cluster_aof.tf.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
resource "google_redis_cluster" "{{$.PrimaryResourceId}}" {
name = "{{index $.Vars "cluster_name"}}"
shard_count = 3
psc_configs {
network = google_compute_network.producer_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 = {{index $.Vars "deletion_protection_enabled"}}

zone_distribution_config {
mode = "MULTI_ZONE"
}
maintenance_policy {
weekly_maintenance_window {
day = "MONDAY"
start_time {
hours = 1
minutes = 0
seconds = 0
nanos = 0
}
}
}
persistence_config {
mode = "AOF"
aof_config {
append_fsync = "EVERYSEC"
}
}
depends_on = [
google_network_connectivity_service_connection_policy.default
]
}

resource "google_network_connectivity_service_connection_policy" "default" {
name = "{{index $.Vars "policy_name"}}"
location = "us-central1"
service_class = "gcp-memorystore-redis"
description = "my basic service connection policy"
network = google_compute_network.producer_net.id
psc_config {
subnetworks = [google_compute_subnetwork.producer_subnet.id]
}
}

resource "google_compute_subnetwork" "producer_subnet" {
name = "{{index $.Vars "subnet_name"}}"
ip_cidr_range = "10.0.0.248/29"
region = "us-central1"
network = google_compute_network.producer_net.id
}

resource "google_compute_network" "producer_net" {
name = "{{index $.Vars "network_name"}}"
auto_create_subnetworks = false
}
64 changes: 64 additions & 0 deletions mmv1/templates/terraform/examples/redis_cluster_rdb.tf.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
resource "google_redis_cluster" "{{$.PrimaryResourceId}}" {
name = "{{index $.Vars "cluster_name"}}"
shard_count = 3
psc_configs {
network = google_compute_network.producer_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 = {{index $.Vars "deletion_protection_enabled"}}

zone_distribution_config {
mode = "MULTI_ZONE"
}
maintenance_policy {
weekly_maintenance_window {
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"
}
}
depends_on = [
google_network_connectivity_service_connection_policy.default
]
}

resource "google_network_connectivity_service_connection_policy" "default" {
name = "{{index $.Vars "policy_name"}}"
location = "us-central1"
service_class = "gcp-memorystore-redis"
description = "my basic service connection policy"
network = google_compute_network.producer_net.id
psc_config {
subnetworks = [google_compute_subnetwork.producer_subnet.id]
}
}

resource "google_compute_subnetwork" "producer_subnet" {
name = "{{index $.Vars "subnet_name"}}"
ip_cidr_range = "10.0.0.248/29"
region = "us-central1"
network = google_compute_network.producer_net.id
}

resource "google_compute_network" "producer_net" {
name = "{{index $.Vars "network_name"}}"
auto_create_subnetworks = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,55 @@ func TestAccRedisCluster_createUpdateDeletionProtection(t *testing.T) {
})
}


// Validate that persistence is updated for the cluster
func TestAccRedisCluster_persistenceUpdate(t *testing.T) {
t.Parallel()

name := fmt.Sprintf("tf-test-%d", acctest.RandInt(t))

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t),
CheckDestroy: testAccCheckRedisClusterDestroyProducer(t),
Steps: []resource.TestStep{
{
// create cluster with AOF enabled
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, nodeType: "REDIS_STANDARD_SMALL", zoneDistributionMode: "MULTI_ZONE", persistenceBlock: "persistence_config {\nmode = \"AOF\"\naof_config{\nappend_fsync = \"EVERYSEC\"\n}\n}"}),
},
{
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"psc_configs"},
},
{
// disable AOF
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, nodeType: "REDIS_STANDARD_SMALL", zoneDistributionMode: "MULTI_ZONE", persistenceBlock: "persistence_config {\nmode = \"DISABLED\"\n}"}),
},
{
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"psc_configs"},
}, {
// update persistence to RDB
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, nodeType: "REDIS_STANDARD_SMALL", zoneDistributionMode: "MULTI_ZONE", persistenceBlock: "persistence_config {\nmode = \"RDB\"\nrdb_config {\nrdb_snapshot_period = \"ONE_HOUR\"\nrdb_snapshot_start_time = \"2024-10-02T15:01:23Z\"\n}\n}"}),
},
{
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"psc_configs"},
},
{
// clean up the resource
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, nodeType: "REDIS_STANDARD_SMALL", zoneDistributionMode: "MULTI_ZONE", persistenceBlock: "persistence_config {\nmode = \"RDB\"\nrdb_config {\nrdb_snapshot_period = \"ONE_HOUR\"\nrdb_snapshot_start_time = \"2024-10-02T15:01:23Z\"\n}\n}"}),
},
},
})
}

type ClusterParams struct {
name string
replicaCount int
Expand All @@ -274,12 +323,13 @@ type ClusterParams struct {
maintenanceMinutes int
maintenanceSeconds int
maintenanceNanos int
persistenceBlock string
}

func createOrUpdateRedisCluster(params *ClusterParams) string {
var strBuilder strings.Builder
var redsConfigsStrBuilder strings.Builder
for key, value := range params.redisConfigs {
strBuilder.WriteString(fmt.Sprintf("%s = \"%s\"\n", key, value))
redsConfigsStrBuilder.WriteString(fmt.Sprintf("%s = \"%s\"\n", key, value))
}

zoneDistributionConfigBlock := ``
Expand Down Expand Up @@ -325,6 +375,7 @@ resource "google_redis_cluster" "test" {
%s
}
%s
%s
%s
depends_on = [
google_network_connectivity_service_connection_policy.default
Expand Down Expand Up @@ -356,7 +407,7 @@ resource "google_compute_network" "producer_net" {
name = "%s"
auto_create_subnetworks = false
}
`, params.name, params.replicaCount, params.shardCount, params.nodeType, params.deletionProtectionEnabled, strBuilder.String(), zoneDistributionConfigBlock, maintenancePolicyBlock, params.name, params.name, params.name)
`, params.name, params.replicaCount, params.shardCount, params.nodeType, params.deletionProtectionEnabled, redsConfigsStrBuilder.String(), zoneDistributionConfigBlock, maintenancePolicyBlock, params.persistenceBlock, params.name, params.name, params.name)
}

{{ end }}

0 comments on commit edfc70b

Please sign in to comment.