-
Notifications
You must be signed in to change notification settings - Fork 9.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
providers/google: Add support for Internal Load Balancing #10453
Conversation
@danawillow: Looks like it needs to be rebased on master, due to vendor updates :) |
852d003
to
093f20b
Compare
… it can only be INTERNAL
093f20b
to
2009d6a
Compare
All right, now it's ready. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi! Thanks for the PR! It brings a lot of good stuff, and it's really exciting to be able to add all this to Terraform! My apologies for taking so long to get to it--it's been hard finding a large enough chunk of time for it. I think smaller PRs are easier to review, but sometimes they don't split up easily, so it's always a judgement call. :)
Anyways this looks great! There were a few things I noted, hopefully not too nitpicky, that I could totally be wrong about. But I just wanted to draw your attention to them.
Thanks!
@@ -93,13 +127,24 @@ func resourceComputeForwardingRuleCreate(d *schema.ResourceData, meta interface{ | |||
return err | |||
} | |||
|
|||
ps := d.Get("ports").(*schema.Set).List() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an optional attribute. What if it's not specified--wouldn't this panic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't look like it does- the tests that don't set ports still pass, like https://github.com/danawillow/terraform/blob/2009d6a1357fe16b1f98e3a652fd13631242ac5b/builtin/providers/google/resource_compute_forwarding_rule_test.go#L119.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're totally right, and I learned some new stuff about *ResourceData.Get
and *schema.Set.List
today. Thanks!
Name: d.Get("name").(string), | ||
PortRange: d.Get("port_range").(string), | ||
Target: d.Get("target").(string), | ||
BackendService: d.Get("backend_service").(string), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here--isn't this nil if it's not set? It's an optional attribute, I think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only required attribute in the whole list is Name, so it seems there's a precedent for doing it this way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're totally right, I misunderstood the situations in which d.Get
would return nil. Whoops! Thanks for correcting me. :D
Description: d.Get("description").(string), | ||
LoadBalancingScheme: d.Get("load_balancing_scheme").(string), | ||
Name: d.Get("name").(string), | ||
Network: d.Get("network").(string), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same, what if this isn't set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likewise
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, you're totally right on this.
PortRange: d.Get("port_range").(string), | ||
Ports: ports, | ||
Subnetwork: d.Get("subnetwork").(string), | ||
Target: d.Get("target").(string), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if this isn't set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likewise
Network: d.Get("network").(string), | ||
PortRange: d.Get("port_range").(string), | ||
Ports: ports, | ||
Subnetwork: d.Get("subnetwork").(string), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if this isn't set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likewise
}, | ||
}, | ||
|
||
"https_health_check": &schema.Schema{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming nit: do we really need _health_check
. as a suffix to all of these, inside of the health_check
resource?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the name in the GCP resource (https://cloud.google.com/compute/docs/reference/latest/healthChecks), but I don't mind changing it. I don't think just calling it http or https is a good naming choice though, since to me that feels more like a boolean. it could be http_details, but then it's not much shorter than the current version. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, these are some good points. My instincts are based on the Go philosophy of not repeating things, but that may be a bad instinct here. Looking at what the aws_route53_health_check
resource does (as a close equivalent), it uses a single property for all its health checks, and uses "type" to distinguish them, as you previously had. Though that seems to be a reflection of the underlying API.
Thinking this through, I think you're right. It's probably better to stick closer to the API than to try to abstract the repetition out. Good call. :)
if hchk.Type != "HTTP" { | ||
return fmt.Errorf("HTTP health check declared but type is listed as %s", hchk.Type) | ||
} | ||
httpcheck := v.([]interface{})[0].(map[string]interface{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may prevent a future crash to check that
v.([]interface{})
has at least one item- that item isn't nil
before we try to cast it to a map[string]interface{}
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't totally understand this comment, can you give me an example configuration that could cause this issue?
if hchk.Type != "TCP" { | ||
return fmt.Errorf("TCP health check declared but type is listed as %s", hchk.Type) | ||
} | ||
tcpcheck := v.([]interface{})[0].(map[string]interface{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing in update as in create, re: potentially preventing crashes down the road.
_, err := config.clientCompute.HealthChecks.Get( | ||
config.Project, rs.Primary.ID).Do() | ||
if err == nil { | ||
return fmt.Errorf("HealthCheck still exists") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be nice to log the ID of the health check that still exists, to make manual clean-up and debugging easier. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
# google\_compute\_region\_backend\_service | ||
|
||
A Region Backend Service defines a regionally-scoped group of virtual machines that will serve traffic for load balancing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A link to the docs would be awesome here!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review!
@@ -93,13 +127,24 @@ func resourceComputeForwardingRuleCreate(d *schema.ResourceData, meta interface{ | |||
return err | |||
} | |||
|
|||
ps := d.Get("ports").(*schema.Set).List() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't look like it does- the tests that don't set ports still pass, like https://github.com/danawillow/terraform/blob/2009d6a1357fe16b1f98e3a652fd13631242ac5b/builtin/providers/google/resource_compute_forwarding_rule_test.go#L119.
Name: d.Get("name").(string), | ||
PortRange: d.Get("port_range").(string), | ||
Target: d.Get("target").(string), | ||
BackendService: d.Get("backend_service").(string), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only required attribute in the whole list is Name, so it seems there's a precedent for doing it this way.
Network: d.Get("network").(string), | ||
PortRange: d.Get("port_range").(string), | ||
Ports: ports, | ||
Subnetwork: d.Get("subnetwork").(string), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likewise
PortRange: d.Get("port_range").(string), | ||
Ports: ports, | ||
Subnetwork: d.Get("subnetwork").(string), | ||
Target: d.Get("target").(string), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likewise
_, err := config.clientCompute.HealthChecks.Get( | ||
config.Project, rs.Primary.ID).Do() | ||
if err == nil { | ||
return fmt.Errorf("HealthCheck still exists") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
# google\_compute\_region\_backend\_service | ||
|
||
A Region Backend Service defines a regionally-scoped group of virtual machines that will serve traffic for load balancing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Description: d.Get("description").(string), | ||
LoadBalancingScheme: d.Get("load_balancing_scheme").(string), | ||
Name: d.Get("name").(string), | ||
Network: d.Get("network").(string), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likewise
}, | ||
}, | ||
|
||
"https_health_check": &schema.Schema{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the name in the GCP resource (https://cloud.google.com/compute/docs/reference/latest/healthChecks), but I don't mind changing it. I don't think just calling it http or https is a good naming choice though, since to me that feels more like a boolean. it could be http_details, but then it's not much shorter than the current version. What do you think?
} | ||
if v, ok := d.GetOk("tcp_health_check"); ok { | ||
if hchk.Type != "TCP" { | ||
return fmt.Errorf("TCP health check declared but type is listed as %s", hchk.Type) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh neat, great idea! Done.
if hchk.Type != "HTTP" { | ||
return fmt.Errorf("HTTP health check declared but type is listed as %s", hchk.Type) | ||
} | ||
httpcheck := v.([]interface{})[0].(map[string]interface{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't totally understand this comment, can you give me an example configuration that could cause this issue?
|
||
## Example Usage | ||
|
||
```js |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use tf
here (I was surprised, too!):
resource "google_compute_health_check" "default" {
name = "test"
}
I won't comment on all the others, but they can all be updated :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
timeout_sec = 1 | ||
check_interval_sec = 1 | ||
type = "TCP" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that this isn't a thing, we should remove it from the example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
* `timeout_sec` - (Optional) The number of seconds to wait before declaring | ||
failure (default 5). | ||
|
||
* `type` - (Optional) The type of HealthCheck, either TCP, SSL, HTTP or HTTPS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably remove this, as it no longer exists. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, good call. Done.
Thanks for all the changes and comments. Taught me a few things. :) I added a second, shorter round of reviews, mostly about documentation and examples. Other than that, I couldn't see any problems. :) I do notice that we can't run |
Ah, you updated the docs, thanks! Took me too long to investigate. :) Running the tests locally, I'm getting this from
Looks like we need to update the tests, too. :( Sorry for the piecemeal review! |
Actually, I'm pretty sure the reason you can't run (for what it's worth, ILB is in GA now. Even if it were in beta though, I don't think you would need a whitelist- that's just for alpha [citation needed though].) |
Cool! Sorry for the confusion, I couldn't find solid info on that, and when the test failed with ILB stuff, I just assumed. Whoops. I'll re-run the tests and do a final check. :) |
No worries! |
Thanks @danawillow and @paddyforan for the hard work on this! Excited to see it in the next release! |
Tests all pass for me. Thanks for sticking with the lengthy review process, and for contributing the features! |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. |
This change enables Internal Load Balancing with the introduction of two new resources:
google_compute_region_backend_service
andgoogle_compute_health_check
.For all intents and purposes, this is ready for review. I still need to add documentation.
@evandbrown