-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Add conditional validation, allow sending empty capacity scaler for regional backend service #3033
Add conditional validation, allow sending empty capacity scaler for regional backend service #3033
Conversation
Hi! I'm the modular magician. Your PR hasn't generated any diffs, but I'll let you know if a future commit does. |
1 similar comment
Hi! I'm the modular magician. Your PR hasn't generated any diffs, but I'll let you know if a future commit does. |
56886d1
to
2932dde
Compare
2932dde
to
eaa8cdc
Compare
eaa8cdc
to
af493af
Compare
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.
Won't https://github.com/modular-magician/terraform-provider-google/compare/auto-pr-3033-old..auto-pr-3033#diff-212e80d75682146384aa4a2de927dec7L203-L214 cause a real breaking change / regression for users who haven't defined a value? As I understand their state will have 1.0
recorded but Terraform will now see 0
and cause a diff.
// float and because INTERNAL backends can't have the value set, so there will be a permadiff for a | ||
// situational non-zero default returned from the API. We can't diff suppress or customdiff a | ||
// field inside a set object in ResourceDiff, since the value also determines the hash for that set object. | ||
func validateNonInternalBackendServiceBackends(backends []interface{}, d *schema.ResourceDiff) error { |
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.
One thing to watch out for here is unknown values. If I interpolate a variable into one of the fields and that variable isn't known at plan-time it'll appear to be unset/zero. This may fail an otherwise valid config if the value will have a value that works.
You can check values with d.NewValueKnown
. I forget the exact interaction with sets- whether a single unknown value makes the parent count as unknown or not.
Handling unknown values properly is hard though, and it's may not be worth handling correctly. It doesn't come up much and it's painful to simulate with a small config 🤷♀
@@ -0,0 +1,100 @@ | |||
<%# The license inside this block applies to this file. | |||
# Copyright 2019 Google Inc. |
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.
nit: license blocks should all be 2020
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.
Ansible looks good!
@rileykarson yep, that's the breaking change I mentioned - it also has to create a permadiff right now because if they don't have it defined in config, Terraform calculates the set value as 0.00 which causes a hashcode change. If they just are using the INTERNAL default (which i think most people are) then the API doesn't return a value anyways. |
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.
Can you write in the changelog (in the breaking change or as a note) that Terraform now defaults the field to 0.0
while previously it was 1.0
, and that users will need to explicitly specify it to have it set to 1.0
? It's implied by your current message, but making it explicit would help.
Hi! I'm the modular magician. Your PR generated some diffs in downstreams - here they are. Diff report:Terraform GA: Diff ( 6 files changed, 59 insertions(+), 499 deletions(-)) |
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.
InSpec looks fine!
c4f6243
to
ec1821d
Compare
Hi! I'm the modular magician. Your PR generated some diffs in downstreams - here they are. Diff report:Terraform GA: Diff ( 6 files changed, 59 insertions(+), 503 deletions(-)) |
…egional backend service (GoogleCloudPlatform#3033) * fix region backend service capacity scaler * add capacity scaler to fr example * remove recopied handwritten test * move constant list into expanders for tpg conversion * change licenses
Fixes hashicorp/terraform-provider-google#5449
This PR includes a breaking change/bug fix and weird validation because RegionBackendService has a conditional default, and schema.Set cannot tell the difference between nil and zero values for scalars like float/int.
Changes:
Context
RegionBackendService has typically only allowed for Internal Load Balancing (
load_balancing_scheme
defaults toINTERNAL
), and the API rejects INTERNAL backend requests with specific fields inbackend
set likecapacity_scaler
,max_rate
, etcA new INTERNAL_MANAGED lb_scheme allows users to specify fields that were previously managed (unsettable). If not sent in the request, the API returns 1.0 for the value of
capacity_scaler
. NOTE: This is technically also true for BackendService, but as BackendService cannot be INTERNAL, it will always return 1.0 in the case of nil capacity_scaler so we slapped a default value on and it works fine.Then, for
INTERNAL_MANAGED
region backend services: If capacity_scaler is not set in config, the API returns 1.0 --> schema.Set cannot tell capacity_scaler = 0.0 and not-set-capacity-scaler apart --> a diff is detected because of new hash-value of set object, which we can't suppress. d,We also need to be able to send an empty value if non-INTERNAL, but we can't send the empty value if the RegionBackendService is INTERNAL (default)
FUTURE WORK
Right now, BackendService/RegionBackendService has unfixable behavior in that there is no way to send zero values for the other fields either BackendService or RegionBackendService
backend
. On read, schema.Set will zero any unset fields out, and they in turn will get sent to the API on next apply. We can force capacity_scaler to be set just because it's a requirement (hence default 1.0), but the other fields cannot be required because they can't all be set at once on the object (max_rate
,max_rate_per_instance
, etc have conflicts)