Commit Graph

145 Commits

Author SHA1 Message Date
Martin Atkins f6797d6cb0 config: parsing of "locals" blocks in configuration 2017-08-21 15:15:25 -07:00
Martin Atkins f70318097a config: fix provider version constraint validation
Previously we were using the "semver" library to parse version
constraints, but we switched over to go-version and encapsulated it
inside our own plugin/discovery package to reduce dependency sprawl in
the code.

This particular situation was missed when updating references to the new
path, which meant that our validation code disagreed with the rest of
the code about what is considered a valid version constraint string.
By using the correct function, we ensure that we catch early any invalid
versions.
2017-06-09 14:03:59 -07:00
Martin Atkins 7e7d4c70df config: allow version constraints on providers, but validate them
We now accept syntactically-valid version constraints on provider blocks,
though we still don't actually do anything with them.
2017-06-09 14:03:59 -07:00
Martin Atkins 73fc9985b2 config: add "version" argument to provider blocks, disabled
In future we will support version constraints on providers, so we're
reserving this attribute name that is currently not used by any builtin
providers.

For now using this will produce an error, since the rest of Terraform
(outside of the config parser) doesn't currently have this notion and we
don't want people to start trying to use it until its behavior is fully
defined and implemented.

It may be used by third-party providers, so this is a breaking change
worth warning about in CHANGELOG but one whose impact should be small.
Any third-party providers using this name should migrate to using a new
attribute name instead moving forward.
2017-06-09 14:03:59 -07:00
Martin Atkins 410b60cb7f Stop requiring multi-vars (splats) to be in array brackets
Prior to Terraform 0.7, lists in Terraform were just a shallow abstraction
on top of strings with a magic delimiter between items. Wrapping a single
string in brackets in the configuration was Terraform's prompt that it
needed to split the string on that delimiter during interpolation.

In 0.7, when first-class lists were added, this convention was preserved
by flattening lists-of-lists by one level when they were encountered in
configuration. However, there was an oversight in that change where it
did not correctly handle the case where the inner list was unknown.

In #14135 we removed some code that was flattening partially-unknown lists
into fully-unknown (untyped) values. This inadvertently exposed the missed
case from the previous paragraph, causing issues for list-wrapped splat
expressions with unknown members. While this worked fine for resources,
due to some fixup done inside helper/schema, this did not work for other
interpolation contexts such as module blocks.

Various attempts to fix this up and restore the flattening behavior
selectively were unsuccessful, due to a proliferation of assumptions all
over the core code that would be too risky to change just to fix this bug.

This change, then, takes the different approach of removing the
requirement that splats be presented inside list brackets. This
requirement didn't make much sense anymore anyway, since no other
list-returning expression had this constraint and so the rest of Terraform
was already successfully dealing with both cases.

This leaves us with two different scenarios:

- For resource arguments, existing normalization code in helper/schema
  does its own flattening that preserves compatibility with the common
  practice of using bracketed splats. This change proves this with a test
  within the "test" provider that exercises the whole Terraform core and
  helper/schema stack that assigns bracketed splats to list and set
  attributes.

- For arguments in other blocks, such as in module callsites, the
  interpolator's own flattening behavior applies to known lists,
  preserving compatibility with configurations from before
  partially-computed splats were possible, but those wishing to use
  partially-computed splats are required to drop the surrounding brackets.
  This is less concerning because this scenario was introduced only in
  0.9.5, so the scope for breakage is limited to those who adopted this
  new feature quickly after upgrading.

As of this commit, the recommendation is to stop using brackets around
splats but the old form continues to be supported for backward
compatibility. In a future _major_ version of Terraform we will probably
phase out this legacy form to improve consistency, but for now both
forms are acceptable at the expense of some (pre-existing) weird behavior
when _actual_ lists-of-lists are used.

This addresses #14521 by officially adopting the suggested workaround of
dropping the brackets around the splat. However, it doesn't yet allow
passing of a partially-unknown list between modules: that still violates
assumptions in Terraform's core, so for the moment partially-unknown lists
work only within a _single_ interpolation expression, and cannot be
passed around between expressions. Until more holistic work is done to
improve Terraform's type handling, passing a partially-unknown splat
through to a module will result in a fully-unknown list emerging on
the other side, just as was the case before #14135; this change just
addresses the fact that this was failing with an error in 0.9.5.
2017-05-23 11:22:37 -07:00
Martin Atkins 81b0c4b28d config: generate errors for unnamed blocks of various sources
We've been incorrectly validating (or not validating at all) the
requirement that certain blocks be followed by a name string, to prohibit
e.g. this:

    variable {}

and:

    variable = ""

Before this change we were catching this for most constructs only if
there were no _valid_ blocks of the same name in the same file. For
modules in particular, we were not catching this at all.

Now we detect this for all kinds of block (resources had a pre-existing
check, so aren't touched here) and produce a different error message
depending on which of the above incorrect forms are used.

This fixes #13575.
2017-05-02 16:29:57 -07:00
Martin Atkins 76dca009e0 Allow escaped interpolation-like sequences in variable defaults
The variable validator assumes that any AST node it gets from an
interpolation walk is an indicator of an interpolation. Unfortunately,
back in f223be15 we changed the interpolation walker to emit a LiteralNode
as a way to signal that the result is a literal but not identical to the
input due to escapes.

The existence of this issue suggests a bit of a design smell in that the
interpolation walker interface at first glance appears to skip over all
literals, but it actually emits them in this one situation. In the long
run we should perhaps think about whether the abstraction is right here,
but this is a shallow, tactical change that fixes #13001.
2017-03-29 09:25:57 -07:00
James Bardin 8bcb9e19ca restructure JSON terraform config block AST
When configuration is read out of JSON, HCL assumes that empty levels of
objects can be flattened, but this removes too much to decode into a
config.Terraform struct.

Reconstruct the appropriate AST to decode the config struct.
2017-03-21 18:15:58 -04:00
Mitchell Hashimoto f7da5d323c
config: test that JSON loading terraform backend info works 2017-03-16 14:51:26 -07:00
James Bardin 3c41a7ca1e Add test for Validate crash
Crash during Validate walk with nested variable default.
2017-03-07 15:01:29 -05:00
Mitchell Hashimoto 6b4c007894
config: validate backend configuration can't contain interpolations 2017-02-17 16:27:01 -08:00
Mitchell Hashimoto b6bfc4798d
config: Resource.Count should type check
Fixes #11800

Type check the value of count so we don't panic on the conversion.

I wondered "why didn't we do this before?" There is no excuse for NOT
doing it at all but the reasoning was beacuse prior to the list/map work
in 0.7, the value couldn't be anything other than a string since any
primitive can turn into a string.

Regardless, we should've always done this.
2017-02-10 10:41:41 -08:00
Mitchell Hashimoto 7b342100d0
config: add "backend" loading to the Terraform section 2017-01-26 14:33:49 -08:00
Mitchell Hashimoto 928fce71f7
config: parse "when" and "on_failure" on provisioners 2017-01-19 18:10:21 -08:00
Mitchell Hashimoto 8a102799c2 Merge pull request #10658 from hashicorp/b-var-keys
config: validate invalid variable keys
2016-12-12 10:53:07 -08:00
Mitchell Hashimoto 3ba9720b3e
config: validate invalid variable keys
Fixes #9416

A simple change to verify that only valid keys for `variable` blocks are
used.
2016-12-10 19:27:01 -05:00
Mitchell Hashimoto 5d684b399c
config: error when loading multiple lifecycle blocks
Fixes #8776

This introduces an error when multiple `lifecycle` blocks exist on a
resource in the configuration.
2016-12-10 18:52:13 -05:00
Mitchell Hashimoto 6b458160b9
config: disallow names starting with ints
Fixes #10597

This disallows any names for variables, modules, etc. starting with
ints. This causes parse errors with the new HIL parser and actually
causes long term ambiguities if we allow this.

I've also updated the upgrade guide to note this as a backwards
compatibility and how people can fix this going forward.
2016-12-08 23:01:51 -05:00
Mitchell Hashimoto 3665fea2db
config: validate that data sources don't have provisioners 2016-11-23 08:46:13 -08:00
Mitchell Hashimoto 9cc52d83de
config: test that null characters show up as errors in parse 2016-11-21 18:11:11 -08:00
Martin Atkins 399542a168 core: allow outputs to have descriptions (#9722)
We allow variables to have descriptions specified, as additional context
for a module user as to what should be provided for a given variable.

We previously lacked a similar mechanism for outputs. Since they too are
part of a module's public interface, it makes sense to be able to add
descriptions for these for symmetry's sake.

This change makes a "description" attribute valid within an "output"
configuration block and stores it within the configuration data structure,
but doesn't yet do anything further with it. For now this is useful only
for third-party tools that might parse a module's config to generate
user documentation; later we could expose the descriptions as part of
the "apply" output, but that is left for a separate change.
2016-11-18 19:09:43 +02:00
Mitchell Hashimoto 25d19ef3d0 Merge pull request #10080 from hashicorp/f-tf-version
terraform: support version requirement in configuration
2016-11-14 11:53:30 -08:00
Mitchell Hashimoto df34fa88ce Merge pull request #10076 from hashicorp/f-depend-module
terraform: depends_on can reference entire modules
2016-11-14 11:53:12 -08:00
Mitchell Hashimoto 85d3439fa0
config: parse and validate terraform.required_version 2016-11-12 16:22:35 -08:00
Mitchell Hashimoto 576b61a21d
config: validate depends_on with module values 2016-11-12 08:21:27 -08:00
Mitchell Hashimoto 10426ba619
config: parse depends_on for outputs 2016-11-11 17:46:34 -08:00
Mitchell Hashimoto 29287937e3 Merge pull request #9818 from hashicorp/b-var-parse
config: manually parse variable blocks for better validation
2016-11-04 08:47:40 -07:00
Mitchell Hashimoto ef3148bbfa
config: validate that outputs have a name 2016-11-02 16:56:20 -07:00
Mitchell Hashimoto f054c5ca2c
config: manually parse variable blocks for better validation
Fixes #7846

This changes from using the HCL decoder to manually decoding the
`variable` blocks within the configuration. This gives us a lot more
power to catch validation errors. This PR retains the same tests and
fixes one additional issue (covered by a test) in the case where a
variable has no named assigned.
2016-11-02 14:59:16 -07:00
Mitchell Hashimoto 694b16de5d
config: ignore_changes cannot have interpolations
This is the limitation of all lifecycle attributes currently. Right now,
interpolations are allowed through and the user ends up thinking it
should work. We should give an error.

In the future it should be possible to support some minimal set of
interpolations (static variables, data sources even perhaps) but for now
let's validate that this doesn't work.
2016-10-24 23:06:33 -07:00
Mitchell Hashimoto 609219fc65 command/meta: validate config immediately
* config: test for validating multi-vars (passes)

* command/plan: test invalid run

* command/meta: validate module on load
2016-09-03 15:26:49 -07:00
James Bardin 94674fe93c Add a test load of a data source with count 2016-09-03 13:08:41 -07:00
Sander van Harmelen 47dd1ad153 Add wildcard (match all) support to ignore_changes (#8599) 2016-09-02 15:44:35 +02:00
Mitchell Hashimoto 706b2e2aea Merge pull request #8482 from hashicorp/b-output-dup
config: variable names and outputs must be unique
2016-08-26 13:57:59 -07:00
Mitchell Hashimoto 0fceeaaeb0
config: test for var uniqueness in overrides 2016-08-26 13:48:21 -07:00
Mitchell Hashimoto 8a3559560d
config: JSON resource keys with only one item load properly GH-5140
When a resource has only a single key set, the HCL parser treats that
key as part of the overall set of object keys. This isn't valid since
we expect resources to have exactly two keys. In this scenario, we have
to "unwrap" the keys back into a set of objects.
2016-08-25 17:18:18 -07:00
Mitchell Hashimoto fbf06e2a59
config: vars must be unique 2016-08-25 14:51:49 -07:00
Mitchell Hashimoto 099293b690
config: outputs must be unique 2016-08-25 14:43:57 -07:00
Mitchell Hashimoto f4faf2274b
config: count can't be a SimpleVariable 2016-08-16 13:48:12 -07:00
Paul Hinze ffa29090ec
core: Better error for dot indexing on user vars
Dot indexing worked in the "regexps and strings" world of 0.6.x, but it
no longer works on the 0.7 series w/ proper List / Map types.

There is plenty of dot-indexed config out in the wild, so we need to do
what we can to point users to the new syntax.

Here is one place we can do it for user variables (`var.somemap`). We'll
also need to address Resource Variables and Module Variables in a
separate PR.

This fixes the panic in #7103 - a proper error message is now returned.
2016-06-12 10:45:48 -05:00
James Nugent 01cd596c60 core: Fix detection of empty list/map defaults
This commit changes config parsing from weak decoding lists and maps
into []string and map[string]string respectively to decode into
[]interface{} and map[string]interface{} respectively. This is in order
to take advantage of the work integrated in #7082 to defeat the backward
compatibility features of the mapstructure library.

Test coverage of loading empty variables and validating their default
types against expectation.
2016-06-12 11:19:03 +02:00
Martin Atkins 860140074f config: Data source loading
This allows the config loader to read "data" blocks from the config and
turn them into DataSource objects.

This just reads the data from the config file. It doesn't validate the
data nor do anything useful with it.
2016-05-14 08:26:35 -07:00
James Nugent f49583d25a core: support native list variables in config
This commit adds support for native list variables and outputs, building
up on the previous change to state. Interpolation functions now return
native lists in preference to StringList.

List variables are defined like this:

variable "test" {
    # This can also be inferred
    type = "list"
    default = ["Hello", "World"]
}

output "test_out" {
    value = "${var.a_list}"
}
This results in the following state:

```
...
            "outputs": {
                "test_out": [
                    "hello",
                    "world"
                ]
            },
...
```

And the result of terraform output is as follows:

```
$ terraform output
test_out = [
  hello
  world
]
```

Using the output name, an xargs-friendly representation is output:

```
$ terraform output test_out
hello
world
```

The output command also supports indexing into the list (with
appropriate range checking and no wrapping):

```
$ terraform output test_out 1
world
```

Along with maps, list outputs from one module may be passed as variables
into another, removing the need for the `join(",", var.list_as_string)`
and `split(",", var.list_as_string)` which was previously necessary in
Terraform configuration.

This commit also updates the tests and implementations of built-in
interpolation functions to take and return native lists where
appropriate.

A backwards compatibility note: previously the concat interpolation
function was capable of concatenating either strings or lists. The
strings use case was deprectated a long time ago but still remained.
Because we cannot return `ast.TypeAny` from an interpolation function,
this use case is no longer supported for strings - `concat` is only
capable of concatenating lists. This should not be a huge issue - the
type checker picks up incorrect parameters, and the native HIL string
concatenation - or the `join` function - can be used to replicate the
missing behaviour.
2016-05-10 14:49:14 -04:00
Paul Hinze 567a9b9e06 config: remove missing equals test to fix build
This is behavior that's covered in the parser now - and the error
message is nicer to boot!
2016-03-21 10:39:20 -05:00
Paul Hinze 3f72837f4b core: Make copies when creating destroy nodes
Fixes an interpolation race that was occurring when a tainted destroy
node and a primary destroy node both tried to interpolate a computed
count in their config. Since they were sharing a pointer to the _same_
config, depending on how the race played out one of them could catch the
config uninterpolated and would then throw a syntax error.

The `Copy()` tree implemented for this fix can probably be used
elsewhere - basically we should copy the config whenever we drop nodes
into the graph - but for now I'm just applying it to the place that
fixes this bug.

Fixes #4982 - Includes a test covering that race condition.
2016-02-09 09:25:16 -06:00
James Nugent cb6cb8b96a core: Support explicit variable type declaration
This commit adds support for declaring variable types in Terraform
configuration. Historically, the type has been inferred from the default
value, defaulting to string if no default was supplied. This has caused
users to devise workarounds if they wanted to declare a map but provide
values from a .tfvars file (for example).

The new syntax adds the "type" key to variable blocks:

```
variable "i_am_a_string" {
    type = "string"
}

variable "i_am_a_map" {
    type = "map"
}
```

This commit does _not_ extend the type system to include bools, integers
or floats - the only two types available are maps and strings.

Validation is performed if a default value is provided in order to
ensure that the default value type matches the declared type.

In the case that a type is not declared, the old logic is used for
determining the type. This allows backwards compatiblity with previous
Terraform configuration.
2016-01-24 11:40:02 -06:00
Paul Hinze 87a9701f91 config: validation error when output is missing value field
Also lists out invalid keys in errmsg when they are present

Closes #4398
2016-01-20 14:00:36 -06:00
Mitchell Hashimoto 99fbb91ba2 config: validate lifecycle keys [GH-4413] 2016-01-19 11:28:45 -08:00
Paul Hinze b6626eed57 config: friendlier error message on resource arity mismatch
closes #2072
2015-12-09 18:05:49 -06:00
James Nugent 5ea25363a1 Add regression test for #4069
This may be brittle as it makes use of .gitattributes to override the
autocrlf setting in order to have an input file with Windows line
endings across multiple platforms.
2015-12-01 13:37:18 -05:00