I missed this earlier because my link checker was collapsing the two links from
this page to that page into a single report.
For posterity's sake, I'm linking directly to the markdown file in GitHub at an
appropriate tag version. I do not expect anyone to ever click this link again,
though.
So far the output command has had a default output format intended for
human consumption and a JSON output format intended for machine
consumption.
However, until Terraform v0.14 the default output format for primitive
types happened to be _almost_ a raw string representation of the value,
and so users started using that as a more convenient way to access
primitive-typed output values from shell scripts, avoiding the need to
also use a tool like "jq" to decode the JSON.
Recognizing that primitive-typed output values are common and that
processing them with shell scripts is common, this commit introduces a new
-raw mode which is explicitly intended for that use-case, guaranteeing
that the result will always be the direct result of a string conversion
of the output value, or an error if no such conversion is possible.
Our policy elsewhere in Terraform is that we always use JSON for
machine-readable output. We adopted that policy because our other
machine-readable output has typically been complex data structures rather
than single primitive values. A special mode seems justified for output
values because it is common for root module output values to be just
strings, and so it's pragmatic to offer access to the raw value directly
rather than requiring a round-trip through JSON.
This is a repeated cause of confusion and questions in the community
forum, because both JSON and YAML valid syntax are hard to generate using
just string concatenation. Terraform has built-in functions for both of
these common serializations to avoid those problems, and so this will
hopefully make these better alternatives more discoverable.
When we did the earlier documentation rework for Terraform v0.12 we still
had one big "Expressions" page talking about the various operators and
constructs, and so we had to be a bit economical with the details about
some more complicated constructs in order to avoid the page becoming even
more overwhelming.
However, we've recently reorganized the language documentation again so
that the expressions section is split across several separate pages, and
that gives some freedom to go into some more detail about and show longer
examples for certain features.
My changes here are not intended to be an exhaustive rewrite but I did
try to focus on some areas I've commonly seen questions about when helping
in the community forum and elsewhere, and also to create a little more
connectivity between the different content so readers can hopefully find
what they are looking for more easily when they're not yet sure what
terminology to look for.
As of Terraform 0.13+, the get-plugins command has been
superceded by new provider installation mechanisms, and
general philosophy (providers are always installed, but
the sources may be customized). Updat the init command
to give users a warning if they are setting this flag,
to encourage them to remove it from their workflow, and
update relevant docs and docstrings as well
I originally drafted these docs in a context where I was relying on
GitHub's Markdown renderer, and carelessly imported them into the
Terraform website without verifying that the website's Markdown renderer
could process it. This particular quirk has bitten us before: the website
Markdown parser expects follow-on paragraphs in a list item to be indented
at least four spaces, and with less than that it ignores the leading
whitespace altogether and just understands a normal paragraph.
This change will cause the follow-on paragraphs to now correctly render
as part of the bullet points they are intended to be attached to.
This is under a heading "Sensitive Resource Attributes" on the assumption
that if we later stabilize this feature then this heading will live on
with some different content that describes the propagation of sensitive
values from resource attributes, rather than describing the experiment.
The resources, expressions, and modules pages were all split into smaller, more
navigable pages, but the old URLs had accumulated a large number of deep links
to their section headers. To help people recover when they click an old link, we
converted those old URLs to landing pages, which preserve all of the old in-page
anchors and point readers to the appropriate new destinations.
However, because the new link-to-new-page sections are so small, it was kind of
hard to tell which section you had clicked into! Especially if you were near the
bottom of the page and the browser wasn't able to position the desired section
at the very top of the window.
This commit aims to improve that by putting one full screen of whitespace in
between every linkable section on these landing pages. Yes, it's a hack, but
you're meant to only view these pages for three seconds or so before moving on
to the place you wanted to be, and this should help dispel any confusion about
which place that is.
This tutorial uses references to local values, conditional expressions,
and splat expressions, so I've added it to those pages as well as the
expressions overview.
We've historically made statements like this in response to requests for
more customization to the "terraform fmt" behavior, but the documentation
itself was somewhat vague about the intended goals of this command.
This is an attempt to be more explicit that consistency between codebases
is the primary goal of this command, and that the examples in the
Terraform documentation are our main guide for what is "idiomatic style"
when adding additional rules over time.
Nothing here is intended to be new policy, but instead as codifying
positions we've taken elsewhere in the past in the hope of allowing users
to decide how (and whether) they wish to make use of this tool.
When using the enhanced remote backend, a subset of all Terraform
operations are supported. Of these, only plan and apply can be executed
on the remote infrastructure (e.g. Terraform Cloud). Other operations
run locally and use the remote backend for state storage.
This causes problems when the local version of Terraform does not match
the configured version from the remote workspace. If the two versions
are incompatible, an `import` or `state mv` operation can cause the
remote workspace to be unusable until a manual fix is applied.
To prevent this from happening accidentally, this commit introduces a
check that the local Terraform version and the configured remote
workspace Terraform version are compatible. This check is skipped for
commands which do not write state, and can also be disabled by the use
of a new command-line flag, `-ignore-remote-version`.
Terraform version compatibility is defined as:
- For all releases before 0.14.0, local must exactly equal remote, as
two different versions cannot share state;
- 0.14.0 to 1.0.x are compatible, as we will not change the state
version number until at least Terraform 1.1.0;
- Versions after 1.1.0 must have the same major and minor versions, as
we will not change the state version number in a patch release.
If the two versions are incompatible, a diagnostic is displayed,
advising that the error can be suppressed with `-ignore-remote-version`.
When this flag is used, the diagnostic is still displayed, but as a
warning instead of an error.
Commands which will not write state can assert this fact by calling the
helper `meta.ignoreRemoteBackendVersionConflict`, which will disable the
checks. Those which can write state should instead call the helper
`meta.remoteBackendVersionCheck`, which will return diagnostics for
display.
In addition to these explicit paths for managing the version check, we
have an implicit check in the remote backend's state manager
initialization method. Both of the above helpers will disable this
check. This fallback is in place to ensure that future code paths which
access state cannot accidentally skip the remote version check.
The Registry is a web service whose behavior isn't directly tied to Terraform
core's release cycle; therefore, its docs should be decoupled from that release
cycle as well.
https://github.com/hashicorp/terraform-website/pull/1517 adopts the registry
docs into hashicorp/terraform-website, which already hosts several other
corpuses of documentation that aren't tied to Terraform core's version (like
Terraform Cloud, Terraform Enterprise, and Extending Terraform). Once that PR is
merged, we should remove the registry docs from this repository to avoid
confusing anyone.
The local-exec provisioner documentation includes an example which refers
to an attribute of the current resource using its full traversal path,
rather than using "self" as we typically expect.
Due to some coincidences in how Terraform builds the dependency graph,
referring to the resource in this way happens to work when the resource
has only a single instance (the graph builder just skips that
self-referential dependency edge), but it fails if the user later tries
to add "count" or "for_each" to the resource, because at that point all
of the instances become dependent on one another, which creates a
dependency cycle.
Using "self" to access the current instance attributes is the usual
approach, so I've updated the documentation to show that.
As written previously this seemed to suggest using "app.terraform.io" (the
"hostname you use to access the Terraform Cloud application) to access a
private registry in Terraform Enterprise, but that isn't true and I assume
isn't what was intended.
Instead, the hostname for a Terraform Enterprise instance is the hostname
where the Terraform Enterprise application is running, which is both the
hostname where users would find its web UI and the hostname they'd use
to configure the "remote" backend for remote operations and state storage.
In order to be able to predict a result type even if arguments are not yet
known, coalesce requires all of its arguments to be of the same type. Our
usual automatic conversion rules mean that in some cases the result is
a silent type conversion rather than an explicit error, so we'll at least
document that so that folks who encounter it can understand what is
causing the likely-surprising behavior.
If we were building this function over again today I expect we'd make it
always return an error under type mismatch, but to do so now would be a
breaking change and the potential cost of that seems too high for
something that doesn't seem to arise incredibly often in practice.
This one is a lot like the previous two commits, but slightly more complex:
- Only adding one new meta-argument page, for `providers`; otherwise, it just
re-uses the dual-purpose pages I made in the resources commit.
- About that `providers` argument: The stuff that was relevant to consumers of a
module went in that meta-argument page, but there was also a huge deep dive on
how the _author_ of a re-usable module should handle provider configurations
in cases where inheriting the default providers isn't sufficient. THAT, I
moved into a new page in the module development section. (For the consumer of
a module, this should all be an implementation detail; the module README
should tell you which aliased providers you need to configure and pass, and
then you just do it, without worrying about proxy configuration blocks etc.)
- The "standard module structure" recommendations in the main module development
page gets a page of its own, to make it more prominent and discoverable.
- Same deal with using the old URL as a landing page, at least for the main
module calls page. It didn't seem necessary for the module development page.
- Resource behavior gets its own page.
- Meta-arguments all get their own pages.
- Stuff about resource syntax itself gets a page.
In the process of breaking the meta-arguments out into their own pages, I
revised them (with the exception of `provider`) so that they apply to both
resources and modules.
Like with Expressions, this commit repurposes the old resources.html URL as a
landing page for old links.
This commit converts the previous URL for this content to a landing page, which
captures all of the previous in-page anchors and directs readers to the new home
for each section.
For some time now we've been recommending explicitly passing data between
configurations using separate resource types and data sources, rather than
always using terraform_remote_state, for reasons including reducing
coupling between subsystems and allowing a configuration's state snapshots
to be under restrictive access controls.
However, those recommendations have so far not appeared directly in the
documentation for terraform_remote_state, and have instead just been
alluded to elsewhere in the documentation when discussing ways to pass
data between configurations.
This change, then, is an attempt to be clear and explicit about the
recommendation and to give a variety of specific examples of how to
implement it. The terraform_remote_state data source page is admittedly
not the most obvious place in the information architecture to put a set
of alternatives to it, but it does appear that this documentation page is
where people most commonly end up when researching options in this area
and so I've put this here in an attempt to "meet people where they are".
Possibly in a future documentation reorganization we might have an
separate page specifically about sharing data between configurations, but
we don't currently have time to do that bigger reorganization. If we do so
later, the content on this page could potentially be replaced with a
summary of the recommendation and a link to another place for the details,
but the goal here is to make this information visible in the existing
location people look for it, rather than blocking until there's a better
place for it to live.
This also includes a small amount of editing of some existing content on
the page to use terminology and style more similar to how our main
configuration language documentation is written,.
Remove chef, habitat, puppet, and salt-masterless provsioners,
which follows their deprecation. Update the documentatin for these
provisioners to clarify that they have been removed from later versions
of Terraform. Adds the fmt Make target back and updates fmtcheck script
for correctness.
Some hasty, incorrect merge conflict fixing caused this page to have a
strange mix of terminology between "system" and "provider". Along with
that, there were also several editorial errors caused by text on this
page having originally been derived from the provider registry
documentation.
This documentation will now consistently talk about being a module
registry protocol rather than a provider registry protocol, and it will
consistently use the term "system" as a generic term for the final part
of the module source address, aside from noting that there is an optional
convention to name it after the "type" part of an official provider when
possible.
This is a new part of the existing module_variable_optional_attrs
experiment, because it's intended to complement the ability to declare
an input variable whose type constraint is an object type with optional
attributes. Module authors can use this to replace null values (that were
either explicitly set or implied by attribute omission) with other
non-null values of the same type.
This function is a bit more type-fussy than our functions typically are
because it's intended for use primarily with input variables that have
fully-specified type constraints, and thus it uses that type information
to help inform how the defaults data structure should be interpreted.
Other uses of this function will probably be harder today because it takes
a lot of extra annotation to build a value of a specific type if it isn't
passing through a variable type constraint. Perhaps later language
features for more general type conversion will make this more applicable,
but for now the more general form of this problem is better solved other
ways.