Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add redis_configs parameter to Redis Cluster #10515

Merged
merged 1 commit into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions mmv1/products/redis/Cluster.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,9 @@ properties:
description: |
Required. Number of shards for the Redis cluster.
required: true
- !ruby/object:Api::Type::KeyValuePairs
name: 'redisConfigs'
description: |
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
3 changes: 3 additions & 0 deletions mmv1/templates/terraform/examples/redis_cluster_ha.tf.erb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ resource "google_redis_cluster" "<%= ctx[:primary_resource_id] %>" {
node_type = "REDIS_SHARED_CORE_NANO"
transit_encryption_mode = "TRANSIT_ENCRYPTION_MODE_DISABLED"
authorization_mode = "AUTH_MODE_DISABLED"
redis_configs = {
maxmemory-policy = "volatile-ttl"
}
depends_on = [
google_network_connectivity_service_connection_policy.default
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,39 @@ package redis_test

import (
"fmt"
"strings"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-provider-google/google/acctest"
)

func TestAccRedisCluster_createClusterWithNodeType(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 replica count 1
Config: createOrUpdateRedisCluster(name, /* replicaCount = */ 1, /* shardCount = */ 3, true, /*nodeType = */ "REDIS_STANDARD_SMALL"),
},
{
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"psc_configs"},
},
{
// clean up the resource
Config: createOrUpdateRedisCluster(name, /* replicaCount = */ 0, /* shardCount = */ 3, false, /*nodeType = */ "REDIS_STANDARD_SMALL"),
},
},
})
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 replica count 1
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, preventDestroy: true, nodeType: "REDIS_STANDARD_SMALL"}),
},
{
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, preventDestroy: false, nodeType: "REDIS_STANDARD_SMALL"}),
},
},
})
}

// Validate that replica count is updated for the cluster
Expand All @@ -51,41 +52,41 @@ func TestAccRedisCluster_updateReplicaCount(t *testing.T) {
Steps: []resource.TestStep{
{
// create cluster with replica count 1
Config: createOrUpdateRedisCluster(name, /* replicaCount = */ 1, /* shardCount = */ 3, true, /* nodeType = */ ""),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, preventDestroy: true}),
},
{
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"psc_configs"},
},
{
// update replica count to 2
Config: createOrUpdateRedisCluster(name, /* replicaCount = */ 2, /* shardCount = */ 3, true, /*nodeType = */ ""),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 2, shardCount: 3, preventDestroy: true}),
},
{
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"psc_configs"},
},
{
// clean up the resource
Config: createOrUpdateRedisCluster(name, /* replicaCount = */ 2, /* shardCount = */ 3, false, /*nodeType = */ ""),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, preventDestroy: false}),
},
{
// update replica count to 0
Config: createOrUpdateRedisCluster(name, /* replicaCount = */ 0, /* shardCount = */ 3, true, /*nodeType = */ ""),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, preventDestroy: true}),
},
{
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"psc_configs"},
},
{
// clean up the resource
Config: createOrUpdateRedisCluster(name /* replicaCount = */, 0 /* shardCount = */, 3, false, /*nodeType = */ ""),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 0, shardCount: 3, preventDestroy: false}),
},
},
})
Expand All @@ -104,83 +105,151 @@ func TestAccRedisCluster_updateShardCount(t *testing.T) {
Steps: []resource.TestStep{
{
// create cluster with shard count 3
Config: createOrUpdateRedisCluster(name /* replicaCount = */, 1 /* shardCount = */, 3, true, /*nodeType = */ ""),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 3, preventDestroy: true}),
},
{
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"psc_configs"},

},
{
// update shard count to 5
Config: createOrUpdateRedisCluster(name /* replicaCount = */, 1 /* shardCount = */, 5, true, /*nodeType = */ ""),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 5, preventDestroy: true}),
},
{
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"psc_configs"},
},
{
// clean up the resource
Config: createOrUpdateRedisCluster(name /* replicaCount = */, 1 /* shardCount = */, 5, false, /* nodeType = */ ""),
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, replicaCount: 1, shardCount: 5, preventDestroy: false}),
},
},
})
}

func createOrUpdateRedisCluster(name string, replicaCount int, shardCount int, preventDestroy bool, nodeType string) string {
// Validate that redisConfigs is updated for the cluster
func TestAccRedisCluster_updateRedisConfigs(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
Config: createOrUpdateRedisCluster(&ClusterParams{
name: name,
shardCount: 3,
redisConfigs: map[string]string{
"maxmemory-policy": "volatile-ttl",
}}),
},
{
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"psc_configs"},
},
{
// add a new redis config key-value pair and update existing redis config
Config: createOrUpdateRedisCluster(&ClusterParams{
name: name,
shardCount: 3,
redisConfigs: map[string]string{
"maxmemory-policy": "allkeys-lru",
"maxmemory-clients": "90%",
}}),
},
{
ResourceName: "google_redis_cluster.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"psc_configs"},
},
{
// remove all redis configs
Config: createOrUpdateRedisCluster(&ClusterParams{name: name, shardCount: 3}),
},

},
})
}

type ClusterParams struct {
name string
replicaCount int
shardCount int
preventDestroy bool
nodeType string
redisConfigs map[string]string
}

func createOrUpdateRedisCluster(params *ClusterParams) string {
Comment on lines +185 to +194
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nice improvement, thanks!

lifecycleBlock := ""
if preventDestroy {
if params.preventDestroy {
lifecycleBlock = `
lifecycle {
prevent_destroy = true
}`
}
var strBuilder strings.Builder
for key, value := range params.redisConfigs {
strBuilder.WriteString(fmt.Sprintf("%s = \"%s\"\n", key, value))
}

return fmt.Sprintf(`
resource "google_redis_cluster" "test" {
provider = google-beta
name = "%s"
provider = google-beta
name = "%s"
replica_count = %d
shard_count = %d
node_type = "%s"
region = "us-central1"
region = "us-central1"
psc_configs {
network = google_compute_network.producer_net.id
}
redis_configs = {
%s
}
depends_on = [
google_network_connectivity_service_connection_policy.default
]
google_network_connectivity_service_connection_policy.default
]
%s
}

resource "google_network_connectivity_service_connection_policy" "default" {
provider = google-beta
name = "%s"
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]
}
provider = google-beta
name = "%s"
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" {
provider = google-beta
name = "%s"
ip_cidr_range = "10.0.0.248/29"
region = "us-central1"
network = google_compute_network.producer_net.id
provider = google-beta
name = "%s"
ip_cidr_range = "10.0.0.248/29"
region = "us-central1"
network = google_compute_network.producer_net.id
}

resource "google_compute_network" "producer_net" {
provider = google-beta
name = "%s"
auto_create_subnetworks = false
provider = google-beta
name = "%s"
auto_create_subnetworks = false
}
`, name, replicaCount, shardCount, nodeType, lifecycleBlock, name, name, name)
`, params.name, params.replicaCount, params.shardCount, params.nodeType, strBuilder.String(), lifecycleBlock, params.name, params.name, params.name)
}

<% end -%>