Skip to content

Commit 330245e

Browse files
Add Backend Service Custom Metrics. (#13205) (#21710)
[upstream:42f65f7727c86ded43929422f2d6c63986c3bce1] Signed-off-by: Modular Magician <magic-modules@google.com>
1 parent f941faa commit 330245e

7 files changed

+750
-16
lines changed

.changelog/13205.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
compute: added `custom_metrics` field to `google_compute_backend_service` and `google_compute_region_backend_service` (beta)
3+
```

google/services/compute/resource_compute_backend_service.go

+242-6
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,33 @@ Defaults to 1024.`,
578578
},
579579
},
580580
},
581+
"custom_metrics": {
582+
Type: schema.TypeList,
583+
Optional: true,
584+
Description: `List of custom metrics that are used for the WEIGHTED_ROUND_ROBIN locality_lb_policy.`,
585+
Elem: &schema.Resource{
586+
Schema: map[string]*schema.Schema{
587+
"dry_run": {
588+
Type: schema.TypeBool,
589+
Required: true,
590+
Description: `If true, the metric data is not used for load balancing.`,
591+
},
592+
"name": {
593+
Type: schema.TypeString,
594+
Required: true,
595+
Description: `Name of a custom utilization signal. The name must be 1-64 characters
596+
long and match the regular expression [a-z]([-_.a-z0-9]*[a-z0-9])? which
597+
means the first character must be a lowercase letter, and all following
598+
characters must be a dash, period, underscore, lowercase letter, or
599+
digit, except the last character, which cannot be a dash, period, or
600+
underscore. For usage guidelines, see Custom Metrics balancing mode. This
601+
field can only be used for a global or regional backend service with the
602+
loadBalancingScheme set to <code>EXTERNAL_MANAGED</code>,
603+
<code>INTERNAL_MANAGED</code> <code>INTERNAL_SELF_MANAGED</code>.`,
604+
},
605+
},
606+
},
607+
},
581608
"custom_request_headers": {
582609
Type: schema.TypeSet,
583610
Optional: true,
@@ -783,7 +810,7 @@ The possible values are:
783810
"locality_lb_policy": {
784811
Type: schema.TypeString,
785812
Optional: true,
786-
ValidateFunc: verify.ValidateEnum([]string{"ROUND_ROBIN", "LEAST_REQUEST", "RING_HASH", "RANDOM", "ORIGINAL_DESTINATION", "MAGLEV", "WEIGHTED_MAGLEV", ""}),
813+
ValidateFunc: verify.ValidateEnum([]string{"ROUND_ROBIN", "LEAST_REQUEST", "RING_HASH", "RANDOM", "ORIGINAL_DESTINATION", "MAGLEV", "WEIGHTED_MAGLEV", "WEIGHTED_ROUND_ROBIN", ""}),
787814
Description: `The load balancing algorithm used within the scope of the locality.
788815
The possible values are:
789816
@@ -825,6 +852,13 @@ The possible values are:
825852
UNAVAILABLE_WEIGHT. Otherwise, Load Balancing remains
826853
equal-weight.
827854
855+
* 'WEIGHTED_ROUND_ROBIN': Per-endpoint weighted round-robin Load Balancing using weights computed
856+
from Backend reported Custom Metrics. If set, the Backend Service
857+
responses are expected to contain non-standard HTTP response header field
858+
X-Endpoint-Load-Metrics. The reported metrics
859+
to use for computing the weights are specified via the
860+
backends[].customMetrics fields.
861+
828862
locality_lb_policy is applicable to either:
829863
830864
* A regional backend service with the service_protocol set to HTTP, HTTPS, or HTTP2,
@@ -839,7 +873,7 @@ or RING_HASH, session affinity settings will not take effect.
839873
840874
Only ROUND_ROBIN and RING_HASH are supported when the backend service is referenced
841875
by a URL map that is bound to target gRPC proxy that has validate_for_proxyless
842-
field set to true. Possible values: ["ROUND_ROBIN", "LEAST_REQUEST", "RING_HASH", "RANDOM", "ORIGINAL_DESTINATION", "MAGLEV", "WEIGHTED_MAGLEV"]`,
876+
field set to true. Possible values: ["ROUND_ROBIN", "LEAST_REQUEST", "RING_HASH", "RANDOM", "ORIGINAL_DESTINATION", "MAGLEV", "WEIGHTED_MAGLEV", "WEIGHTED_ROUND_ROBIN"]`,
843877
},
844878
"log_config": {
845879
Type: schema.TypeList,
@@ -1229,15 +1263,15 @@ partial URL.`,
12291263
"balancing_mode": {
12301264
Type: schema.TypeString,
12311265
Optional: true,
1232-
ValidateFunc: verify.ValidateEnum([]string{"UTILIZATION", "RATE", "CONNECTION", ""}),
1266+
ValidateFunc: verify.ValidateEnum([]string{"UTILIZATION", "RATE", "CONNECTION", "CUSTOM_METRICS", ""}),
12331267
Description: `Specifies the balancing mode for this backend.
12341268
12351269
For global HTTP(S) or TCP/SSL load balancing, the default is
1236-
UTILIZATION. Valid values are UTILIZATION, RATE (for HTTP(S))
1237-
and CONNECTION (for TCP/SSL).
1270+
UTILIZATION. Valid values are UTILIZATION, RATE (for HTTP(S)),
1271+
CUSTOM_METRICS (for HTTP(s)) and CONNECTION (for TCP/SSL).
12381272
12391273
See the [Backend Services Overview](https://cloud.google.com/load-balancing/docs/backend-service#balancing-mode)
1240-
for an explanation of load balancing modes. Default value: "UTILIZATION" Possible values: ["UTILIZATION", "RATE", "CONNECTION"]`,
1274+
for an explanation of load balancing modes. Default value: "UTILIZATION" Possible values: ["UTILIZATION", "RATE", "CONNECTION", "CUSTOM_METRICS"]`,
12411275
Default: "UTILIZATION",
12421276
},
12431277
"capacity_scaler": {
@@ -1252,6 +1286,41 @@ setting of 0 means the group is completely drained, offering
12521286
0% of its available Capacity. Valid range is [0.0,1.0].`,
12531287
Default: 1.0,
12541288
},
1289+
"custom_metrics": {
1290+
Type: schema.TypeList,
1291+
Optional: true,
1292+
Description: `The set of custom metrics that are used for <code>CUSTOM_METRICS</code> BalancingMode.`,
1293+
Elem: &schema.Resource{
1294+
Schema: map[string]*schema.Schema{
1295+
"dry_run": {
1296+
Type: schema.TypeBool,
1297+
Required: true,
1298+
Description: `If true, the metric data is collected and reported to Cloud
1299+
Monitoring, but is not used for load balancing.`,
1300+
},
1301+
"name": {
1302+
Type: schema.TypeString,
1303+
Required: true,
1304+
Description: `Name of a custom utilization signal. The name must be 1-64 characters
1305+
long and match the regular expression [a-z]([-_.a-z0-9]*[a-z0-9])? which
1306+
means the first character must be a lowercase letter, and all following
1307+
characters must be a dash, period, underscore, lowercase letter, or
1308+
digit, except the last character, which cannot be a dash, period, or
1309+
underscore. For usage guidelines, see Custom Metrics balancing mode. This
1310+
field can only be used for a global or regional backend service with the
1311+
loadBalancingScheme set to <code>EXTERNAL_MANAGED</code>,
1312+
<code>INTERNAL_MANAGED</code> <code>INTERNAL_SELF_MANAGED</code>.`,
1313+
},
1314+
"max_utilization": {
1315+
Type: schema.TypeFloat,
1316+
Optional: true,
1317+
Description: `Optional parameter to define a target utilization for the Custom Metrics
1318+
balancing mode. The valid range is <code>[0.0, 1.0]</code>.`,
1319+
Default: 0.8,
1320+
},
1321+
},
1322+
},
1323+
},
12551324
"description": {
12561325
Type: schema.TypeString,
12571326
Optional: true,
@@ -1449,6 +1518,12 @@ func resourceComputeBackendServiceCreate(d *schema.ResourceData, meta interface{
14491518
} else if v, ok := d.GetOkExists("locality_lb_policies"); !tpgresource.IsEmptyValue(reflect.ValueOf(localityLbPoliciesProp)) && (ok || !reflect.DeepEqual(v, localityLbPoliciesProp)) {
14501519
obj["localityLbPolicies"] = localityLbPoliciesProp
14511520
}
1521+
customMetricsProp, err := expandComputeBackendServiceCustomMetrics(d.Get("custom_metrics"), d, config)
1522+
if err != nil {
1523+
return err
1524+
} else if v, ok := d.GetOkExists("custom_metrics"); !tpgresource.IsEmptyValue(reflect.ValueOf(customMetricsProp)) && (ok || !reflect.DeepEqual(v, customMetricsProp)) {
1525+
obj["customMetrics"] = customMetricsProp
1526+
}
14521527
nameProp, err := expandComputeBackendServiceName(d.Get("name"), d, config)
14531528
if err != nil {
14541529
return err
@@ -1748,6 +1823,9 @@ func resourceComputeBackendServiceRead(d *schema.ResourceData, meta interface{})
17481823
if err := d.Set("locality_lb_policies", flattenComputeBackendServiceLocalityLbPolicies(res["localityLbPolicies"], d, config)); err != nil {
17491824
return fmt.Errorf("Error reading BackendService: %s", err)
17501825
}
1826+
if err := d.Set("custom_metrics", flattenComputeBackendServiceCustomMetrics(res["customMetrics"], d, config)); err != nil {
1827+
return fmt.Errorf("Error reading BackendService: %s", err)
1828+
}
17511829
if err := d.Set("name", flattenComputeBackendServiceName(res["name"], d, config)); err != nil {
17521830
return fmt.Errorf("Error reading BackendService: %s", err)
17531831
}
@@ -1915,6 +1993,12 @@ func resourceComputeBackendServiceUpdate(d *schema.ResourceData, meta interface{
19151993
} else if v, ok := d.GetOkExists("locality_lb_policies"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, localityLbPoliciesProp)) {
19161994
obj["localityLbPolicies"] = localityLbPoliciesProp
19171995
}
1996+
customMetricsProp, err := expandComputeBackendServiceCustomMetrics(d.Get("custom_metrics"), d, config)
1997+
if err != nil {
1998+
return err
1999+
} else if v, ok := d.GetOkExists("custom_metrics"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, customMetricsProp)) {
2000+
obj["customMetrics"] = customMetricsProp
2001+
}
19182002
nameProp, err := expandComputeBackendServiceName(d.Get("name"), d, config)
19192003
if err != nil {
19202004
return err
@@ -2189,6 +2273,7 @@ func flattenComputeBackendServiceBackend(v interface{}, d *schema.ResourceData,
21892273
"max_rate_per_instance": flattenComputeBackendServiceBackendMaxRatePerInstance(original["maxRatePerInstance"], d, config),
21902274
"max_rate_per_endpoint": flattenComputeBackendServiceBackendMaxRatePerEndpoint(original["maxRatePerEndpoint"], d, config),
21912275
"max_utilization": flattenComputeBackendServiceBackendMaxUtilization(original["maxUtilization"], d, config),
2276+
"custom_metrics": flattenComputeBackendServiceBackendCustomMetrics(original["customMetrics"], d, config),
21922277
})
21932278
}
21942279
return transformed
@@ -2292,6 +2377,38 @@ func flattenComputeBackendServiceBackendMaxUtilization(v interface{}, d *schema.
22922377
return v
22932378
}
22942379

2380+
func flattenComputeBackendServiceBackendCustomMetrics(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
2381+
if v == nil {
2382+
return v
2383+
}
2384+
l := v.([]interface{})
2385+
transformed := make([]interface{}, 0, len(l))
2386+
for _, raw := range l {
2387+
original := raw.(map[string]interface{})
2388+
if len(original) < 1 {
2389+
// Do not include empty json objects coming back from the api
2390+
continue
2391+
}
2392+
transformed = append(transformed, map[string]interface{}{
2393+
"name": flattenComputeBackendServiceBackendCustomMetricsName(original["name"], d, config),
2394+
"dry_run": flattenComputeBackendServiceBackendCustomMetricsDryRun(original["dryRun"], d, config),
2395+
"max_utilization": flattenComputeBackendServiceBackendCustomMetricsMaxUtilization(original["maxUtilization"], d, config),
2396+
})
2397+
}
2398+
return transformed
2399+
}
2400+
func flattenComputeBackendServiceBackendCustomMetricsName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
2401+
return v
2402+
}
2403+
2404+
func flattenComputeBackendServiceBackendCustomMetricsDryRun(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
2405+
return v
2406+
}
2407+
2408+
func flattenComputeBackendServiceBackendCustomMetricsMaxUtilization(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
2409+
return v
2410+
}
2411+
22952412
func flattenComputeBackendServiceCircuitBreakers(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
22962413
if v == nil {
22972414
return nil
@@ -2962,6 +3079,33 @@ func flattenComputeBackendServiceLocalityLbPoliciesCustomPolicyData(v interface{
29623079
return v
29633080
}
29643081

3082+
func flattenComputeBackendServiceCustomMetrics(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
3083+
if v == nil {
3084+
return v
3085+
}
3086+
l := v.([]interface{})
3087+
transformed := make([]interface{}, 0, len(l))
3088+
for _, raw := range l {
3089+
original := raw.(map[string]interface{})
3090+
if len(original) < 1 {
3091+
// Do not include empty json objects coming back from the api
3092+
continue
3093+
}
3094+
transformed = append(transformed, map[string]interface{}{
3095+
"name": flattenComputeBackendServiceCustomMetricsName(original["name"], d, config),
3096+
"dry_run": flattenComputeBackendServiceCustomMetricsDryRun(original["dryRun"], d, config),
3097+
})
3098+
}
3099+
return transformed
3100+
}
3101+
func flattenComputeBackendServiceCustomMetricsName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
3102+
return v
3103+
}
3104+
3105+
func flattenComputeBackendServiceCustomMetricsDryRun(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
3106+
return v
3107+
}
3108+
29653109
func flattenComputeBackendServiceName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
29663110
return v
29673111
}
@@ -3543,6 +3687,13 @@ func expandComputeBackendServiceBackend(v interface{}, d tpgresource.TerraformRe
35433687
transformed["maxUtilization"] = transformedMaxUtilization
35443688
}
35453689

3690+
transformedCustomMetrics, err := expandComputeBackendServiceBackendCustomMetrics(original["custom_metrics"], d, config)
3691+
if err != nil {
3692+
return nil, err
3693+
} else if val := reflect.ValueOf(transformedCustomMetrics); val.IsValid() && !tpgresource.IsEmptyValue(val) {
3694+
transformed["customMetrics"] = transformedCustomMetrics
3695+
}
3696+
35463697
req = append(req, transformed)
35473698
}
35483699
return req, nil
@@ -3592,6 +3743,54 @@ func expandComputeBackendServiceBackendMaxUtilization(v interface{}, d tpgresour
35923743
return v, nil
35933744
}
35943745

3746+
func expandComputeBackendServiceBackendCustomMetrics(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
3747+
l := v.([]interface{})
3748+
req := make([]interface{}, 0, len(l))
3749+
for _, raw := range l {
3750+
if raw == nil {
3751+
continue
3752+
}
3753+
original := raw.(map[string]interface{})
3754+
transformed := make(map[string]interface{})
3755+
3756+
transformedName, err := expandComputeBackendServiceBackendCustomMetricsName(original["name"], d, config)
3757+
if err != nil {
3758+
return nil, err
3759+
} else if val := reflect.ValueOf(transformedName); val.IsValid() && !tpgresource.IsEmptyValue(val) {
3760+
transformed["name"] = transformedName
3761+
}
3762+
3763+
transformedDryRun, err := expandComputeBackendServiceBackendCustomMetricsDryRun(original["dry_run"], d, config)
3764+
if err != nil {
3765+
return nil, err
3766+
} else if val := reflect.ValueOf(transformedDryRun); val.IsValid() && !tpgresource.IsEmptyValue(val) {
3767+
transformed["dryRun"] = transformedDryRun
3768+
}
3769+
3770+
transformedMaxUtilization, err := expandComputeBackendServiceBackendCustomMetricsMaxUtilization(original["max_utilization"], d, config)
3771+
if err != nil {
3772+
return nil, err
3773+
} else if val := reflect.ValueOf(transformedMaxUtilization); val.IsValid() && !tpgresource.IsEmptyValue(val) {
3774+
transformed["maxUtilization"] = transformedMaxUtilization
3775+
}
3776+
3777+
req = append(req, transformed)
3778+
}
3779+
return req, nil
3780+
}
3781+
3782+
func expandComputeBackendServiceBackendCustomMetricsName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
3783+
return v, nil
3784+
}
3785+
3786+
func expandComputeBackendServiceBackendCustomMetricsDryRun(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
3787+
return v, nil
3788+
}
3789+
3790+
func expandComputeBackendServiceBackendCustomMetricsMaxUtilization(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
3791+
return v, nil
3792+
}
3793+
35953794
func expandComputeBackendServiceCircuitBreakers(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
35963795
l := v.([]interface{})
35973796
if len(l) == 0 || l[0] == nil {
@@ -4240,6 +4439,43 @@ func expandComputeBackendServiceLocalityLbPoliciesCustomPolicyData(v interface{}
42404439
return v, nil
42414440
}
42424441

4442+
func expandComputeBackendServiceCustomMetrics(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
4443+
l := v.([]interface{})
4444+
req := make([]interface{}, 0, len(l))
4445+
for _, raw := range l {
4446+
if raw == nil {
4447+
continue
4448+
}
4449+
original := raw.(map[string]interface{})
4450+
transformed := make(map[string]interface{})
4451+
4452+
transformedName, err := expandComputeBackendServiceCustomMetricsName(original["name"], d, config)
4453+
if err != nil {
4454+
return nil, err
4455+
} else if val := reflect.ValueOf(transformedName); val.IsValid() && !tpgresource.IsEmptyValue(val) {
4456+
transformed["name"] = transformedName
4457+
}
4458+
4459+
transformedDryRun, err := expandComputeBackendServiceCustomMetricsDryRun(original["dry_run"], d, config)
4460+
if err != nil {
4461+
return nil, err
4462+
} else if val := reflect.ValueOf(transformedDryRun); val.IsValid() && !tpgresource.IsEmptyValue(val) {
4463+
transformed["dryRun"] = transformedDryRun
4464+
}
4465+
4466+
req = append(req, transformed)
4467+
}
4468+
return req, nil
4469+
}
4470+
4471+
func expandComputeBackendServiceCustomMetricsName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
4472+
return v, nil
4473+
}
4474+
4475+
func expandComputeBackendServiceCustomMetricsDryRun(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
4476+
return v, nil
4477+
}
4478+
42434479
func expandComputeBackendServiceName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
42444480
return v, nil
42454481
}

google/services/compute/resource_compute_backend_service_generated_meta.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ fields:
1010
api_field: 'backends.balancing_mode'
1111
- field: 'backend.capacity_scaler'
1212
api_field: 'backends.capacity_scaler'
13+
- field: 'backend.custom_metrics.dry_run'
14+
api_field: 'backends.custom_metrics.dry_run'
15+
- field: 'backend.custom_metrics.max_utilization'
16+
api_field: 'backends.custom_metrics.max_utilization'
17+
- field: 'backend.custom_metrics.name'
18+
api_field: 'backends.custom_metrics.name'
1319
- field: 'backend.description'
1420
api_field: 'backends.description'
1521
- field: 'backend.group'
@@ -60,6 +66,8 @@ fields:
6066
- field: 'consistent_hash.http_header_name'
6167
- field: 'consistent_hash.minimum_ring_size'
6268
- field: 'creation_timestamp'
69+
- field: 'custom_metrics.dry_run'
70+
- field: 'custom_metrics.name'
6371
- field: 'custom_request_headers'
6472
- field: 'custom_response_headers'
6573
- field: 'description'

0 commit comments

Comments
 (0)