It doesn't make sense for a built-in provider to appear in a lock file
because built-in providers have no version independent of the version of
Terraform they are compiled into.
We also exclude legacy providers here, because they were supported only
as a transitional aid to enable the Terraform 0.13 upgrade process and
are not intended for explicit selection.
The provider installer will, once it's updated to understand dependency
locking, use this concept to decide which subset of its selections to
record in the dependency lock file for reference for future installation
requests.
This is an initial implementation of writing locks back to a file on disk.
This initial implementation is incomplete because it does not write the
changes to the new file atomically. We'll revisit that in a later commit
as we return to polish these codepaths, once we've proven out this
package's design by integrating it with Terraform's provider installer.
This is the initial implementation of the parser/decoder portion of the
new dependency lock file handler. It's currently dead code because the
caller isn't written yet. We'll continue to build out this functionality
here until we have the basic level of both load and save functionality
before introducing this into the provider installer codepath.
The version constraint parser allows "~> 2", but it behavior is identical
to "~> 2.0". Due to a quirk of the constraint parser (caused by the fact
that it supports both Ruby-style and npm/cargo-style constraints), it
ends up returning "~> 2" with the minor version marked as "unconstrained"
rather than as zero, but that means the same thing as zero in this context
anyway and so we'll prefer to stringify as "~> 2.0" so that we can be
clearer about how Terraform is understanding that version constraint.
The version argument is deprecated in Terraform v0.14 in favor of
required_providers and will be removed in a future version of terraform
(expected to be v0.15). The provider configuration documentation already
discourages use of 'version' inside provider configuration blocks, so it
only needed an extra note that it is actively deprecated.
This new option is intended to address the previous inconsistencies where
some older subcommands supported partially changing the target directory
(where Terraform would use the new directory inconsistently) where newer
commands did not support that override at all.
Instead, now Terraform will accept a -chdir command at the start of the
command line (before the subcommand) and will interpret it as a request
to direct all actions that would normally be taken in the current working
directory into the target directory instead. This is similar to options
offered by some other similar tools, such as the -C option in "make".
The new option is only accepted at the start of the command line (before
the subcommand) as a way to reflect that it is a global command (not
specific to a particular subcommand) and that it takes effect _before_
executing the subcommand. This also means it'll be forced to appear before
any other command-specific arguments that take file paths, which hopefully
communicates that those other arguments are interpreted relative to the
overridden path.
As a measure of pragmatism for existing uses, the path.cwd object in
the Terraform language will continue to return the _original_ working
directory (ignoring -chdir), in case that is important in some exceptional
workflows. The path.root object gives the root module directory, which
will always match the overriden working directory unless the user
simultaneously uses one of the legacy directory override arguments, which
is not a pattern we intend to support in the long run.
As a first step down the deprecation path, this commit adjusts the
documentation to de-emphasize the inconsistent old command line arguments,
including specific guidance on what to use instead for the main three
workflow commands, but all of those options remain supported in the same
way as they were before. In a later commit we'll make those arguments
produce a visible deprecation warning in Terraform's output, and then
in an even later commit we'll remove them entirely so that -chdir is the
single supported way to run Terraform from a directory other than the
one containing the root module configuration.
Most of the functionality for rendering output changes is covered by the
tests for ResourceChanges, as they both share the same diff renderer.
This commit adds a few tests to cover some of the output specific code.
For reasons that are unclear, these two tests just started failing on
macOS very recently. The failure looked like:
PackageDir: strings.Join({
"/",
+ "private/",
"var/folders/3h/foobar/T/terraform-test-p",
"rovidercache655312854/registry.terraform.io/hashicorp/null/2.0.0",
"/windows_amd64",
},
Speculating that the macOS temporary directory moved into the /private
directory, I added a couple of EvalSymlinks calls and the tests pass
again.
No other unit tests appear to be affected by this at the moment.
This introduces a new GraphNode, GraphNodeExecutable, which will
gradually replace GraphNodeEvalable as part of the overall removal of
EvalTree()s. Terraform's Graph.walk function will now check if a node is
GraphNodeExecutable and run walker.Execute instead of running through
the EvalTree() and Eval().
For the time being, terraform will panic if a node implements both
GraphNodeExecutable and GraphNodeEvalable. This will be removed when
we've finished removing all GraphNodeEvalable implementations.
The new GraphWalker function, Execute(), is meant to replace both
EnterEvalTree and ExitEvalTree, and wraps the call to the
GraphNodeExecutable's Execute function.
The encoding/json package escapes some HTML-specific characters to
prevent JSON from being misinterpreted when in the context of an HTML
document. Terraform 0.11 used this behaviour, and to preserve backwards
compatibility we are continuing to do so moving forward.
This commit adds an explicit test to document that this is intentional,
not a bug.
* Return an error on unlock failure
When the lock can't be released return the err even if there is no previous error with the current action. This allows faster failure in CI/CD systems. Without this failure to remove the lock would result in the failure happening on a subsequent plan or apply which slows down the feedback loop in automated systems.
* Update command/clistate/state.go
Accept review suggestion
Co-authored-by: ZymoticB <ZymoticB@users.noreply.github.com>
* add test
Co-authored-by: ZymoticB <ZymoticB@users.noreply.github.com>
Co-authored-by: Kristin Laemmert <mildwonkey@users.noreply.github.com>
We've not been using HIL in the main codepaths since Terraform 0.12, but
some references to it (and some supporting functionality in Terraform)
stuck around due to interactions with types we'd kept around to support
legacy shims.
However, removing the configs.RawConfig field from
terraform.ResourceConfig disconnects that subtree of dependencies from
everything else, allowing us to remove it. This is safe because the only
remaining uses of terraform.ResourceConfig are shims from values that
were already evaluated using the HCL 2 API, and thus they never need
the "just in time" HIL evaluation that ResourceConfig.interpolateForce
used to do.
We also had some HIL references in configs/hcl2shim that were previously
in support of the "terraform 0.12upgrade" command, but the implementation
of that command is now removed.
There was one remaining reference to HIL in a now-unused function in the
helper/schema package, which I removed entirely here.
This then allows us to remove the HIL dependency entirely, and also to
clean up some remaining old remants of the legacy "config" package that
we'd recently moved into the "configs" package pending further pruning.
The subtle difference in keywords when creating vs. accessing locals trips
people up, even more than the "variable" vs. "var" distinction. It deserves its
own subheader on the page, plus a nice noisy callout.
I've just wasted an hour to two hours trying to find the problem to finally realize that although I declare a "locals" block, it's referred to as "local". This is pretty weird! So let's be be clear about this.
The error diagnostic shown when legacy state contains resources from
in-house providers has changed, so update references to it in the 0.13
upgrade guide.
When init attempts to install a legacy provider required by state and
fails, but another provider with the same type is successfully
installed, this almost definitely means that the user is migrating an
in-house provider. The solution here is to use the `terraform state
replace-provider` subcommand.
This commit makes that next step clearer, by detecting this specific
case, and displaying a list of commands to fix the existing state
provider references.
Diagnostic detail lines sometimes contain lines which include commands
suggested for the user to execute. By convention, these start with
leading whitespace to indicate that they are not prose.
This commit changes the diagnostic formatter to wrap each line of the
detail separately, and skips word wrapping for lines prefixed with
space. This prevents ugly and confusing wrapping of long command lines.
Although we have in this same directory the protocol buffers schemas for
the static parts of the provider wire protocol, many of the protocol
messages include DynamicValue messages that are presented in a nested
dynamic serialization format.
That format was previously not documented, and was thus defined only by
the implementation. Terraform happens to use a third-party library to
implement parts of this encoding, which means that the rules were even
harder to track down from reading the code.
Regardless of how Terraform happens to implement its serialization and
deserialization of DynamicValue, it's the wire format that is contractual
and so this document is an implementation-agnostic description of the
mapping rules for serializing any Terraform Language value by reference to
a provider-defined schema.
All future changes to the rules described in here must be backward
compatible until protocol major version 6, which is not currently planned.