Skip to content

Commit 59d4572

Browse files
Add HA Policy to Regional Backend Services (#14522) (#23905)
[upstream:0692e14d57fe7513a9b872f3a6bc4fef880992bb] Signed-off-by: Modular Magician <[email protected]>
1 parent ac056ac commit 59d4572

6 files changed

+809
-0
lines changed

.changelog/14522.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
compute: added `ha_policy` field to `google_compute_region_backend_service` resource
3+
```

google/services/compute/resource_compute_region_backend_service.go

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,78 @@ This field is only used with l4 load balancing.`,
570570
},
571571
},
572572
},
573+
"ha_policy": {
574+
Type: schema.TypeList,
575+
Optional: true,
576+
Description: `Configures self-managed High Availability (HA) for External and Internal Protocol Forwarding.
577+
The backends of this regional backend service must only specify zonal network endpoint groups
578+
(NEGs) of type GCE_VM_IP. Note that haPolicy is not for load balancing, and therefore cannot
579+
be specified with sessionAffinity, connectionTrackingPolicy, and failoverPolicy. haPolicy
580+
requires customers to be responsible for tracking backend endpoint health and electing a
581+
leader among the healthy endpoints. Therefore, haPolicy cannot be specified with healthChecks.
582+
haPolicy can only be specified for External Passthrough Network Load Balancers and Internal
583+
Passthrough Network Load Balancers.`,
584+
MaxItems: 1,
585+
Elem: &schema.Resource{
586+
Schema: map[string]*schema.Schema{
587+
"fast_ip_move": {
588+
Type: schema.TypeString,
589+
Optional: true,
590+
ForceNew: true,
591+
ValidateFunc: verify.ValidateEnum([]string{"DISABLED", "GARP_RA", ""}),
592+
Description: `Specifies whether fast IP move is enabled, and if so, the mechanism to achieve it.
593+
Supported values are:
594+
595+
* 'DISABLED': Fast IP Move is disabled. You can only use the haPolicy.leader API to
596+
update the leader.
597+
598+
* 'GARP_RA': Provides a method to very quickly define a new network endpoint as the
599+
leader. This method is faster than updating the leader using the
600+
haPolicy.leader API. Fast IP move works as follows: The VM hosting the
601+
network endpoint that should become the new leader sends either a
602+
Gratuitous ARP (GARP) packet (IPv4) or an ICMPv6 Router Advertisement(RA)
603+
packet (IPv6). Google Cloud immediately but temporarily associates the
604+
forwarding rule IP address with that VM, and both new and in-flight packets
605+
are quickly delivered to that VM. Possible values: ["DISABLED", "GARP_RA"]`,
606+
},
607+
"leader": {
608+
Type: schema.TypeList,
609+
Optional: true,
610+
Description: `Selects one of the network endpoints attached to the backend NEGs of this service as the
611+
active endpoint (the leader) that receives all traffic.`,
612+
MaxItems: 1,
613+
Elem: &schema.Resource{
614+
Schema: map[string]*schema.Schema{
615+
"backend_group": {
616+
Type: schema.TypeString,
617+
Optional: true,
618+
DiffSuppressFunc: tpgresource.CompareSelfLinkOrResourceName,
619+
Description: `A fully-qualified URL of the zonal Network Endpoint Group (NEG) that the leader is
620+
attached to.`,
621+
},
622+
"network_endpoint": {
623+
Type: schema.TypeList,
624+
Optional: true,
625+
Description: `The network endpoint within the leader.backendGroup that is designated as the leader.`,
626+
MaxItems: 1,
627+
Elem: &schema.Resource{
628+
Schema: map[string]*schema.Schema{
629+
"instance": {
630+
Type: schema.TypeString,
631+
Optional: true,
632+
Description: `The name of the VM instance of the leader network endpoint. The instance must
633+
already be attached to the NEG specified in the haPolicy.leader.backendGroup.`,
634+
},
635+
},
636+
},
637+
},
638+
},
639+
},
640+
},
641+
},
642+
},
643+
ConflictsWith: []string{"session_affinity", "failover_policy", "health_checks"},
644+
},
573645
"health_checks": {
574646
Type: schema.TypeSet,
575647
Optional: true,
@@ -1357,6 +1429,12 @@ func resourceComputeRegionBackendServiceCreate(d *schema.ResourceData, meta inte
13571429
} else if v, ok := d.GetOkExists("network"); !tpgresource.IsEmptyValue(reflect.ValueOf(networkProp)) && (ok || !reflect.DeepEqual(v, networkProp)) {
13581430
obj["network"] = networkProp
13591431
}
1432+
haPolicyProp, err := expandComputeRegionBackendServiceHaPolicy(d.Get("ha_policy"), d, config)
1433+
if err != nil {
1434+
return err
1435+
} else if v, ok := d.GetOkExists("ha_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(haPolicyProp)) && (ok || !reflect.DeepEqual(v, haPolicyProp)) {
1436+
obj["haPolicy"] = haPolicyProp
1437+
}
13601438
regionProp, err := expandComputeRegionBackendServiceRegion(d.Get("region"), d, config)
13611439
if err != nil {
13621440
return err
@@ -1572,6 +1650,9 @@ func resourceComputeRegionBackendServiceRead(d *schema.ResourceData, meta interf
15721650
if err := d.Set("network", flattenComputeRegionBackendServiceNetwork(res["network"], d, config)); err != nil {
15731651
return fmt.Errorf("Error reading RegionBackendService: %s", err)
15741652
}
1653+
if err := d.Set("ha_policy", flattenComputeRegionBackendServiceHaPolicy(res["haPolicy"], d, config)); err != nil {
1654+
return fmt.Errorf("Error reading RegionBackendService: %s", err)
1655+
}
15751656
if err := d.Set("region", flattenComputeRegionBackendServiceRegion(res["region"], d, config)); err != nil {
15761657
return fmt.Errorf("Error reading RegionBackendService: %s", err)
15771658
}
@@ -1748,6 +1829,12 @@ func resourceComputeRegionBackendServiceUpdate(d *schema.ResourceData, meta inte
17481829
} else if v, ok := d.GetOkExists("network"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, networkProp)) {
17491830
obj["network"] = networkProp
17501831
}
1832+
haPolicyProp, err := expandComputeRegionBackendServiceHaPolicy(d.Get("ha_policy"), d, config)
1833+
if err != nil {
1834+
return err
1835+
} else if v, ok := d.GetOkExists("ha_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, haPolicyProp)) {
1836+
obj["haPolicy"] = haPolicyProp
1837+
}
17511838
regionProp, err := expandComputeRegionBackendServiceRegion(d.Get("region"), d, config)
17521839
if err != nil {
17531840
return err
@@ -3094,6 +3181,64 @@ func flattenComputeRegionBackendServiceNetwork(v interface{}, d *schema.Resource
30943181
return tpgresource.ConvertSelfLinkToV1(v.(string))
30953182
}
30963183

3184+
func flattenComputeRegionBackendServiceHaPolicy(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
3185+
if v == nil {
3186+
return nil
3187+
}
3188+
original := v.(map[string]interface{})
3189+
if len(original) == 0 {
3190+
return nil
3191+
}
3192+
transformed := make(map[string]interface{})
3193+
transformed["fast_ip_move"] =
3194+
flattenComputeRegionBackendServiceHaPolicyFastIPMove(original["fastIPMove"], d, config)
3195+
transformed["leader"] =
3196+
flattenComputeRegionBackendServiceHaPolicyLeader(original["leader"], d, config)
3197+
return []interface{}{transformed}
3198+
}
3199+
func flattenComputeRegionBackendServiceHaPolicyFastIPMove(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
3200+
return v
3201+
}
3202+
3203+
func flattenComputeRegionBackendServiceHaPolicyLeader(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
3204+
if v == nil {
3205+
return nil
3206+
}
3207+
original := v.(map[string]interface{})
3208+
if len(original) == 0 {
3209+
return nil
3210+
}
3211+
transformed := make(map[string]interface{})
3212+
transformed["backend_group"] =
3213+
flattenComputeRegionBackendServiceHaPolicyLeaderBackendGroup(original["backendGroup"], d, config)
3214+
transformed["network_endpoint"] =
3215+
flattenComputeRegionBackendServiceHaPolicyLeaderNetworkEndpoint(original["networkEndpoint"], d, config)
3216+
return []interface{}{transformed}
3217+
}
3218+
func flattenComputeRegionBackendServiceHaPolicyLeaderBackendGroup(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
3219+
if v == nil {
3220+
return v
3221+
}
3222+
return tpgresource.ConvertSelfLinkToV1(v.(string))
3223+
}
3224+
3225+
func flattenComputeRegionBackendServiceHaPolicyLeaderNetworkEndpoint(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
3226+
if v == nil {
3227+
return nil
3228+
}
3229+
original := v.(map[string]interface{})
3230+
if len(original) == 0 {
3231+
return nil
3232+
}
3233+
transformed := make(map[string]interface{})
3234+
transformed["instance"] =
3235+
flattenComputeRegionBackendServiceHaPolicyLeaderNetworkEndpointInstance(original["instance"], d, config)
3236+
return []interface{}{transformed}
3237+
}
3238+
func flattenComputeRegionBackendServiceHaPolicyLeaderNetworkEndpointInstance(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
3239+
return v
3240+
}
3241+
30973242
func flattenComputeRegionBackendServiceRegion(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
30983243
if v == nil {
30993244
return v
@@ -4235,6 +4380,89 @@ func expandComputeRegionBackendServiceNetwork(v interface{}, d tpgresource.Terra
42354380
return f.RelativeLink(), nil
42364381
}
42374382

4383+
func expandComputeRegionBackendServiceHaPolicy(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
4384+
l := v.([]interface{})
4385+
if len(l) == 0 || l[0] == nil {
4386+
return nil, nil
4387+
}
4388+
raw := l[0]
4389+
original := raw.(map[string]interface{})
4390+
transformed := make(map[string]interface{})
4391+
4392+
transformedFastIPMove, err := expandComputeRegionBackendServiceHaPolicyFastIPMove(original["fast_ip_move"], d, config)
4393+
if err != nil {
4394+
return nil, err
4395+
} else if val := reflect.ValueOf(transformedFastIPMove); val.IsValid() && !tpgresource.IsEmptyValue(val) {
4396+
transformed["fastIPMove"] = transformedFastIPMove
4397+
}
4398+
4399+
transformedLeader, err := expandComputeRegionBackendServiceHaPolicyLeader(original["leader"], d, config)
4400+
if err != nil {
4401+
return nil, err
4402+
} else if val := reflect.ValueOf(transformedLeader); val.IsValid() && !tpgresource.IsEmptyValue(val) {
4403+
transformed["leader"] = transformedLeader
4404+
}
4405+
4406+
return transformed, nil
4407+
}
4408+
4409+
func expandComputeRegionBackendServiceHaPolicyFastIPMove(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
4410+
return v, nil
4411+
}
4412+
4413+
func expandComputeRegionBackendServiceHaPolicyLeader(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
4414+
l := v.([]interface{})
4415+
if len(l) == 0 || l[0] == nil {
4416+
return nil, nil
4417+
}
4418+
raw := l[0]
4419+
original := raw.(map[string]interface{})
4420+
transformed := make(map[string]interface{})
4421+
4422+
transformedBackendGroup, err := expandComputeRegionBackendServiceHaPolicyLeaderBackendGroup(original["backend_group"], d, config)
4423+
if err != nil {
4424+
return nil, err
4425+
} else if val := reflect.ValueOf(transformedBackendGroup); val.IsValid() && !tpgresource.IsEmptyValue(val) {
4426+
transformed["backendGroup"] = transformedBackendGroup
4427+
}
4428+
4429+
transformedNetworkEndpoint, err := expandComputeRegionBackendServiceHaPolicyLeaderNetworkEndpoint(original["network_endpoint"], d, config)
4430+
if err != nil {
4431+
return nil, err
4432+
} else if val := reflect.ValueOf(transformedNetworkEndpoint); val.IsValid() && !tpgresource.IsEmptyValue(val) {
4433+
transformed["networkEndpoint"] = transformedNetworkEndpoint
4434+
}
4435+
4436+
return transformed, nil
4437+
}
4438+
4439+
func expandComputeRegionBackendServiceHaPolicyLeaderBackendGroup(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
4440+
return v, nil
4441+
}
4442+
4443+
func expandComputeRegionBackendServiceHaPolicyLeaderNetworkEndpoint(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
4444+
l := v.([]interface{})
4445+
if len(l) == 0 || l[0] == nil {
4446+
return nil, nil
4447+
}
4448+
raw := l[0]
4449+
original := raw.(map[string]interface{})
4450+
transformed := make(map[string]interface{})
4451+
4452+
transformedInstance, err := expandComputeRegionBackendServiceHaPolicyLeaderNetworkEndpointInstance(original["instance"], d, config)
4453+
if err != nil {
4454+
return nil, err
4455+
} else if val := reflect.ValueOf(transformedInstance); val.IsValid() && !tpgresource.IsEmptyValue(val) {
4456+
transformed["instance"] = transformedInstance
4457+
}
4458+
4459+
return transformed, nil
4460+
}
4461+
4462+
func expandComputeRegionBackendServiceHaPolicyLeaderNetworkEndpointInstance(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
4463+
return v, nil
4464+
}
4465+
42384466
func expandComputeRegionBackendServiceRegion(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
42394467
f, err := tpgresource.ParseGlobalFieldValue("regions", v.(string), "project", d, config, true)
42404468
if err != nil {

google/services/compute/resource_compute_region_backend_service_generated_meta.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ fields:
7474
- field: 'fingerprint'
7575
- field: 'generated_id'
7676
api_field: 'id'
77+
- field: 'ha_policy.fast_ip_move'
78+
- field: 'ha_policy.leader.backend_group'
79+
- field: 'ha_policy.leader.network_endpoint.instance'
7780
- field: 'health_checks'
7881
- field: 'iap.enabled'
7982
- field: 'iap.oauth2_client_id'

0 commit comments

Comments
 (0)