-
Notifications
You must be signed in to change notification settings - Fork 9.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
Terraform 0.12.0-alpha no longer allows assignments in terraform.tfvars without a corresponding variable declaration #19424
Comments
Hi @lubars! Thanks for reporting this and sharing your use-case. We intentionally made this change to improve usability in situations where a user makes a typo in a It's unlikely that the outcome here will be a new command-line option since each new option increases complexity and hurts usability. Therefore the decision to be made here is whether the unintended convenience of sharing a single "superset" file between configurations outweighs the poor usability of having a silent failure. |
Thanks for the response @apparentlymart. I agree with what you said about command-line options; Terraform has done a good job of keeping them in check, such that the --help for most commands fits on one screen. I did want to add that it's not just a superset file (otherwise we could break it up into provider-specific and shared portions), but that we're generating it from a database from which we generate config files intended for consumption by a variety of applications; what these applications all have in common is that they ignore unrecognized fields, allowing the master to be upgraded without breaking existing applications (as long as fields have been added but not deleted). |
Hi @lubars, One other thing I noticed looking at your opening comment again was an inconsistency in the error message you shared:
The snippet is showing the If it was inconsistent then that suggests a bug in the error message handling here which I'll open as a separate issue so we can investigate further, but I just wanted to check first to make sure that wasn't "doctored" output! |
Hi @apparentlymart - that was indeed a cut-and-paste error - the "Label" contained something semi-proprietary, so I (clumsily) pasted over it with an earlier error. Sorry to confuse the issue! I will fix it now. |
Closing because the regex filter I put on terraform.tfvars generation is working well. |
We have been using a common |
The last 3 places I’ve worked all had similar usage where this would cause problems, so surely this change will affect many users making the terraform upgrade not backwards compatible. |
Same, here - this is surely a very common pattern - every single project I've worked on has had a similar pattern as described by @Legogris : a global.tfvars, and also one tfvars file per environment, with all the values across all the states that are specific to that environment. It would be a nightmare to have to change this pattern when upgrading to 0.12. |
@lubars any chance you could reopen this for visibility? Having to devise workarounds for this is very undesirable in my opinion |
Hi all, As a compromise, we will make this situation be a warning for 0.12, and then plan on making it an error in 0.13. As I noted above, we made this change so that users can get feedback when they make a typo in a variable name either in the main configuration or in the However, I can see that right now there is a hole here where it's not clear what exactly such an automation should do, because there's no way to ask Terraform which variables are needed for a particular configuration. For now the easiest answer would be to declare the same variables in every configuration if you intend to pass them all there, but I know that's not ideal for a number of reasons. In future we intend to have a built-in command to "inspect" a configuration to get a machine-readable description of its top-level objects, which could potentially help here. For now, we have a separate codebase terraform-config-inspect which could be used for this in principle. The scope of this issue will just be to make the error into a warning. We'll tackle further improvements in this area via other issues once we've got 0.12.0 released. |
thank you very much @apparentlymart - that is a reasonable compromise. |
I realize I forgot to mention the other possible approach here: For pragmatic reasons the As a consequence, it's possible to use environment variables to set this sort of "global" variable that is provided by the automation wrapper, and reserve the CLI arguments for any run-specific overrides. In a previous role (before joining the Terraform team) this is how my team arranged for the automation wrapper to pass in certain "global" values like the environment name, application name, etc. This approach is particularly handy if your automation tool already has first-class support for setting environment variables for runs. |
Would you consider adding an opt-in flag to terraform to allow unused global variables? |
I don't think an opt-in is required here now that it's a warning. Terraform will just print a message telling you it's deprecated (which it is) and move on as before. You can transition to using environment variables instead at your leisure any time before the future major release that will turn this back into an error again (which is not yet decided). |
@apparentlymart Where can I track the decision making process for this for 0.13? tfscaffold explicitly depends on the capability to inherit and share configuration files as required between the scopes of "global" "region" "group" and "environment". If this is implemented as an absolute error, it will completely break many projects, requiring every component to be forced to code unnecessary variable blocks to account for any variable it does not use. I completely understand the desire to support users who have made a mistake, I do not understand the need to enforce further backward-incompatible change on users who intentionally work in this manner to provide an enterprise-grade project management structure around terraform. Frankly I do not understand the need to introduce backward-incompatible changes at every major release. I would really appreciate you guys considering this more in the future. Additional features do not have to be breaking. For example, the introduction of the -auto-approve flag as a requirement to continue to act in the pre-existing manner, instead of simply adding -require-approval as an optional feature. |
The more backwards compatibility changes there are, the more likely we are to look for alternatives to terraform. Wouldn't just a warning do in this case? |
I can understand this feature from a correctness perspective but like other
people on this thread think users should be able to opt-out via a flag or
environment variable.
…On Fri, Mar 8, 2019 at 7:58 AM David Roussel ***@***.***> wrote:
The more backwards compatibility changes there are, the more likely we are
to look for alternatives to terraform. Wouldn't just a warning do in this
case?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#19424 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AADFlPvlQ7cy98FDeH_2qjc_VrjBb0u_ks5vUnqpgaJpZM4YsC6s>
.
|
Thanks for your feedback here, everyone. What is implemented right now is already a warning for the initial 0.12 release. The migration path for existing software relying on this is to transition to using the We make these carefully-considered breaking changes because real-world feedback tells us that the previous behavior was not good enough. Not making these changes would prevent fixing real-world pitfalls that cause frustration and real damage. We always try to ensure there is a path forward for existing valid use-cases, which we did both in changing the default behavior of Helpful feedback about mistakes is never helpful if you have to know to opt in to see it, because the person who needs the feedback doesn't know to ask for it yet. It is therefore important that Terraform's default behavior is safe and helpful, while providing opt-in alternative paths where needed. Because the If you find that other products suit your needs better than Terraform for whatever reason then if course we invite you to use them. Terraform is one product in a busy space, and we make these decisions to make it as user-friendly as possible but a single product will never meet every use-cases and we would rather see you use the right tool for your job (whether it be an older version of Terraform that is already meeting your needs or another similar product in the space) than to be frustrated by forcing Terraform into uses it is less suited for. |
@apparentlymart how can we pass more complex variables such as maps and lists via environment variables? I’m sure they work fine for some use cases, but I cannot see them working in my case. |
@edmundcraske it should be possible to set any variable that way. If you are seeing strange/unexpected behavior, please open an issue about it and we will investigate what is going on. |
@apparentlymart I for one appreciate the detailed response.
Definitely. The suggestion some of us made here is therefore to introduce an opt-in flag for the pre-v0.12 behavior. Something like Would you be open to this? If not, what do you see as the downside here? |
* hashicorp#19424 This adds the flag `-allow-undeclared-vars` which skips the parsing of variables, which would otherwise generate an Error/Warning when a `-var` is passed to `apply`/`plan` without being defined in a variable block Without flag: ``` $ terraform plan -var foo=bar Error: Value for undeclared variable A variable named "foo" was assigned on the command line, but the root module does not declare a variable of that name. To use this value, add a "variable" block to the configuration. ``` With flag: ``` $ terraform apply -var foo=bar -allow-undeclared-vars Refreshing Terraform state in-memory prior to plan... ... ```
I understand this hasn't been accepted yet, but made a WIP PR for a little fun ☝️ (Using the I agree with @Legogris on this, I don't think that this feature should be enforced. It feels more like a strict linting/styling feature than core functionality, so would feel better to have the option to ignore it. |
We do not intend to have two different ways to specify undeclared variables, because that increases the complexity of the software, and thus increases the documentation, testing, and ongoing maintenance overhead. A command line argument also doesn't solve the problem for any wrapper program that is trying to work with both v0.11 and v0.12 at the same time, because The environment variables solution is the documented way to do this, it already works in Terraform v0.11 (so automation wrappers don't need to do any special version switching to detect when v0.12 is in use, and can embrace this solution today), and is what we plan to ship in v0.12. As I noted above, if you find that setting variables by environment variables is non-functional for some reason then please let us know in a separate issue, and we will fix it. |
Really feels like disallowing superset variable configuration files and forcing users to jam everything into environment variables is going to exacerbate the original problem you're setting out to fix. Most people here likely have machine generated configurations that are being passed to several different terraform projects for managing subsets of their infrastructure. Forcing all of that to be passed via environment just to hide warnings (and eventually, errors) is just sweeping the typo problem under a different, even more opaque, and less user friendly rug... |
If the argument is you don't want to support two different methods, you'd probably be better off rejecting undeclared TF_VAR_* environment variables and leaving configuration file superset behavior as is The latter is a far, far more likely source of accidental typos, as it'll usually be utilized for passing secrets on the command line. |
The best compromise would be to allow undeclared variables from var files and reject undeclared env vars. This way:
It's good to try make a tool fool-proof, but it's just not cool to break everything. |
Not allowing variables in tfvars files that are undeclared as variables would break the magic we've put together. Would it not be enough to just list unused variables as an "info" message when running the terraform command? |
Absolutely, having to set all global vars as TF_VAR_* environment variables adds a level of complexity and is prone to errors. |
There are different absurd solutions to this problem:
cuts it off nicely. But in reality, just one line needs to change. |
Meanwhile, I took the formula from brew and modified it to apply the patch. Now the patched version can be installed as simple as Check this out: https://github.com/springload/homebrew-tools/blob/master/Formula/terraform.rb Linux is out of scope, unfortunately. Well, brew works on Linux... |
I strongly disagree with the rationale for this change! I've been using terraform for years and this goes against almost everything I've come to consider as best practices. First, the recommendation to use Second, it makes no sense to be concerned about typos since i can simply use a map for my top-level variables and i'm right back in the same boat with typos. Lastly, expecting a single Also, the diff output of terraform is absolutely critical. It's immensely more important than warning about a typo and I would even argue that it's the most important aspect of the tool. The diff is actually the right place to discover that there is a typo. To clutter that output with warnings about situations that the user may intentionally desire is amazingly irresponsible. This has a very serious negative impact on productivity. I don't completely disagree with the intent, only the solution. While I do agree with your concern about restraining the complexity of the CLI flags, I believe this is a valid reason for an exception of making this a selectable feature. Something like cc: @apparentlymart |
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. |
Terraform Version
Expected Behavior
Terraform v0.11.10 and earlier allowed assignments to occur in terraform.tfvars without a corresponding variable declaration in infrastructure.tf.
Actual Behavior
This now results in errors such as the following:
Steps to Reproduce
terraform plan
Additional Context
We generate a common terraform.tfvars file shared by multiple provider-specific infrastucture.tf files. Only a subset of the assignments in terraform.tfvars are referenced in a given infrastructure.tf file. Up until v0.11.10, assignments in terraform.tfvars without a corresponding variable declaration in a given infrastructure.tf were ignored. The previous behavior should be supported, or perhaps a flag (e.g. "-ignore-undeclared") added. I am submitting this as a bug rather than a feature because we considered the behavior up to v.0.11.10 as the feature because it allowed use of a common file and, by allowing new assignments without a corresponding variable declaration, provided a certain amount of forward- and backward-compatiblity.
Update
I am now deleting from terraform.tfvars every line that does not match the following regular expression in infrastructure.tf:
So I am unblocked for the moment.
The text was updated successfully, but these errors were encountered: