Skip to content
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

Various fixes for "terraform validate" command #18318

Merged
merged 3 commits into from
Jun 26, 2018

Conversation

apparentlymart
Copy link
Contributor

@apparentlymart apparentlymart commented Jun 22, 2018

The increased precision of the new type checker has caused some assumptions to shift for terraform validate, and for the validate walk in general, causing it to be not fully functional at the moment.

This PR doesn't quite get it all the way there, since some bigger work needs to be completed first, but this pushes the errors down the stack a couple steps:

  • Set root variables during terraform validate: the early pass we did to get terraform validate working against the new config loader got away with not setting variables because it wasn't actually walking the graph. However, now we are walking the graph we must provide values for all of the root variables in order to prevent a "this is a bug in terraform"-type error message. Here we set them to unknown values of the declared type, allowing us to do type checking of the uses of these values regardless of which particular values are finally set when running plan or apply.

  • Don't DynamicExpand during evaluate: doing a dynamic-expand in the validate walk creates a loophole where we will fail to validate the contents of a resource block which either has count = 0 or has count set to some value that won't be known until the plan walk. Here instead we just validate the configuration block itself, using an unknown number for count.index if appropriate, to determine of the configuration is valid for any count. More precise validation then happens during the DynamicExpand in the plan walk.

The remaining step here to repair the validate walk is to swap in the new state types and then allow the evaluator to recognize the difference between a completed resource with count = 0 and a resource that has no state at all due to being in the validate walk. That will then allow expressions like null_resource.example[0] to pass validation, since null_resource.example would in that case be an unknown list value of null_resource's implied object type, allowing type checking to proceed.

Once this is working again, we'll be partially down the road towards #15895, though we'll probably want to do some further refactoring afterwards to more cleanly distinguish the different walks. The sequence of work that this PR belongs to is just about getting terraform validate back into a working state when running against our new expression evaluator.

This doesn't yet include any tests for the terraform validate breakage, with the intent that we'll do that once it's working end-to-end and thus the tests would actually pass.

Since the intent of the validate command is to check config validity
regardless of context (input variables, state, etc), we use unknown values
of the requested type here, which will then allow us to complete type
checking against the specified types of the variables without assuming
any particular values.
Previously we had the evaluate methods accept directly an
addrs.InstanceKey and had our evaluator infer a suitable value for
count.index for it, but that prevents us from setting the index to be
unknown in the validation scenario where we may not be able to predict
the number of instances yet but we still want to be able to check that
the configuration block is type-safe for all possible count values.

To achieve this, we separate the concern of deciding on a value for
count.index from the concern of evaluating it, which then allows for
other implementations of this in future. For the purpose of this commit
there is no change in behavior, with the count.index value being populated
whenever the instance key is a number.

This commit does a little more groundwork for the future implementation
of the for_each feature (which'll support each.key and each.value) but
still doesn't yet implement it, leaving it just stubbed out for the
moment.
@apparentlymart apparentlymart self-assigned this Jun 22, 2018
@apparentlymart apparentlymart requested a review from a team June 22, 2018 23:47
Previously we would attempt to DynamicExpand during the validate walk and
then validate each expanded instance separately. However, this meant that
we would not be able to validate the contents of a block where count = 0
or if count is not yet known.

Here we instead do a more static validation pass against the resource
configuration itself, setting count.index to cty.UnknownVal(cty.Number) so
we can type-check everything inside the block as being correct regardless
of the final count.

This is another step towards repairing the "validate" command for our
changed assumptions in a world where we have a more sophisticated type
checker.

This doesn't yet address the remaining problem that the expression
evaluator can't, with the current state structures, distinguish between
a completed resource with count = 0 and a resource that doesn't exist
at all (during validate), and so we'll still get errors if an expression
elsewhere in configuration refers to a dynamic index of a resource with
"count" set. That's a pre-existing condition that's no longer being masked
by _this_ problem, but can't be addressed until we've introduced the new
state types (states.State, etc) and thus we _can_ distinguish these two
situations. That will therefore be addressed in a later commit.
@apparentlymart apparentlymart merged commit 6e826cd into v0.12-dev Jun 26, 2018
@apparentlymart apparentlymart deleted the f-hcl2-validate2 branch June 26, 2018 01:28
@ghost
Copy link

ghost commented Apr 3, 2020

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.

@ghost ghost locked and limited conversation to collaborators Apr 3, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants