-
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
Value assertions / validations in configuration files #2847
Comments
This might help at least with some very basic validation: |
require_regex and require_oneof would be an awesome feature :) |
Any further thoughts on this? I'd love to see something like this. Any suggested workarounds? |
I solved our problem with this; does this do what you want? |
Hey guys, I found a way today how you can hack in asserts into the current version of Terraform. TL;DR
or
|
Here's another use case. I'd like to ensure that my AWS ALB health check interval is greater than my AWS ALB health check timeout. |
We have certain conventions we like to make sure are met when creating resources around this organisation using terraform. A simple example is that specific AWS resources need to be lower-case. In other cases, we might want to make sure that a specific I was thinking that either the keywords variable "input" {
type = "list"
default = true
# ensure that input values are distinct
assert = "${distinct(var.input) == var.input}"
} I'm not super sold on using We are specifically interested in this feature to prevent situations which have appeared in the past where resources have simply been named erroneously or following outdated conventions that we'd like to catch. References |
@apparentlymart have we got the enhancement to put constraints to the input in terraform such as require_one_of ? or it still work in progress |
I use terraform to configure AWS Auto-scaling Groups, and would love to be able to put a constraint on my module that |
@ruke47 perhaps not as desirable, but you could make use of
wherever you need to use |
I was using the workaround provided by @Jamie-BitFlight above, but this no longer works with 0.12. You get an error that the argument is no expected. |
I'm currently using a pattern like this with 0.12:
The output is not 100% explicit
but, it does achieve a validation check, and the |
We also need a proper solution to ensure module users are supplying valid values. These hacks are nice but something officially supported would be better. |
It would be great if there could be multiple assertions, along with a user friendly error message. Something like:
|
Some of the workarounds above were for older versions or didn't quite work. So here's an example that has worked for me recently to get enum behaviour:
|
I ran across the change in tf .12 and @teamterraform had a great solution (I think) in #22901 using a local map and key lookup. The same principal can be used with a list and index with a few less key strokes with the same effect. If you name the local testing the value well enough it should be clear what the issue it.
When a bad value is provided:
|
It is strange to me that this has been being asked for since 2015 and yet input validation still remains absent from Terraform. There also doesn't seem to be much of an explanation officially for why? Happy to be corrected. |
I'd like to add my use case from #23205 which was closed as it "seems to be covering the same problem or request" as the one here. We use terraform to deploy resources to GCP and we use labels upon those resources to enable fine-grained analysis of billing. For example, we have a label with a key of component and we encourage each product team within our organisation to create that label with the same value on all their resources - thus we can aggregate all expenditure per component. The set of values that we expect to be used for that component label is finite and short but GCP does not provide a way to restrict the actual value that gets supplied. This creates two problems:
We provide terraform modules for our various teams to use to deploy GCP resources. Those terraform modules allow us to control how resources get configured/deployed and thus allow us to mandate a component label by providing a module variable var.component for which a value must be supplied - that gets us around the problem developers forgetting to create the label. However, we still don't have a way to restrict the value that gets supplied, thus we still get the detritus of values. My suggestion is that terraform variables can optionally be configured with a specified with a set of allowed values. Something like this perhaps:
|
This is the approach I am currently using. |
@oqf this is brilliant, thank you. Time to expedite our move to terraform 12. |
Hi all, In the forthcoming Terraform 0.12.20 we're planning to introduce an experimental new feature intended to meet the major use-cases discussed in this issue. The initial design is to add a new block type variable "environment" {
type = string
validation {
condition = contains(["test", "staging", "production"], var.environment)
error_message = "Argument \"environment\" must be either \"test\", \"staging\", or \"production\"."
}
} Each Terraform will evaluate the expression given in If the
A variable "cidr_block" {
type = string
validation {
condition = can(regex("^\d{,3}.\d{,3}.\d{,3}.\d{,3}/[0-3][0-9]$", var.environment))
error_message = "Argument \"cidr_block\" must be an IPv4 CIDR prefix in the standard CIDR prefix notation."
}
} The function This feature is currently experimental and subject to breaking changes with no automatic upgrade path even in patch releases of Terraform. We do not recommend using this feature in "production" modules at this stage, and to avoid accidentally depending on the experimental feature we're currently requiring an explicit opt-in using a new argument in a terraform {
experiments = [variable_validation]
} This opt-in marker will be required as long as the feature remains experimental. Activating this experiment will cause Terraform to emit a warning to make sure all users of the module are aware that it is depending on an experimental feature that may break in future Terraform releases. We plan to introduce the Alternatively, the implementation for this is already in the If you do have feedback on this experimental feature once it's available, please open a new feature request issue and complete the template to show what you're trying to do and what challenges you ran into, if any. This issue already has a long and varied discussion history, so please avoid leaving feedback comments directly in reply to this comment so we can keep the notification noise to a minimum for those who are watching this issue for development updates. (If this announcement leads to a lot of chatter in this issue then I may temporarily lock it for a while just to manage notification noise, but 🤞 that won't be necessary.) We're excited to hear you feedback. Thanks! |
@apparentlymart can the experiment also run an external script for validation of a variable? Or check things like "file exists"? |
One thing I noticed about this experimental feature - you cannot reference other variables in the condition. E.g., I want to make sure a certain variable is actually given when another variable has a certain value. Something like this: variable "tfstate_sa_name" {
type = string
description = "The name of the storage account to store the remote backend state of this component. Required when role is component"
default = ""
validation {
condition = var.tfstate_sa_name != "" || var.role != "component"
error_message = "The \"tfstate_sa_name\" variable must be given when configuring the remote backend for regular components."
}
} Not allowed:
|
Hi @MarkKharitonov, Indeed, that's an intentional limitation at least for this initial version of the feature because it avoids a situation where a variable could potentially have additional dependency edges apart from what comes from its expression in the calling module, and while that might be possible someday it would've made this initial implementation far more risky and complicated. Would you mind opening a new feature request issue describing that use-case? That way when we close out this issue (once the new feature stops being experimental) we won't lose track of this enhancement request. As I noted in my comment above, that guidance applies to all feedback on the experiment: please open new issues, rather than leaving comments here, because that way we can make sure that we see all of the feedback and can track the outcome of each response separately, with regard to whether it's been resolved in the initial release or whether it's deferred as a later enhancement, and also we can have multiple threads of discussion rather than trying to discuss everything all at once in here. Thanks! |
I had situation to restrict deployments from the default workspace using v0.12.20(not using the experimental feature) when a default workspace is used then the below error is thrown, ` non_default_workspace_chk = index(terraform.workspace == "default" ? []:[terraform.workspace], terraform.workspace) Call to function "index" failed: cannot search an empty list.` |
I am trying out this validation block - and it works well as long as you have a single string input variable. How do you accommodate a list(string) - say I need a list of values of validated? |
@avarmaavarma it sounds like you've been trying out the experimental feature and have run into something unclear about it. If so, it would be helpful if you would open a new issue using the "Feature Request" template to show more about what you tried to do and what happened when you tried it. Then I may be able to help you use the feature to solve your problem, but it will also be useful to help improve the feature and/or the documentation about it before it is released as stable. Thanks! |
Here is the feature request - #24223 Essentially, input validation (love the experimental feature - much needed!), does not allow a collection of values to be validated. And yes - a workaround until then, would be very valuable. I am curious as to how folks are currently validating sets of input values... Thanks |
Is there any plan to add something like a testcase to the validation? It would be nice to have some inline examples of good and bad values for ensuring complex validation behaves as expected. Thanks! |
Hi all, The custom variable validation feature will become stable (non-experimental) in the forthcoming 0.13 release. Because all of the feedback we saw based on the experiment was functionality that could be added later without breaking compatibility, we decided to leave the feature exactly as originally implemented for the initial release and then improve it gradually in subsequent releases. Terraform 0.13's beta testing period will start imminently, where you can try this out if you wish. With that said, aside from the experiment opt-in no longer being required the functionality has not changed at all, so if you already tried it out under the experiment you may wish to just wait until 0.13.0 final to use the stable version. Because the change is already merged in the Thanks! |
It would be nice to assert conditions on values, extending the schema validation idea to the actual config language. This could probably be limited to variables, but even standalone assertion statements could be a possibility (e.g., maybe we need to validate multiple variables in tandem).
As an example, suppose I have a variable that I want to be one of three values – e.g., test, staging, or production – and maybe my stack / module won't fail if given another value, but I want to enforce it to be one of the three. It would be nice to specify these requirements somewhere. Here's one possibility:
Where the
require
attribute must evaluate to a true value or terraform would raise an error. Another option, instead of more interpolation functions, would be to include a few basicrequire_xyz
attributes:And so on. The benefit of the latter option is that you can return nicer error messages whereas the former provides interpolation functions that may be useful even beyond this context.
In some cases these values will end up in attributes for resources, at which point the attribute's validation may spit back an error, but if you're considering modules nested inside modules nested inside modules, it's nice to know at exactly which point the invalid input occurred. In other words, it's great that
module.foo.module.bar.module.spam.aws_vpc.cidr_block
is invalid, but perhaps the CIDR block input was constructed atmodule.bar
from input given bymodule.foo
.The text was updated successfully, but these errors were encountered: