Skip to content

Commit 90d849e

Browse files
Add NON_GCP_PRIVATE_IP_PORT as networkEndpointType for NetworkEndpointGroup (#5684) (#4068)
* Add NON_GCP_PRIVATE_IP_PORT as networkEndpointType for NetworkEndpointGroup * Fix the Network Endpoint Group non-GCP example * Make networkEndpoint instance optional, handle, and add example * Put the hybrid endpoint in the hybrid NEG Signed-off-by: Modular Magician <[email protected]>
1 parent 400b365 commit 90d849e

8 files changed

+370
-25
lines changed

.changelog/5684.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
```release-note:enhancement
2+
compute: add `NON_GCP_PRIVATE_IP_PORT` value for `network_endpoint_type` in the `google_compute_network_endpoint_group` resource
3+
```
4+
```release-note:enhancement
5+
compute: Update `instance` attribute for `google_compute_network_endpoint` to be optional, as Hybrid connectivity NEGs use network endpoints with just IP and Port.
6+
```

google-beta/resource_compute_global_forwarding_rule_generated_test.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,141 @@ resource "google_compute_backend_service" "default" {
667667
`, context)
668668
}
669669

670+
func TestAccComputeGlobalForwardingRule_globalForwardingRuleHybridExample(t *testing.T) {
671+
t.Parallel()
672+
673+
context := map[string]interface{}{
674+
"random_suffix": randString(t, 10),
675+
}
676+
677+
vcrTest(t, resource.TestCase{
678+
PreCheck: func() { testAccPreCheck(t) },
679+
Providers: testAccProviders,
680+
CheckDestroy: testAccCheckComputeGlobalForwardingRuleDestroyProducer(t),
681+
Steps: []resource.TestStep{
682+
{
683+
Config: testAccComputeGlobalForwardingRule_globalForwardingRuleHybridExample(context),
684+
},
685+
{
686+
ResourceName: "google_compute_global_forwarding_rule.default",
687+
ImportState: true,
688+
ImportStateVerify: true,
689+
ImportStateVerifyIgnore: []string{"network", "port_range", "target"},
690+
},
691+
},
692+
})
693+
}
694+
695+
func testAccComputeGlobalForwardingRule_globalForwardingRuleHybridExample(context map[string]interface{}) string {
696+
return Nprintf(`
697+
// Roughly mirrors https://cloud.google.com/load-balancing/docs/https/setting-up-ext-https-hybrid
698+
699+
resource "google_compute_network" "default" {
700+
name = "tf-test-my-network%{random_suffix}"
701+
}
702+
703+
// Zonal NEG with GCE_VM_IP_PORT
704+
resource "google_compute_network_endpoint_group" "default" {
705+
name = "tf-test-default-neg%{random_suffix}"
706+
network = google_compute_network.default.id
707+
default_port = "90"
708+
zone = "us-central1-a"
709+
network_endpoint_type = "GCE_VM_IP_PORT"
710+
}
711+
712+
// Hybrid connectivity NEG
713+
resource "google_compute_network_endpoint_group" "hybrid" {
714+
name = "tf-test-hybrid-neg%{random_suffix}"
715+
network = google_compute_network.default.id
716+
default_port = "90"
717+
zone = "us-central1-a"
718+
network_endpoint_type = "NON_GCP_PRIVATE_IP_PORT"
719+
}
720+
721+
resource "google_compute_network_endpoint" "hybrid-endpoint" {
722+
network_endpoint_group = google_compute_network_endpoint_group.hybrid.name
723+
port = google_compute_network_endpoint_group.hybrid.default_port
724+
ip_address = "127.0.0.1"
725+
}
726+
727+
// Backend service for Zonal NEG
728+
resource "google_compute_backend_service" "default" {
729+
name = "tf-test-backend-default%{random_suffix}"
730+
port_name = "http"
731+
protocol = "HTTP"
732+
timeout_sec = 10
733+
backend {
734+
group = google_compute_network_endpoint_group.default.id
735+
balancing_mode = "RATE"
736+
max_rate_per_endpoint = 10
737+
}
738+
health_checks = [google_compute_health_check.default.id]
739+
}
740+
741+
// Backgend service for Hybrid NEG
742+
resource "google_compute_backend_service" "hybrid" {
743+
name = "tf-test-backend-hybrid%{random_suffix}"
744+
port_name = "http"
745+
protocol = "HTTP"
746+
timeout_sec = 10
747+
backend {
748+
group = google_compute_network_endpoint_group.hybrid.id
749+
balancing_mode = "RATE"
750+
max_rate_per_endpoint = 10
751+
}
752+
health_checks = [google_compute_health_check.default.id]
753+
}
754+
755+
resource "google_compute_health_check" "default" {
756+
name = "tf-test-health-check%{random_suffix}"
757+
timeout_sec = 1
758+
check_interval_sec = 1
759+
760+
tcp_health_check {
761+
port = "80"
762+
}
763+
}
764+
765+
resource "google_compute_url_map" "default" {
766+
name = "url-map-tf-test-target-proxy%{random_suffix}"
767+
description = "a description"
768+
default_service = google_compute_backend_service.default.id
769+
770+
host_rule {
771+
hosts = ["mysite.com"]
772+
path_matcher = "allpaths"
773+
}
774+
775+
path_matcher {
776+
name = "allpaths"
777+
default_service = google_compute_backend_service.default.id
778+
779+
path_rule {
780+
paths = ["/*"]
781+
service = google_compute_backend_service.default.id
782+
}
783+
784+
path_rule {
785+
paths = ["/hybrid"]
786+
service = google_compute_backend_service.hybrid.id
787+
}
788+
}
789+
}
790+
791+
resource "google_compute_target_http_proxy" "default" {
792+
name = "tf-test-target-proxy%{random_suffix}"
793+
description = "a description"
794+
url_map = google_compute_url_map.default.id
795+
}
796+
797+
resource "google_compute_global_forwarding_rule" "default" {
798+
name = "tf-test-global-rule%{random_suffix}"
799+
target = google_compute_target_http_proxy.default.id
800+
port_range = "80"
801+
}
802+
`, context)
803+
}
804+
670805
func TestAccComputeGlobalForwardingRule_privateServiceConnectGoogleApisExample(t *testing.T) {
671806
t.Parallel()
672807

google-beta/resource_compute_network_endpoint.go

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,6 @@ func resourceComputeNetworkEndpoint() *schema.Resource {
3939
},
4040

4141
Schema: map[string]*schema.Schema{
42-
"instance": {
43-
Type: schema.TypeString,
44-
Required: true,
45-
ForceNew: true,
46-
DiffSuppressFunc: compareSelfLinkOrResourceName,
47-
Description: `The name for a specific VM instance that the IP address belongs to.
48-
This is required for network endpoints of type GCE_VM_IP_PORT.
49-
The instance must be in the same zone of network endpoint group.`,
50-
},
5142
"ip_address": {
5243
Type: schema.TypeString,
5344
Required: true,
@@ -69,6 +60,15 @@ range).`,
6960
ForceNew: true,
7061
Description: `Port number of network endpoint.`,
7162
},
63+
"instance": {
64+
Type: schema.TypeString,
65+
Optional: true,
66+
ForceNew: true,
67+
DiffSuppressFunc: compareSelfLinkOrResourceName,
68+
Description: `The name for a specific VM instance that the IP address belongs to.
69+
This is required for network endpoints of type GCE_VM_IP_PORT.
70+
The instance must be in the same zone of network endpoint group.`,
71+
},
7272
"zone": {
7373
Type: schema.TypeString,
7474
Computed: true,
@@ -277,7 +277,9 @@ func resourceComputeNetworkEndpointDelete(d *schema.ResourceData, meta interface
277277
if err != nil {
278278
return err
279279
}
280-
toDelete["instance"] = instanceProp
280+
if instanceProp != "" {
281+
toDelete["instance"] = instanceProp
282+
}
281283

282284
portProp, err := expandNestedComputeNetworkEndpointPort(d.Get("port"), d, config)
283285
if err != nil {
@@ -320,11 +322,12 @@ func resourceComputeNetworkEndpointDelete(d *schema.ResourceData, meta interface
320322

321323
func resourceComputeNetworkEndpointImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
322324
config := meta.(*Config)
325+
// instance is optional, so use * instead of + when reading the import id
323326
if err := parseImportId([]string{
324-
"projects/(?P<project>[^/]+)/zones/(?P<zone>[^/]+)/networkEndpointGroups/(?P<network_endpoint_group>[^/]+)/(?P<instance>[^/]+)/(?P<ip_address>[^/]+)/(?P<port>[^/]+)",
325-
"(?P<project>[^/]+)/(?P<zone>[^/]+)/(?P<network_endpoint_group>[^/]+)/(?P<instance>[^/]+)/(?P<ip_address>[^/]+)/(?P<port>[^/]+)",
326-
"(?P<zone>[^/]+)/(?P<network_endpoint_group>[^/]+)/(?P<instance>[^/]+)/(?P<ip_address>[^/]+)/(?P<port>[^/]+)",
327-
"(?P<network_endpoint_group>[^/]+)/(?P<instance>[^/]+)/(?P<ip_address>[^/]+)/(?P<port>[^/]+)",
327+
"projects/(?P<project>[^/]+)/zones/(?P<zone>[^/]+)/networkEndpointGroups/(?P<network_endpoint_group>[^/]+)/(?P<instance>[^/]*)/(?P<ip_address>[^/]+)/(?P<port>[^/]+)",
328+
"(?P<project>[^/]+)/(?P<zone>[^/]+)/(?P<network_endpoint_group>[^/]+)/(?P<instance>[^/]*)/(?P<ip_address>[^/]+)/(?P<port>[^/]+)",
329+
"(?P<zone>[^/]+)/(?P<network_endpoint_group>[^/]+)/(?P<instance>[^/]*)/(?P<ip_address>[^/]+)/(?P<port>[^/]+)",
330+
"(?P<network_endpoint_group>[^/]+)/(?P<instance>[^/]*)/(?P<ip_address>[^/]+)/(?P<port>[^/]+)",
328331
}, d, config); err != nil {
329332
return nil, err
330333
}

google-beta/resource_compute_network_endpoint_group.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,15 @@ you create the resource.`,
7878
Type: schema.TypeString,
7979
Optional: true,
8080
ForceNew: true,
81-
ValidateFunc: validateEnum([]string{"GCE_VM_IP_PORT", ""}),
82-
Description: `Type of network endpoints in this network endpoint group. Default value: "GCE_VM_IP_PORT" Possible values: ["GCE_VM_IP_PORT"]`,
83-
Default: "GCE_VM_IP_PORT",
81+
ValidateFunc: validateEnum([]string{"GCE_VM_IP_PORT", "NON_GCP_PRIVATE_IP_PORT", ""}),
82+
Description: `Type of network endpoints in this network endpoint group.
83+
NON_GCP_PRIVATE_IP_PORT is used for hybrid connectivity network
84+
endpoint groups (see https://cloud.google.com/load-balancing/docs/hybrid).
85+
Note that NON_GCP_PRIVATE_IP_PORT can only be used with Backend Services
86+
that 1) have the following load balancing schemes: EXTERNAL, EXTERNAL_MANAGED,
87+
INTERNAL_MANAGED, and INTERNAL_SELF_MANAGED and 2) support the RATE or
88+
CONNECTION balancing modes. Default value: "GCE_VM_IP_PORT" Possible values: ["GCE_VM_IP_PORT", "NON_GCP_PRIVATE_IP_PORT"]`,
89+
Default: "GCE_VM_IP_PORT",
8490
},
8591
"subnetwork": {
8692
Type: schema.TypeString,

google-beta/resource_compute_network_endpoint_group_generated_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,53 @@ resource "google_compute_subnetwork" "default" {
7272
`, context)
7373
}
7474

75+
func TestAccComputeNetworkEndpointGroup_networkEndpointGroupNonGcpExample(t *testing.T) {
76+
t.Parallel()
77+
78+
context := map[string]interface{}{
79+
"random_suffix": randString(t, 10),
80+
}
81+
82+
vcrTest(t, resource.TestCase{
83+
PreCheck: func() { testAccPreCheck(t) },
84+
Providers: testAccProviders,
85+
CheckDestroy: testAccCheckComputeNetworkEndpointGroupDestroyProducer(t),
86+
Steps: []resource.TestStep{
87+
{
88+
Config: testAccComputeNetworkEndpointGroup_networkEndpointGroupNonGcpExample(context),
89+
},
90+
{
91+
ResourceName: "google_compute_network_endpoint_group.neg",
92+
ImportState: true,
93+
ImportStateVerify: true,
94+
ImportStateVerifyIgnore: []string{"network", "subnetwork", "zone"},
95+
},
96+
},
97+
})
98+
}
99+
100+
func testAccComputeNetworkEndpointGroup_networkEndpointGroupNonGcpExample(context map[string]interface{}) string {
101+
return Nprintf(`
102+
resource "google_compute_network_endpoint_group" "neg" {
103+
name = "tf-test-my-lb-neg%{random_suffix}"
104+
network = google_compute_network.default.id
105+
default_port = "90"
106+
zone = "us-central1-a"
107+
network_endpoint_type = "NON_GCP_PRIVATE_IP_PORT"
108+
}
109+
110+
resource "google_compute_network_endpoint" "default-endpoint" {
111+
network_endpoint_group = google_compute_network_endpoint_group.neg.name
112+
port = google_compute_network_endpoint_group.neg.default_port
113+
ip_address = "127.0.0.1"
114+
}
115+
116+
resource "google_compute_network" "default" {
117+
name = "tf-test-neg-network%{random_suffix}"
118+
}
119+
`, context)
120+
}
121+
75122
func testAccCheckComputeNetworkEndpointGroupDestroyProducer(t *testing.T) func(s *terraform.State) error {
76123
return func(s *terraform.State) error {
77124
for name, rs := range s.RootModule().Resources {

0 commit comments

Comments
 (0)