-
-
Notifications
You must be signed in to change notification settings - Fork 32
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
Fix nat_gateway_id network_interface_id variable defaults conflict #36
Conversation
/test all |
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.
Thank you for trying, but please think of another solution.
I have both general comments and specific comments.
In general, there are some problems with having defaults of null:
- A bug in the Terraform registry (Terraform Module Registry incorrectly shows Inputs as required if default = null hashicorp/terraform#21417) causes inputs with defaults of
null
to be marked required, which is the opposite of what we want - There is considerable confusion about passing
null
as amodule
input. As explained in Inconsistent/incorrect(?) handling of null input variables hashicorp/terraform#26499, the Terraform documentation says that passingnull
into a module should be treated the same way as not passing in an argument, and should result in the module using the default input value. In fact, it does not work this way, but everyone would like it to, so we should be prepared for both behaviors with inputs that are optional:- A
null
input should be treated as selecting the default value, unlessnull
is a valid alternative value - If
null
is a valid option for the variable, the variable should not be optional
- A
It is not always possible to find a satisfactory resolution, but for strings we have adopted the standard that we use empty strings (""
) to indicate omission and defaults where you might be inclined to use null
if it were not for these problems. Inside the module, values of null
and empty strings should be detected and treated equally. I like to do it this way for compactness if not necessarily readability:
input = length(compact([var.optional])) > 0 ? var.optional : null
@osterman @aknysh @Gowiem do you have anything to add?
Specific comments:
-
This module seems pretty tedious to use, and makes me wonder if we should deprecate this module in favor of https://github.com/cloudposse/terraform-aws-dynamic-subnets and/or terraform-aws-multi-az-subnets, enhancing one or both of those to the extent this module provides working and useful features the other 2 do not.
-
This bug is not our fault. This module has, for 4 years (see Add option to set
ENI
as a default route for private subnets #7, 2017-11-16), set both
network_interface_id = ""
nat_gateway_id = ""
If this now suddenly stops working, which appears it may have due to hashicorp/terraform-provider-aws#16930 and AWS Provider release 3.34.0, this should be reported as an issue to the hashicorp/terraform-provider-aws
project and the issue linked to this PR and any issue in this repo that refers to it (e.g. #35).
Also, I know this impractical, but for bug fixes, I would like to see the examples/complete
test enhanced so that it catches the bug being fixed. That means that
- The current release would fail the test
- The PR fixes pass the test (of course, PR is required to pass all tests)
This will both verify that the bug being fixed is a real bug and that the PR fixes it. The tests are not that helpful if they are insensitive to the changes being made in the PR.
@Nuru how is our usage of null in all of our other modules different? We should no longer use Also, in this case, it seems like 2 variables are mutually exclusive so we should probably add a validator. I know from first-hand experience setting values to null correctly fixes certain errors in HCL2, while in HCL1 the empty string was required. In HCL2, passing @Nuru In this PR specifically, what is the specific problem of changing |
I disagree. I don't think we should continue to maintain backward compatibility with empty strings and null. If we did, then we should do the same for booleans, so we preserve the behavior or |
@osterman wrote
This is true when passing
There are several problems with changing the default value of the input from
With this solution, old code like this will still work: eni_id = local.have_eni ? var.eni_id : ""
ngw_id = local.have_eni ? "" : var.ngw_id Newer code written like this will work under the present behavior of passing null to modules eni_id = local.have_eni ? var.eni_id : null
ngw_id = local.have_eni ? null : var.ngw_id and it will continue to work when Terraform starts correctly treating We also avoid having Hashicorp unhelpfully describe 2 conflicting inputs as being both required. |
/test all |
Thanks for great discussion here! I think I have digested all bullet points and can formulate my own opinion about
I disagree with that. I tried to use that module and with default values it is broken, because it tries to pass wrong values to I think going
Either way the PR is merged already so thank you! ❤️ 🦄 🚀 |
@3h4x wrote:
I don't understand what you mean by "crippling" modules. The current module, after the changes in this PR, accepts either
See these bugs, both still open/unresolved as of this writing:
I agree that, because of changes in the AWS provider, this module was broken, and this module (all our modules) should work with default values when given reasonable values of required variables. That does not mean we need to make |
what
""
foreni_id
,igw_id
, andngw_id
tonull
before passing them toaws_route
eni_id
and notigw_id
that conficts withngw_id
why
aws_route
specifying bothnetwork_interface_id
andnat_gateway_id
is not valid. Prior to Terraform AWS Provider 3.34.0, a value of""
was treated as "not present" so, for example, specifying a validnat_gateway_id
and anetwork_interface_id = ""
was accepted. With 3.34.0, however,""
is interpreted as a value by and triggers the error:igw_id
is only used in the route table for the public subnets, so it does not conflict witheni_id
origw_id
which are only used in the route table for the private subnets.references
aws_route