Skip to content

Commit 865edc2

Browse files
Adding zone distribution mode in the Cluster resource for Memorystore Redis cluster (#10458) (#18307)
[upstream:40e5c97e051e9b4ac75cc1704c1e5a92eaa7bad5] Signed-off-by: Modular Magician <[email protected]>
1 parent 2753939 commit 865edc2

File tree

3 files changed

+238
-0
lines changed

3 files changed

+238
-0
lines changed

google/services/redis/resource_redis_cluster.go

+90
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,30 @@ https://cloud.google.com/memorystore/docs/cluster/supported-instance-configurati
133133
If not provided, encryption is disabled for the cluster. Default value: "TRANSIT_ENCRYPTION_MODE_DISABLED" Possible values: ["TRANSIT_ENCRYPTION_MODE_UNSPECIFIED", "TRANSIT_ENCRYPTION_MODE_DISABLED", "TRANSIT_ENCRYPTION_MODE_SERVER_AUTHENTICATION"]`,
134134
Default: "TRANSIT_ENCRYPTION_MODE_DISABLED",
135135
},
136+
"zone_distribution_config": {
137+
Type: schema.TypeList,
138+
Optional: true,
139+
ForceNew: true,
140+
Description: `Immutable. Zone distribution config for Memorystore Redis cluster.`,
141+
MaxItems: 1,
142+
Elem: &schema.Resource{
143+
Schema: map[string]*schema.Schema{
144+
"mode": {
145+
Type: schema.TypeString,
146+
Computed: true,
147+
Optional: true,
148+
ValidateFunc: verify.ValidateEnum([]string{"MULTI_ZONE", "SINGLE_ZONE", ""}),
149+
Description: `Immutable. The mode for zone distribution for Memorystore Redis cluster.
150+
If not provided, MULTI_ZONE will be used as default Possible values: ["MULTI_ZONE", "SINGLE_ZONE"]`,
151+
},
152+
"zone": {
153+
Type: schema.TypeString,
154+
Optional: true,
155+
Description: `Immutable. The zone for single zone Memorystore Redis cluster.`,
156+
},
157+
},
158+
},
159+
},
136160
"create_time": {
137161
Type: schema.TypeString,
138162
Computed: true,
@@ -299,6 +323,12 @@ func resourceRedisClusterCreate(d *schema.ResourceData, meta interface{}) error
299323
} else if v, ok := d.GetOkExists("node_type"); !tpgresource.IsEmptyValue(reflect.ValueOf(nodeTypeProp)) && (ok || !reflect.DeepEqual(v, nodeTypeProp)) {
300324
obj["nodeType"] = nodeTypeProp
301325
}
326+
zoneDistributionConfigProp, err := expandRedisClusterZoneDistributionConfig(d.Get("zone_distribution_config"), d, config)
327+
if err != nil {
328+
return err
329+
} else if v, ok := d.GetOkExists("zone_distribution_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(zoneDistributionConfigProp)) && (ok || !reflect.DeepEqual(v, zoneDistributionConfigProp)) {
330+
obj["zoneDistributionConfig"] = zoneDistributionConfigProp
331+
}
302332
pscConfigsProp, err := expandRedisClusterPscConfigs(d.Get("psc_configs"), d, config)
303333
if err != nil {
304334
return err
@@ -448,6 +478,9 @@ func resourceRedisClusterRead(d *schema.ResourceData, meta interface{}) error {
448478
if err := d.Set("node_type", flattenRedisClusterNodeType(res["nodeType"], d, config)); err != nil {
449479
return fmt.Errorf("Error reading Cluster: %s", err)
450480
}
481+
if err := d.Set("zone_distribution_config", flattenRedisClusterZoneDistributionConfig(res["zoneDistributionConfig"], d, config)); err != nil {
482+
return fmt.Errorf("Error reading Cluster: %s", err)
483+
}
451484
if err := d.Set("discovery_endpoints", flattenRedisClusterDiscoveryEndpoints(res["discoveryEndpoints"], d, config)); err != nil {
452485
return fmt.Errorf("Error reading Cluster: %s", err)
453486
}
@@ -685,6 +718,29 @@ func flattenRedisClusterNodeType(v interface{}, d *schema.ResourceData, config *
685718
return v
686719
}
687720

721+
func flattenRedisClusterZoneDistributionConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
722+
if v == nil {
723+
return nil
724+
}
725+
original := v.(map[string]interface{})
726+
if len(original) == 0 {
727+
return nil
728+
}
729+
transformed := make(map[string]interface{})
730+
transformed["mode"] =
731+
flattenRedisClusterZoneDistributionConfigMode(original["mode"], d, config)
732+
transformed["zone"] =
733+
flattenRedisClusterZoneDistributionConfigZone(original["zone"], d, config)
734+
return []interface{}{transformed}
735+
}
736+
func flattenRedisClusterZoneDistributionConfigMode(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
737+
return v
738+
}
739+
740+
func flattenRedisClusterZoneDistributionConfigZone(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
741+
return v
742+
}
743+
688744
func flattenRedisClusterDiscoveryEndpoints(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
689745
if v == nil {
690746
return v
@@ -918,6 +974,40 @@ func expandRedisClusterNodeType(v interface{}, d tpgresource.TerraformResourceDa
918974
return v, nil
919975
}
920976

977+
func expandRedisClusterZoneDistributionConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
978+
l := v.([]interface{})
979+
if len(l) == 0 || l[0] == nil {
980+
return nil, nil
981+
}
982+
raw := l[0]
983+
original := raw.(map[string]interface{})
984+
transformed := make(map[string]interface{})
985+
986+
transformedMode, err := expandRedisClusterZoneDistributionConfigMode(original["mode"], d, config)
987+
if err != nil {
988+
return nil, err
989+
} else if val := reflect.ValueOf(transformedMode); val.IsValid() && !tpgresource.IsEmptyValue(val) {
990+
transformed["mode"] = transformedMode
991+
}
992+
993+
transformedZone, err := expandRedisClusterZoneDistributionConfigZone(original["zone"], d, config)
994+
if err != nil {
995+
return nil, err
996+
} else if val := reflect.ValueOf(transformedZone); val.IsValid() && !tpgresource.IsEmptyValue(val) {
997+
transformed["zone"] = transformedZone
998+
}
999+
1000+
return transformed, nil
1001+
}
1002+
1003+
func expandRedisClusterZoneDistributionConfigMode(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1004+
return v, nil
1005+
}
1006+
1007+
func expandRedisClusterZoneDistributionConfigZone(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1008+
return v, nil
1009+
}
1010+
9211011
func expandRedisClusterPscConfigs(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
9221012
l := v.([]interface{})
9231013
req := make([]interface{}, 0, len(l))

google/services/redis/resource_redis_cluster_generated_test.go

+76
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,82 @@ resource "google_redis_cluster" "cluster-ha" {
7272
redis_configs = {
7373
maxmemory-policy = "volatile-ttl"
7474
}
75+
zone_distribution_config {
76+
mode = "MULTI_ZONE"
77+
}
78+
depends_on = [
79+
google_network_connectivity_service_connection_policy.default
80+
]
81+
82+
lifecycle {
83+
prevent_destroy = %{prevent_destroy}
84+
}
85+
}
86+
87+
resource "google_network_connectivity_service_connection_policy" "default" {
88+
name = "mypolicy%{random_suffix}"
89+
location = "us-central1"
90+
service_class = "gcp-memorystore-redis"
91+
description = "my basic service connection policy"
92+
network = google_compute_network.producer_net.id
93+
psc_config {
94+
subnetworks = [google_compute_subnetwork.producer_subnet.id]
95+
}
96+
}
97+
98+
resource "google_compute_subnetwork" "producer_subnet" {
99+
name = "mysubnet%{random_suffix}"
100+
ip_cidr_range = "10.0.0.248/29"
101+
region = "us-central1"
102+
network = google_compute_network.producer_net.id
103+
}
104+
105+
resource "google_compute_network" "producer_net" {
106+
name = "mynetwork%{random_suffix}"
107+
auto_create_subnetworks = false
108+
}
109+
`, context)
110+
}
111+
112+
func TestAccRedisCluster_redisClusterHaSingleZoneExample(t *testing.T) {
113+
t.Parallel()
114+
115+
context := map[string]interface{}{
116+
"prevent_destroy": false,
117+
"random_suffix": acctest.RandString(t, 10),
118+
}
119+
120+
acctest.VcrTest(t, resource.TestCase{
121+
PreCheck: func() { acctest.AccTestPreCheck(t) },
122+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
123+
CheckDestroy: testAccCheckRedisClusterDestroyProducer(t),
124+
Steps: []resource.TestStep{
125+
{
126+
Config: testAccRedisCluster_redisClusterHaSingleZoneExample(context),
127+
},
128+
{
129+
ResourceName: "google_redis_cluster.cluster-ha-single-zone",
130+
ImportState: true,
131+
ImportStateVerify: true,
132+
ImportStateVerifyIgnore: []string{"name", "psc_configs", "region"},
133+
},
134+
},
135+
})
136+
}
137+
138+
func testAccRedisCluster_redisClusterHaSingleZoneExample(context map[string]interface{}) string {
139+
return acctest.Nprintf(`
140+
resource "google_redis_cluster" "cluster-ha-single-zone" {
141+
name = "tf-test-ha-cluster-single-zone%{random_suffix}"
142+
shard_count = 3
143+
psc_configs {
144+
network = google_compute_network.producer_net.id
145+
}
146+
region = "us-central1"
147+
zone_distribution_config {
148+
mode = "SINGLE_ZONE"
149+
zone = "us-central1-f"
150+
}
75151
depends_on = [
76152
google_network_connectivity_service_connection_policy.default
77153
]

website/docs/r/redis_cluster.html.markdown

+72
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,61 @@ resource "google_redis_cluster" "cluster-ha" {
5151
redis_configs = {
5252
maxmemory-policy = "volatile-ttl"
5353
}
54+
zone_distribution_config {
55+
mode = "MULTI_ZONE"
56+
}
57+
depends_on = [
58+
google_network_connectivity_service_connection_policy.default
59+
]
60+
61+
lifecycle {
62+
prevent_destroy = true
63+
}
64+
}
65+
66+
resource "google_network_connectivity_service_connection_policy" "default" {
67+
name = "mypolicy"
68+
location = "us-central1"
69+
service_class = "gcp-memorystore-redis"
70+
description = "my basic service connection policy"
71+
network = google_compute_network.producer_net.id
72+
psc_config {
73+
subnetworks = [google_compute_subnetwork.producer_subnet.id]
74+
}
75+
}
76+
77+
resource "google_compute_subnetwork" "producer_subnet" {
78+
name = "mysubnet"
79+
ip_cidr_range = "10.0.0.248/29"
80+
region = "us-central1"
81+
network = google_compute_network.producer_net.id
82+
}
83+
84+
resource "google_compute_network" "producer_net" {
85+
name = "mynetwork"
86+
auto_create_subnetworks = false
87+
}
88+
```
89+
<div class = "oics-button" style="float: right; margin: 0 0 -15px">
90+
<a href="https://console.cloud.google.com/cloudshell/open?cloudshell_git_repo=https%3A%2F%2Fgithub.jpy.wang%2Fterraform-google-modules%2Fdocs-examples.git&cloudshell_image=gcr.io%2Fcloudshell-images%2Fcloudshell%3Alatest&cloudshell_print=.%2Fmotd&cloudshell_tutorial=.%2Ftutorial.md&cloudshell_working_dir=redis_cluster_ha_single_zone&open_in_editor=main.tf" target="_blank">
91+
<img alt="Open in Cloud Shell" src="//gstatic.com/cloudssh/images/open-btn.svg" style="max-height: 44px; margin: 32px auto; max-width: 100%;">
92+
</a>
93+
</div>
94+
## Example Usage - Redis Cluster Ha Single Zone
95+
96+
97+
```hcl
98+
resource "google_redis_cluster" "cluster-ha-single-zone" {
99+
name = "ha-cluster-single-zone"
100+
shard_count = 3
101+
psc_configs {
102+
network = google_compute_network.producer_net.id
103+
}
104+
region = "us-central1"
105+
zone_distribution_config {
106+
mode = "SINGLE_ZONE"
107+
zone = "us-central1-f"
108+
}
54109
depends_on = [
55110
google_network_connectivity_service_connection_policy.default
56111
]
@@ -136,6 +191,11 @@ The following arguments are supported:
136191
If not provided, REDIS_HIGHMEM_MEDIUM will be used as default
137192
Possible values are: `REDIS_SHARED_CORE_NANO`, `REDIS_HIGHMEM_MEDIUM`, `REDIS_HIGHMEM_XLARGE`, `REDIS_STANDARD_SMALL`.
138193

194+
* `zone_distribution_config` -
195+
(Optional)
196+
Immutable. Zone distribution config for Memorystore Redis cluster.
197+
Structure is [documented below](#nested_zone_distribution_config).
198+
139199
* `replica_count` -
140200
(Optional)
141201
Optional. The number of replica nodes per shard.
@@ -154,6 +214,18 @@ The following arguments are supported:
154214
If it is not provided, the provider project is used.
155215

156216

217+
<a name="nested_zone_distribution_config"></a>The `zone_distribution_config` block supports:
218+
219+
* `mode` -
220+
(Optional)
221+
Immutable. The mode for zone distribution for Memorystore Redis cluster.
222+
If not provided, MULTI_ZONE will be used as default
223+
Possible values are: `MULTI_ZONE`, `SINGLE_ZONE`.
224+
225+
* `zone` -
226+
(Optional)
227+
Immutable. The zone for single zone Memorystore Redis cluster.
228+
157229
## Attributes Reference
158230

159231
In addition to the arguments listed above, the following computed attributes are exported:

0 commit comments

Comments
 (0)