* Make sidebar nav in language docs more intuitive
* Minor display fixes for registry docs
* Explain providers in the registry in the providers index
* Revise a bunch of language docs around provider reqs
This is mostly an effort to smooth out some of the explanations, make sure
things are presented in a helpful order, make sure terminology lines up, draw
connections between related concepts, make default behavior more apparent, and
the like. It shouldn't include very much new information, but there might be one
or two things that came out of a conversation somewhere.
Co-authored-by: Judith Malnick <judith@hashicorp.com>
As part of documenting the new module for_each capabilities we added a
section noting that shared modules using the legacy pattern of declaring
their own provider configurations would not be compatible with them.
However, that also applies to the new module depends_on and several folks
participating in the beta pointed out that the documentation wasn't
discussing that at all.
In order to generalize the advice, I've moved the old content we had
(since v0.11) recommending against provider configurations in shared
modules out into its own section, now being more explicit that it is
a legacy pattern and not recommended, and then folded the content about
for_each and count, now also including depends_on, into that expanded
section.
As is often the case, that had some knock-on effects on the content on
the rest of this page, so there's some general editing and reorganization
here. In particular, I moved the "Multiple Instances of a Module" section
much further up the page because it's content relevant to users of
shared modules, while the later content on this page is more aimed at
authors of shared modules, including the new section about the legacy
pattern.
We previously covered everything about using providers on a single page,
but that was getting unwieldy already and we now have a lot more to
discuss with v0.13 introducing a new source address syntax and some other
concepts.
Here we split the provider-related content into two parts: "Provider
Requirements" covers how to find and declare dependencies on providers,
and then "Provider Configuration" (formerly just "Providers") then focuses
primarily on how to write zero or more provider configurations for a
particular provider.
Because "Provider Requirements" is now presented before "Provider
Configuration" in the navigation, I've also moved some of the introductory
content about providers in general onto the "Requirements" page. The
first paragraph of that content is duplicated onto the "Configuration"
page for discoverability, but we now link to the requirements page to get
the full story.
The "Configuration Language" section was becoming rather unweildy, both
by having a lot of pages and by some of the pages being quite large in
themselves.
This is a first step towards breaking things up a little more, starting
with two changes:
- The "Configuration Language" navigation is now split into two
sub-headings "Configuration Blocks" and "Syntax".
- Some of the information about sub-blocks of the "terraform" block are
now given their own pages, because their content is quite complex
in itself.
- "Version Constraints" is now a page in its own right, rather than this
content being duplicated in slightly different forms across multiple
contexts that make use of user-specified version constraints.
When helping folks in the community forum, I commonly see questions around
more complex patterns in transforming deep data structures into different
shapes to work with for_each. We have examples of these patterns in the
docs for the functions that they rely on, but they were not previously
very discoverable in the main configuration language documentation
sections.
Here I've moved the "Using Expressions in for_each" subsection on the
Resources page above some of the other sub-sections to hopefully make it
easier to see, and written out in more detail the two specific patterns
that answer a significant number of for_each-related user questions in
the hope that readers will be more likely to realize that the links are
relevant to what their goals.
I also added some more elaboration about the behavior of converting from
list to set in the "Using Sets" subsection, because this feature is often
a user's first encounter with the set data type and I've inferred from
some of the questions I've answered that a number of Terraform users don't
have prior experience with set data types in other languages to draw
assumptions from.
Finally, I added some similar links to the for_each patterns within the
for expression documentation itself, to try to make those examples more
visible to those who might be discovering the documentation in a different
sequence, e.g. by following a deep link shared in an answer to a question
in the community forum.
All of the feedback from the experiment described enhancements that can
potentially be added later without breaking changes, so this change simply
removes the experiment gate from the feature as originally implemented
with no changes to its functionality.
Further enhancements may follow in later releases, but the goal of this
change is just to ship the feature exactly as it was under the experiment.
Most of the changes here are cleaning up the experiment opt-ins from our
test cases. The most important parts are in configs/experiments.go and in
experiments/experiment.go .
This is an initial draft of documentation for this new feature of the
CLI configuration. This is mainly intended as a placeholder for now,
because there are other documentation updates pending for the new provider
namespacing and installation scheme and we'll likely want to revise these
docs to better complement the broader documentation once it's written.
Implement a new provider_meta block in the terraform block of modules, allowing provider-keyed metadata to be communicated from HCL to provider binaries.
Bundled in this change for minimal protocol version bumping is the addition of markdown support for attribute descriptions and the ability to indicate when an attribute is deprecated, so this information can be shown in the schema dump.
Co-authored-by: Paul Tyng <paul@paultyng.net>
Previously the templatefile function would permit any arbitrary string as
a variable name, but due to the HCL template syntax it would be impossible
to refer to one that isn't a valid HCL identifier without causing an
HCL syntax error.
The HCL syntax errors are correct, but don't really point to the root
cause of the problem. Instead, we'll pre-verify that the variable names
are valid before we even try to render the template, and given a
specialized error message that refers to the vars argument expression as
the problematic part, which will hopefully make the resolution path
clearer for a user encountering this situation.
The syntax error still remains for situations where all of the variable
names are correct but e.g. the user made a typo referring to one, which
makes sense because in that case the problem _is_ inside the template.
* add setdifference and setsubtract functions and docs
* remove setdifference as it is not implemented correct in underlying lib
* Update setintersection.html.md
* Update setproduct.html.md
* Update setunion.html.md
This guide now lives at:
- https://learn.hashicorp.com/terraform#getting-started
...and terraform.io has been redirecting to there for quite a while. This commit
removes the extra copy so that the text of the two versions doesn't drift, and
updates existing links to point to the new location.
The existing "type" argument allows specifying a type constraint that
allows for some basic validation, but often there are more constraints on
a variable value than just its type.
This new feature (requiring an experiment opt-in for now, while we refine
it) allows specifying arbitrary validation rules for any variable which
can then cause custom error messages to be returned when a caller provides
an inappropriate value.
variable "example" {
validation {
condition = var.example != "nope"
error_message = "Example value must not be \"nope\"."
}
}
The core parts of this are designed to do as little new work as possible
when no validations are specified, and thus the main new checking codepath
here can therefore only run when the experiment is enabled in order to
permit having validations.
These are intended to make it easier to work with arbitrary data
structures whose shape might not be known statically, such as the result
of jsondecode(...) or yamldecode(...) of data from a separate system.
For example, in an object value which has attributes that may or may not
be set we can concisely provide a fallback value to use when the attribute
isn't set:
try(local.example.foo, "fallback-foo")
Using a "try to evaluate" model rather than explicit testing fits better
with the usual programming model of the Terraform language where values
are normally automatically converted to the necessary type where possible:
the given expression is subject to all of the same normal type conversions,
which avoids inadvertently creating a more restrictive evaluation model
as might happen if this were handled using checks like a hypothetical
isobject(...) function, etc.
It's a common source of errors to try to produce JSON or YAML syntax
using string concatenation via our template language but to miss some
details like correct string escaping, quoting, required commas, etc.
The jsonencode and yamlencode functions are a better way to generate JSON
and YAML, but it's not immediately obvious that both of these functions
are available for use in external templates (via templatefile) too.
Given that questions related to this come up a lot in our community forum
and elsewhere, it seems worth having a documentation section to show the
pattern of having a template that consists only of a single function call.
A very common question since we launched the two repetition constructs
is how to deal with situations where the input data structure doesn't
match one-to-one with the desired configuration.
This adds some full worked examples of two common situations that have
come up in questions. To avoid adding a lot of extra content to the
already-large "expressions" and "resources" pages, the main bulk of this
new content lives with the relevant functions themselves as a full example
of one thing they are good for, and then we'll link to them from the two
general documentation sections where folks are likely to be reading when
they encounter the problem.
Previously we were using the experimental HCL 2 repository, but now we'll
shift over to the v2 import path within the main HCL repository as part of
actually releasing HCL 2.0 as stable.
This is a mechanical search/replace to the new import paths. It also
switches to the v2.0.0 release of HCL, which includes some new code that
Terraform didn't previously have but should not change any behavior that
matters for Terraform's purposes.
For the moment the experimental HCL2 repository is still an indirect
dependency via terraform-config-inspect, so it remains in our go.sum and
vendor directories for the moment. Because terraform-config-inspect uses
a much smaller subset of the HCL2 functionality, this does still manage
to prune the vendor directory a little. A subsequent release of
terraform-config-inspect should allow us to completely remove that old
repository in a future commit.
The cidrsubnets function signature is intentionally very low-level and
focused on the core requirement of generating addresses. This registry
module then wraps it with some additional functionality to make it more
convenient to generate and use subnet address ranges.
This is a companion to cidrsubnet that allows bulk-allocation of multiple
subnet addresses at once, with automatic numbering.
Unlike cidrsubnet, cidrsubnets allows each of the allocations to have a
different prefix length, and will pack the networks consecutively into the
given address space. cidrsubnets can potentially create more complicated
addressing schemes than cidrsubnet alone can, because it's able to take
into account the full set of requested prefix lengths rather than just
one at a time.
* website/formatdate: update example
The given example was showing HOUR:MONTH instead of HOUR:MINUTE
Fixes#22598
* website/import: remove reference to no-longer-working option
Users can no longer supply `-config=""` to tell Terraform not to load
configuration for import.
Fixes#22294
* website/provisioners: `host` is required in connection blocks
Fixes#21877
* website/variables: clarify variable definition precedence
It was not entirely obvious that a variable could not be assigned
multiples times in a single source.
Fixes#21682
* website/backend/local: add `workspace_dir` attribute
Fixes#21391
* website/output: `sensitive` outputs are redacted in output
Fixes#21502
* website/backends: sidebar order tweak
It makes sense for backend 'configuration' to appear before 'init'.
Fixes#13796
* Revert "website/formatdate: update example"
This reverts commit ccd93c86ddd15a21625c0767702ee1cc62e77254.
Reference: https://github.com/hashicorp/terraform/issues/16697
Enumerates a set of regular file names from a given glob pattern. Implemented via the Go stdlib `path/filepath.Glob()` functionality. Notably, stdlib does not support `**` or `{}` extended patterns. See also: https://github.com/golang/go/issues/11862
To support the extended glob patterns, it will require adding a dependency on a third party library or adding our own matching code.
The Terraform Enterprise brand has now been split into two parts:
- Terraform Cloud is the application that helps teams use Terraform together,
with remote state storage, a shared run environment, etc.
- Terraform Enterprise is the on-premise distribution that lets enterprises run
a private instance of the Terraform Cloud application.
The former TFE docs have been split accordingly.
- Make these descriptions more similar, since they do basically the same thing.
- Add some subheaders to break up the wall of text and make it more skimmable.
- Nudge people more firmly toward `for_each` if they need to actually
incorporate data from a variable into their instances.
- Add version note so you know whether you can use this yet.
These existing upstream cty functions allow matching strings against
regular expression patterns, which can be useful if you need to consume
a non-standard string format that Terraform doesn't (and can't) have a
built-in function for.
We added the csvdecode function originally with the intent of it being
used with for_each, but because csvdecode was released first we had a
section in its documentation warning about the downsides of using it with
"count", since that seemed like something people would be likely to try.
With resource "for_each" now merged, we can replace that scary section
with a more positive example of using these two features together.
We still include a paragraph noting that "count" _could_ be used here, but
with a caution against doing so. This is in the hope of helping users
understand the difference between these two patterns and why for_each is
the superior choice for most situations.
The search "terraform leading zero" does not find the `format()`
function, which is perfectly capable of adding leading zeros.
Thus I have added this one word to help people find `format()`.
This also includes a previously-missing test that verifies the behavior
described here, implemented as a planning context test for consistency
with how the other ignore_changes tests are handled.
There have been a few questions about this so far which indicated that the
previous docs for this feature were very lacking. This is an attempt to
describe more completely what "any" means, and in particular that it isn't
actually a type at all but rather a placeholder for a type to be selected
dynamically.
Based on some common questions and feedback since the v0.12.0 release,
here we add some small additional content to the documentation for
"dynamic" blocks, covering how to access the keys of the collection being
iterated over and how to fold multiple collections into a single one to
achieve the effect of a nested iteration.
These follow the same principle as jsondecode and jsonencode, but use
YAML instead of JSON.
YAML has a much more complex information model than JSON, so we can only
support a subset of it during decoding, but hopefully the subset supported
here is a useful one.
Because there are many different ways to _generate_ YAML, the yamlencode
function is forced to make some decisions, and those decisions are likely
to affect compatibility with other real-world YAML parsers. Although the
format here is intended to be generic and compatible, we may find that
there are problems with it that'll we'll want to adjust for in a future
release, so yamlencode is therefore marked as experimental for now until
the underlying library is ready to commit to ongoing byte-for-byte
compatibility in serialization.
The main use-case here is met by yamldecode, which will allow reading in
files written in YAML format by humans for use in Terraform modules, in
situations where a higher-level input format than direct Terraform
language declarations is helpful.
This is similar to the function of the same name in Python, generating a
sequence of numbers as a list that can then be used in other
sequence-oriented operations.
The primary use-case for it is to turn a count expressed as a number into
a list of that length, which can then be iterated over or passed to a
collection function to produce that number of something else, as shown
in the example at the end of its documentation page.
- Note that we intentionally omitted it from the sidebar, to reduce confusion.
- Write a summary up top so you can stop reading sooner if you don't actually need this.
* lang/funcs: testing of functions through the lang package API
The function-specific unit tests do not cover the HCL conversion that happens when the functions are called in a terraform configuration. For e.g., HCL converts sets to lists before passing it to the function. This means that we could not test passing a set in the function _unit_ tests.
This adds a higher-level acceptance test, plus a check that every (pure) function has a test.
* website/docs: update function documentation
There was some leftover v0.11-style interpolation syntax here.
We prefer to use a "naked" expression in situations like this where the result
isn't a string, because interpolations returning non-strings is a common source
of confusion for new users.
* funcs/coalesce: return the first non-null, non-empty element from a
sequence.
The go-cty coalesce function, which was originally used here, returns the
first non-null element from a sequence. Terraform 0.11's coalesce,
however, returns the first non-empty string from a list of strings.
This new coalesce function aims to preserve terraform's documented
functionality while adding support for additional argument types. The
tests include those in go-cty and adapted tests from the 0.11 version of
coalesce.
* website/docs: update coalesce function document
The re-introduction of some of the ambiguity between argument and nested
block syntax (for compatibility with existing provider patterns)
unfortunately leads to some interesting consequences for attributes using
this mode.
While the behavior is generally as before in straightforward cases, this
page aims to spell out some of the different usage patterns explicitly
for the benefit of those writing more complex configurations, such as
generic re-usable modules where using argument vs. block syntax leads to
some real differences.
This page is intentionally not linked from anywhere in the part of the
website maintained in the Terraform repository. Instead, it can be linked
from the provider documentation for any argument where this pattern is
used, to help users understand the ways in which that argument might
deviate from the usual behaviors of arguments vs. nested blocks.
Some users are not accustomed to thinking of IP addresses in a bitwise
fashion, so the hope here is to give enough of an introduction to that way
of thinking for the reader to understand what the "newbits" and "netnum"
arguments represent.
For 0.11 I just specified the naming rules; for 0.12, I added some info about
referencing values and tightened up the layout of the optional arguments.
This commit also syncs up descriptions of `depends_on`.