Skip to content

Commit e8383d8

Browse files
feat(spanner): support defining autoscaling limit as nodes (#9606) (#6748)
[upstream:6afde3f9effd7c1c7298108a856395f220421201] Signed-off-by: Modular Magician <[email protected]>
1 parent 3700308 commit e8383d8

File tree

5 files changed

+218
-6
lines changed

5 files changed

+218
-6
lines changed

.changelog/9606.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
spanner: added support for defining autoscaling limit using node count in `google_spanner_instance`
3+
```

google-beta/services/spanner/resource_spanner_instance.go

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,22 +159,44 @@ the instance.`,
159159
Type: schema.TypeList,
160160
Optional: true,
161161
Description: `Defines scale in controls to reduce the risk of response latency
162-
and outages due to abrupt scale-in events`,
162+
and outages due to abrupt scale-in events. Users can define the minimum and
163+
maximum compute capacity allocated to the instance, and the autoscaler will
164+
only scale within that range. Users can either use nodes or processing
165+
units to specify the limits, but should use the same unit to set both the
166+
min_limit and max_limit.`,
163167
MaxItems: 1,
164168
Elem: &schema.Resource{
165169
Schema: map[string]*schema.Schema{
170+
"max_nodes": {
171+
Type: schema.TypeInt,
172+
Optional: true,
173+
Description: `Specifies maximum number of nodes allocated to the instance. If set, this number
174+
should be greater than or equal to min_nodes.`,
175+
ExactlyOneOf: []string{},
176+
RequiredWith: []string{},
177+
},
166178
"max_processing_units": {
167179
Type: schema.TypeInt,
168180
Optional: true,
169181
Description: `Specifies maximum number of processing units allocated to the instance.
170182
If set, this number should be multiples of 1000 and be greater than or equal to
171183
min_processing_units.`,
184+
ExactlyOneOf: []string{},
185+
},
186+
"min_nodes": {
187+
Type: schema.TypeInt,
188+
Optional: true,
189+
Description: `Specifies number of nodes allocated to the instance. If set, this number
190+
should be greater than or equal to 1.`,
191+
ExactlyOneOf: []string{},
192+
RequiredWith: []string{},
172193
},
173194
"min_processing_units": {
174195
Type: schema.TypeInt,
175196
Optional: true,
176197
Description: `Specifies minimum number of processing units allocated to the instance.
177198
If set, this number should be multiples of 1000.`,
199+
ExactlyOneOf: []string{},
178200
},
179201
},
180202
},
@@ -792,6 +814,10 @@ func flattenSpannerInstanceAutoscalingConfigAutoscalingLimits(v interface{}, d *
792814
flattenSpannerInstanceAutoscalingConfigAutoscalingLimitsMinProcessingUnits(original["minProcessingUnits"], d, config)
793815
transformed["max_processing_units"] =
794816
flattenSpannerInstanceAutoscalingConfigAutoscalingLimitsMaxProcessingUnits(original["maxProcessingUnits"], d, config)
817+
transformed["min_nodes"] =
818+
flattenSpannerInstanceAutoscalingConfigAutoscalingLimitsMinNodes(original["minNodes"], d, config)
819+
transformed["max_nodes"] =
820+
flattenSpannerInstanceAutoscalingConfigAutoscalingLimitsMaxNodes(original["maxNodes"], d, config)
795821
return []interface{}{transformed}
796822
}
797823
func flattenSpannerInstanceAutoscalingConfigAutoscalingLimitsMinProcessingUnits(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
@@ -828,6 +854,40 @@ func flattenSpannerInstanceAutoscalingConfigAutoscalingLimitsMaxProcessingUnits(
828854
return v // let terraform core handle it otherwise
829855
}
830856

857+
func flattenSpannerInstanceAutoscalingConfigAutoscalingLimitsMinNodes(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
858+
// Handles the string fixed64 format
859+
if strVal, ok := v.(string); ok {
860+
if intVal, err := tpgresource.StringToFixed64(strVal); err == nil {
861+
return intVal
862+
}
863+
}
864+
865+
// number values are represented as float64
866+
if floatVal, ok := v.(float64); ok {
867+
intVal := int(floatVal)
868+
return intVal
869+
}
870+
871+
return v // let terraform core handle it otherwise
872+
}
873+
874+
func flattenSpannerInstanceAutoscalingConfigAutoscalingLimitsMaxNodes(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
875+
// Handles the string fixed64 format
876+
if strVal, ok := v.(string); ok {
877+
if intVal, err := tpgresource.StringToFixed64(strVal); err == nil {
878+
return intVal
879+
}
880+
}
881+
882+
// number values are represented as float64
883+
if floatVal, ok := v.(float64); ok {
884+
intVal := int(floatVal)
885+
return intVal
886+
}
887+
888+
return v // let terraform core handle it otherwise
889+
}
890+
831891
func flattenSpannerInstanceAutoscalingConfigAutoscalingTargets(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
832892
if v == nil {
833893
return nil
@@ -975,6 +1035,20 @@ func expandSpannerInstanceAutoscalingConfigAutoscalingLimits(v interface{}, d tp
9751035
transformed["maxProcessingUnits"] = transformedMaxProcessingUnits
9761036
}
9771037

1038+
transformedMinNodes, err := expandSpannerInstanceAutoscalingConfigAutoscalingLimitsMinNodes(original["min_nodes"], d, config)
1039+
if err != nil {
1040+
return nil, err
1041+
} else if val := reflect.ValueOf(transformedMinNodes); val.IsValid() && !tpgresource.IsEmptyValue(val) {
1042+
transformed["minNodes"] = transformedMinNodes
1043+
}
1044+
1045+
transformedMaxNodes, err := expandSpannerInstanceAutoscalingConfigAutoscalingLimitsMaxNodes(original["max_nodes"], d, config)
1046+
if err != nil {
1047+
return nil, err
1048+
} else if val := reflect.ValueOf(transformedMaxNodes); val.IsValid() && !tpgresource.IsEmptyValue(val) {
1049+
transformed["maxNodes"] = transformedMaxNodes
1050+
}
1051+
9781052
return transformed, nil
9791053
}
9801054

@@ -986,6 +1060,14 @@ func expandSpannerInstanceAutoscalingConfigAutoscalingLimitsMaxProcessingUnits(v
9861060
return v, nil
9871061
}
9881062

1063+
func expandSpannerInstanceAutoscalingConfigAutoscalingLimitsMinNodes(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1064+
return v, nil
1065+
}
1066+
1067+
func expandSpannerInstanceAutoscalingConfigAutoscalingLimitsMaxNodes(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1068+
return v, nil
1069+
}
1070+
9891071
func expandSpannerInstanceAutoscalingConfigAutoscalingTargets(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
9901072
l := v.([]interface{})
9911073
if len(l) == 0 || l[0] == nil {
@@ -1077,6 +1159,12 @@ func resourceSpannerInstanceUpdateEncoder(d *schema.ResourceData, meta interface
10771159
if d.HasChange("autoscaling_config.0.autoscaling_limits.0.min_processing_units") {
10781160
updateMask = append(updateMask, "autoscalingConfig.autoscalingLimits.minProcessingUnits")
10791161
}
1162+
if d.HasChange("autoscaling_config.0.autoscaling_limits.0.max_nodes") {
1163+
updateMask = append(updateMask, "autoscalingConfig.autoscalingLimits.maxNodes")
1164+
}
1165+
if d.HasChange("autoscaling_config.0.autoscaling_limits.0.min_nodes") {
1166+
updateMask = append(updateMask, "autoscalingConfig.autoscalingLimits.minNodes")
1167+
}
10801168
if d.HasChange("autoscaling_config.0.autoscaling_targets.0.high_priority_cpu_utilization_percent") {
10811169
updateMask = append(updateMask, "autoscalingConfig.autoscalingTargets.highPriorityCpuUtilizationPercent")
10821170
}

google-beta/services/spanner/resource_spanner_instance_generated_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,11 @@ resource "google_spanner_instance" "example" {
141141
display_name = "Test Spanner Instance"
142142
autoscaling_config {
143143
autoscaling_limits {
144-
max_processing_units = 3000
145-
min_processing_units = 2000
144+
// Define the minimum and maximum compute capacity allocated to the instance
145+
// Either use nodes or processing units to specify the limits,
146+
// but should use the same unit to set both the min_limit and max_limit.
147+
max_processing_units = 3000 // OR max_nodes = 3
148+
min_processing_units = 2000 // OR min_nodes = 2
146149
}
147150
autoscaling_targets {
148151
high_priority_cpu_utilization_percent = 75

google-beta/services/spanner/resource_spanner_instance_test.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,67 @@ func TestAccSpannerInstance_basicWithAutoscalingUsingProcessingUnitConfigUpdate(
205205
})
206206
}
207207

208+
func TestAccSpannerInstance_basicWithAutoscalingUsingNodeConfig(t *testing.T) {
209+
t.Parallel()
210+
211+
displayName := fmt.Sprintf("spanner-test-%s-dname", acctest.RandString(t, 10))
212+
acctest.VcrTest(t, resource.TestCase{
213+
PreCheck: func() { acctest.AccTestPreCheck(t) },
214+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
215+
CheckDestroy: testAccCheckSpannerInstanceDestroyProducer(t),
216+
Steps: []resource.TestStep{
217+
{
218+
Config: testAccSpannerInstance_basicWithAutoscalerConfigUsingNodesAsConfigs(displayName),
219+
Check: resource.ComposeTestCheckFunc(
220+
resource.TestCheckResourceAttrSet("google_spanner_instance.basic", "state"),
221+
),
222+
},
223+
{
224+
ResourceName: "google_spanner_instance.basic",
225+
ImportState: true,
226+
ImportStateVerify: true,
227+
},
228+
},
229+
})
230+
}
231+
232+
func TestAccSpannerInstance_basicWithAutoscalingUsingNodeConfigUpdate(t *testing.T) {
233+
t.Parallel()
234+
235+
displayName := fmt.Sprintf("spanner-test-%s-dname", acctest.RandString(t, 10))
236+
acctest.VcrTest(t, resource.TestCase{
237+
PreCheck: func() { acctest.AccTestPreCheck(t) },
238+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
239+
CheckDestroy: testAccCheckSpannerInstanceDestroyProducer(t),
240+
Steps: []resource.TestStep{
241+
{
242+
Config: testAccSpannerInstance_basicWithAutoscalerConfigUsingNodesAsConfigsUpdate(displayName, 1, 2, 65, 95),
243+
Check: resource.ComposeTestCheckFunc(
244+
resource.TestCheckResourceAttrSet("google_spanner_instance.basic", "state"),
245+
),
246+
},
247+
{
248+
ResourceName: "google_spanner_instance.basic",
249+
ImportState: true,
250+
ImportStateVerify: true,
251+
ImportStateVerifyIgnore: []string{"labels", "terraform_labels"},
252+
},
253+
{
254+
Config: testAccSpannerInstance_basicWithAutoscalerConfigUsingNodesAsConfigsUpdate(displayName, 2, 3, 75, 90),
255+
Check: resource.ComposeTestCheckFunc(
256+
resource.TestCheckResourceAttrSet("google_spanner_instance.basic", "state"),
257+
),
258+
},
259+
{
260+
ResourceName: "google_spanner_instance.basic",
261+
ImportState: true,
262+
ImportStateVerify: true,
263+
ImportStateVerifyIgnore: []string{"labels", "terraform_labels"},
264+
},
265+
},
266+
})
267+
}
268+
208269
func testAccSpannerInstance_basic(name string) string {
209270
return fmt.Sprintf(`
210271
resource "google_spanner_instance" "basic" {
@@ -306,3 +367,43 @@ resource "google_spanner_instance" "basic" {
306367
}
307368
`, name, name, maxProcessingUnits, minProcessingUnits, cupUtilizationPercent, storageUtilizationPercent)
308369
}
370+
371+
func testAccSpannerInstance_basicWithAutoscalerConfigUsingNodesAsConfigs(name string) string {
372+
return fmt.Sprintf(`
373+
resource "google_spanner_instance" "basic" {
374+
name = "%s"
375+
config = "regional-us-central1"
376+
display_name = "%s"
377+
autoscaling_config {
378+
autoscaling_limits {
379+
max_nodes = 2
380+
min_nodes = 1
381+
}
382+
autoscaling_targets {
383+
high_priority_cpu_utilization_percent = 65
384+
storage_utilization_percent = 95
385+
}
386+
}
387+
}
388+
`, name, name)
389+
}
390+
391+
func testAccSpannerInstance_basicWithAutoscalerConfigUsingNodesAsConfigsUpdate(name string, minNodes, maxNodes, cupUtilizationPercent, storageUtilizationPercent int) string {
392+
return fmt.Sprintf(`
393+
resource "google_spanner_instance" "basic" {
394+
name = "%s"
395+
config = "regional-us-central1"
396+
display_name = "%s"
397+
autoscaling_config {
398+
autoscaling_limits {
399+
max_nodes = %v
400+
min_nodes = %v
401+
}
402+
autoscaling_targets {
403+
high_priority_cpu_utilization_percent = %v
404+
storage_utilization_percent = %v
405+
}
406+
}
407+
}
408+
`, name, name, maxNodes, minNodes, cupUtilizationPercent, storageUtilizationPercent)
409+
}

website/docs/r/spanner_instance.html.markdown

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,11 @@ resource "google_spanner_instance" "example" {
8080
display_name = "Test Spanner Instance"
8181
autoscaling_config {
8282
autoscaling_limits {
83-
max_processing_units = 3000
84-
min_processing_units = 2000
83+
// Define the minimum and maximum compute capacity allocated to the instance
84+
// Either use nodes or processing units to specify the limits,
85+
// but should use the same unit to set both the min_limit and max_limit.
86+
max_processing_units = 3000 // OR max_nodes = 3
87+
min_processing_units = 2000 // OR min_nodes = 2
8588
}
8689
autoscaling_targets {
8790
high_priority_cpu_utilization_percent = 75
@@ -181,7 +184,11 @@ This must be set to true if you created a backup manually in the console.
181184
* `autoscaling_limits` -
182185
(Optional)
183186
Defines scale in controls to reduce the risk of response latency
184-
and outages due to abrupt scale-in events
187+
and outages due to abrupt scale-in events. Users can define the minimum and
188+
maximum compute capacity allocated to the instance, and the autoscaler will
189+
only scale within that range. Users can either use nodes or processing
190+
units to specify the limits, but should use the same unit to set both the
191+
min_limit and max_limit.
185192
Structure is [documented below](#nested_autoscaling_limits).
186193

187194
* `autoscaling_targets` -
@@ -204,6 +211,16 @@ This must be set to true if you created a backup manually in the console.
204211
If set, this number should be multiples of 1000 and be greater than or equal to
205212
min_processing_units.
206213

214+
* `min_nodes` -
215+
(Optional)
216+
Specifies number of nodes allocated to the instance. If set, this number
217+
should be greater than or equal to 1.
218+
219+
* `max_nodes` -
220+
(Optional)
221+
Specifies maximum number of nodes allocated to the instance. If set, this number
222+
should be greater than or equal to min_nodes.
223+
207224
<a name="nested_autoscaling_targets"></a>The `autoscaling_targets` block supports:
208225

209226
* `high_priority_cpu_utilization_percent` -

0 commit comments

Comments
 (0)