mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-19 17:59:05 -05:00
544 lines
20 KiB
Plaintext
544 lines
20 KiB
Plaintext
---
|
|
description: >-
|
|
Input variables allow you to customize modules without altering their source
|
|
code. Learn how to declare, define, and reference variables in configurations.
|
|
---
|
|
|
|
# Input Variables
|
|
|
|
Input variables let you customize aspects of modules without altering
|
|
the module's own source code. This functionality allows you to share modules across different
|
|
OpenTofu configurations, making your module composable and reusable.
|
|
|
|
When you declare variables in the root module of your configuration, you can
|
|
set their values using CLI options and environment variables.
|
|
When you declare them in [child modules](../../language/modules/index.mdx),
|
|
the calling module should pass values in the `module` block.
|
|
|
|
If you're familiar with traditional programming languages, it can be useful to
|
|
compare modules to function definitions:
|
|
|
|
* Input variables are like function arguments.
|
|
* [Output values](../../language/values/outputs.mdx) are like function return values.
|
|
* [Local values](../../language/values/locals.mdx) are like a function's temporary local variables.
|
|
|
|
:::note
|
|
For brevity, input variables are often referred to as just
|
|
"variables" or "OpenTofu variables" when it is clear from context what sort of
|
|
variable is being discussed. Other kinds of variables in OpenTofu include
|
|
_environment variables_ (set by the shell where OpenTofu runs) and _expression
|
|
variables_ (used to indirectly represent a value in an
|
|
[expression](../../language/expressions/index.mdx)).
|
|
:::
|
|
|
|
## Declaring an Input Variable
|
|
|
|
Each input variable accepted by a module must be declared using a `variable`
|
|
block:
|
|
|
|
```hcl
|
|
variable "image_id" {
|
|
type = string
|
|
}
|
|
|
|
variable "availability_zone_names" {
|
|
type = list(string)
|
|
default = ["us-west-1a"]
|
|
}
|
|
|
|
variable "docker_ports" {
|
|
type = list(object({
|
|
internal = number
|
|
external = number
|
|
protocol = string
|
|
}))
|
|
default = [
|
|
{
|
|
internal = 8300
|
|
external = 8300
|
|
protocol = "tcp"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
The label after the `variable` keyword is a name for the variable, which must
|
|
be unique among all variables in the same module. This name is used to
|
|
assign a value to the variable from outside and to reference the variable's
|
|
value from within the module.
|
|
|
|
The name of a variable can be any valid [identifier](../../language/syntax/configuration.mdx#identifiers)
|
|
_except_ the following: `source`, `version`, `providers`, `count`, `for_each`, `lifecycle`, `depends_on`, `locals`.
|
|
|
|
These names are reserved for meta-arguments in
|
|
[module configuration blocks](../../language/modules/syntax.mdx), and cannot be
|
|
declared as variable names.
|
|
|
|
## Arguments
|
|
|
|
OpenTofu CLI defines the following optional arguments for variable declarations:
|
|
|
|
* [`default`][inpage-default] - A default value which then makes the variable optional.
|
|
* [`type`][inpage-type] - This argument specifies what value types are accepted for the variable.
|
|
* [`description`][inpage-description] - This specifies the input variable's documentation.
|
|
* [`validation`][inpage-validation] - A block to define validation rules, usually in addition to type constraints.
|
|
* [`sensitive`][inpage-sensitive] - Limits OpenTofu UI output when the variable is used in configuration.
|
|
* [`nullable`][inpage-nullable] - Specify if the variable can be `null` within the module.
|
|
* [`deprecated`][inpage-deprecated] - Mark the variable as deprecated to warn callers about migration.
|
|
|
|
### Default values
|
|
|
|
[inpage-default]: #default-values
|
|
|
|
The variable declaration can also include a `default` argument. If present,
|
|
the variable is considered to be _optional_ and the default value will be used
|
|
if no value is set when calling the module or running OpenTofu. The `default`
|
|
argument requires a literal value and cannot reference other objects in the
|
|
configuration.
|
|
|
|
### Type Constraints
|
|
|
|
[inpage-type]: #type-constraints
|
|
|
|
The `type` argument in a `variable` block allows you to restrict the
|
|
[type of value](../../language/expressions/types.mdx) that will be accepted as
|
|
the value for a variable. If no type constraint is set then a value of any type
|
|
is accepted.
|
|
|
|
While type constraints are optional, we recommend specifying them; they
|
|
can serve as helpful reminders for users of the module, and they
|
|
allow OpenTofu to return a helpful error message if the wrong type is used.
|
|
|
|
Type constraints are created from a mixture of type keywords and type
|
|
constructors. The supported type keywords are:
|
|
|
|
* `string`
|
|
* `number`
|
|
* `bool`
|
|
|
|
The type constructors allow you to specify complex types such as
|
|
collections:
|
|
|
|
* `list(<TYPE>)`
|
|
* `set(<TYPE>)`
|
|
* `map(<TYPE>)`
|
|
* `object({<ATTR NAME> = <TYPE>, ... })`
|
|
* `tuple([<TYPE>, ...])`
|
|
|
|
The keyword `any` may be used to indicate that any type is acceptable. For
|
|
more information on the meaning and behavior of these different types, as well
|
|
as detailed information about automatic conversion of complex types, see
|
|
[Type Constraints](../../language/expressions/types.mdx).
|
|
|
|
If both the `type` and `default` arguments are specified, the given default
|
|
value must be convertible to the specified type.
|
|
|
|
### Input Variable Documentation
|
|
|
|
[inpage-description]: #input-variable-documentation
|
|
|
|
Because the input variables of a module are part of its user interface, you can
|
|
briefly describe the purpose of each variable using the optional
|
|
`description` argument:
|
|
|
|
```hcl
|
|
variable "image_id" {
|
|
type = string
|
|
description = "The id of the machine image (AMI) to use for the server."
|
|
}
|
|
```
|
|
|
|
The description should concisely explain the purpose
|
|
of the variable and what kind of value is expected. This description string
|
|
might be included in documentation about the module, and so it should be written
|
|
from the perspective of the user of the module rather than its maintainer. For
|
|
commentary for module maintainers, use comments.
|
|
|
|
### Custom Validation Rules
|
|
|
|
[inpage-validation]: #custom-validation-rules
|
|
|
|
You can specify custom validation rules for a particular variable by adding a `validation` block within the corresponding `variable` block. The example below checks whether the AMI ID has the correct syntax.
|
|
|
|
```hcl
|
|
variable "image_id" {
|
|
type = string
|
|
description = "The id of the machine image (AMI) to use for the server."
|
|
|
|
validation {
|
|
condition = length(var.image_id) > 4 && substr(var.image_id, 0, 4) == "ami-"
|
|
error_message = "The image_id value must be a valid AMI id, starting with \"ami-\"."
|
|
}
|
|
}
|
|
```
|
|
Refer to [Custom Condition Checks](../../language/expressions/custom-conditions.mdx#input-variable-validation) for more details.
|
|
|
|
### Suppressing Values in CLI Output
|
|
|
|
[inpage-sensitive]: #suppressing-values-in-cli-output
|
|
|
|
Setting a variable as `sensitive` prevents OpenTofu from showing its value in
|
|
the `plan` or `apply` output, when you use that variable elsewhere in your
|
|
configuration.
|
|
|
|
OpenTofu will still record sensitive values in the [state](../../language/state/index.mdx),
|
|
and so anyone who can access the state data will have access to the sensitive
|
|
values in cleartext. For more information, see
|
|
[_Sensitive Data in State_](../../language/state/sensitive-data.mdx).
|
|
|
|
Declare a variable as sensitive by setting the `sensitive` argument to `true`:
|
|
|
|
```hcl
|
|
variable "user_information" {
|
|
type = object({
|
|
name = string
|
|
address = string
|
|
})
|
|
sensitive = true
|
|
}
|
|
|
|
resource "some_resource" "a" {
|
|
name = var.user_information.name
|
|
address = var.user_information.address
|
|
}
|
|
```
|
|
|
|
Any expressions whose result depends on the sensitive variable will be treated
|
|
as sensitive themselves, and so in the above example the two arguments of
|
|
`resource "some_resource" "a"` will also be hidden in the plan output:
|
|
|
|
```
|
|
OpenTofu will perform the following actions:
|
|
|
|
# some_resource.a will be created
|
|
+ resource "some_resource" "a" {
|
|
+ name = (sensitive value)
|
|
+ address = (sensitive value)
|
|
}
|
|
|
|
Plan: 1 to add, 0 to change, 0 to destroy.
|
|
```
|
|
|
|
In some cases where you use a sensitive variable inside a nested block, OpenTofu
|
|
may treat the entire block as redacted. This happens for resource types where
|
|
all of the blocks of a particular type are required to be unique, and so
|
|
disclosing the content of one block might imply the content of a sibling block.
|
|
|
|
```
|
|
# some_resource.a will be updated in-place
|
|
~ resource "some_resource" "a" {
|
|
~ nested_block {
|
|
# At least one attribute in this block is (or was) sensitive,
|
|
# so its contents will not be displayed.
|
|
}
|
|
}
|
|
```
|
|
|
|
A provider can also
|
|
[declare an attribute as sensitive](https://developer.hashicorp.com/terraform/plugin/best-practices/sensitive-state#using-sensitive-flag-functionality),
|
|
which will cause OpenTofu to hide it from regular output regardless of how
|
|
you assign it a value. For more information, see
|
|
[Sensitive Resource Attributes](../../language/expressions/references.mdx#sensitive-resource-attributes).
|
|
|
|
If you use a sensitive value as part of an
|
|
[output value](../../language/values/outputs.mdx) then OpenTofu will require
|
|
you to also mark the output value itself as sensitive, to confirm that you
|
|
intended to export it.
|
|
|
|
#### Cases where OpenTofu may disclose a sensitive variable
|
|
|
|
A `sensitive` variable is a configuration-centered concept, and values are sent to providers without any obfuscation. A provider error could disclose a value if that value is included in the error message. For example, a provider might return the following error even if "foo" is a sensitive value: `"Invalid value 'foo' for field"`
|
|
|
|
If a resource attribute is used as, or part of, the provider-defined resource id, an `apply` will disclose the value. In the example below, the `prefix` attribute has been set to a sensitive variable, but then that value ("jae") is later disclosed as part of the resource id:
|
|
|
|
```
|
|
# random_pet.animal will be created
|
|
+ resource "random_pet" "animal" {
|
|
+ id = (known after apply)
|
|
+ length = 2
|
|
+ prefix = (sensitive value)
|
|
+ separator = "-"
|
|
}
|
|
|
|
Plan: 1 to add, 0 to change, 0 to destroy.
|
|
|
|
...
|
|
|
|
random_pet.animal: Creating...
|
|
random_pet.animal: Creation complete after 0s [id=jae-known-mongoose]
|
|
```
|
|
|
|
### Disallowing Null Input Values
|
|
|
|
[inpage-nullable]: #disallowing-null-input-values
|
|
|
|
The `nullable` argument in a variable block controls whether the module caller
|
|
may assign the value `null` to the variable.
|
|
|
|
```hcl
|
|
variable "example" {
|
|
type = string
|
|
nullable = false
|
|
}
|
|
```
|
|
|
|
The default value for `nullable` is `true`. When `nullable` is `true`, `null`
|
|
is a valid value for the variable, and the module configuration must always
|
|
account for the possibility of the variable value being `null`. Passing a
|
|
`null` value as a module input argument will override any `default` value.
|
|
|
|
Setting `nullable` to `false` ensures that the variable value will never be
|
|
`null` within the module. If `nullable` is `false` and the variable has a
|
|
`default` value, then OpenTofu uses the default when a module input argument is `null`.
|
|
|
|
The `nullable` argument only controls where the direct value of the variable may be `null`.
|
|
For variables of collection or structural types, such as lists or objects,
|
|
the caller may still use `null` in nested elements or attributes, as long as
|
|
the collection or structure itself is not null.
|
|
|
|
### Marking variable as deprecated
|
|
|
|
[inpage-deprecated]: #marking-variable-as-deprecated
|
|
|
|
:::warning
|
|
This feature is considered experimental and the final UX may change in the future.
|
|
:::
|
|
|
|
The `deprecated` argument in a variable block indicates its deprecation and potential
|
|
removal in the future. This attribute should contain non-empty string and should provide
|
|
instructions on how to migrate away from usage of this variable. Here is an example of the
|
|
configuration:
|
|
|
|
```hcl
|
|
variable "examle" {
|
|
type = string
|
|
deprecated = "'examle' variable must no longer be used due to a typo, use 'example' instead"
|
|
}
|
|
```
|
|
|
|
The caller of the module will receive a warning if the deprecated variable is used in
|
|
their configuration:
|
|
|
|
```
|
|
│ Warning: Variable marked as deprecated by the module author
|
|
│
|
|
│ on main.tf line 3, in module "mod":
|
|
│ 3: examle = "a"
|
|
│
|
|
│ Variable "examle" is marked as deprecated with the following message:
|
|
│ 'examle' variable must no longer be used due to a typo, use 'example' instead
|
|
```
|
|
|
|
Deprecation warnings can be filtered or disabled by using the `-deprecation` CLI argument. For more details, check its description
|
|
in the command options for [plan](../../cli/commands/plan.mdx#other-options) and [apply](../../cli/commands/apply.mdx#apply-options).
|
|
## Using Input Variable Values
|
|
|
|
Within the module that declared a variable, its value can be accessed from
|
|
within [expressions](../../language/expressions/index.mdx) as `var.<NAME>`,
|
|
where `<NAME>` matches the label given in the declaration block:
|
|
|
|
:::note
|
|
Input variables are _created_ by a `variable` block, but you
|
|
_reference_ them as attributes on an object named `var`.
|
|
:::
|
|
|
|
```hcl
|
|
resource "aws_instance" "example" {
|
|
instance_type = "t2.micro"
|
|
ami = var.image_id
|
|
}
|
|
```
|
|
|
|
The value assigned to a variable can only be accessed in expressions within
|
|
the module where it was declared.
|
|
|
|
## Assigning Values to Root Module Variables
|
|
|
|
When variables are declared in the root module of your configuration, they
|
|
can be set in a number of ways:
|
|
|
|
* Individually, with the `-var` command line option.
|
|
* In variable definitions (`.tfvars`) files, either specified on the command line
|
|
or automatically loaded.
|
|
* As environment variables.
|
|
|
|
The following sections describe these options in more detail. This section does
|
|
not apply to _child_ modules, where values for input variables are instead
|
|
assigned in the configuration of their parent module, as described in
|
|
[_Modules_](../../language/modules/index.mdx).
|
|
|
|
### Variables on the Command Line
|
|
|
|
To specify individual variables on the command line, use the `-var` option
|
|
when running the `tofu plan` and `tofu apply` commands:
|
|
|
|
```
|
|
tofu apply -var="image_id=ami-abc123"
|
|
tofu apply -var='image_id_list=["ami-abc123","ami-def456"]' -var="instance_type=t2.micro"
|
|
tofu apply -var='image_id_map={"us-east-1":"ami-abc123","us-east-2":"ami-def456"}'
|
|
```
|
|
|
|
The above examples show appropriate syntax for Unix-style shells, such as on
|
|
Linux or macOS. For more information on shell quoting, including additional
|
|
examples for Windows Command Prompt, see
|
|
[Input Variables on the Command Line](../../cli/commands/plan.mdx#input-variables-on-the-command-line).
|
|
|
|
You can use the `-var` option multiple times in a single command to set several
|
|
different variables.
|
|
|
|
<a id="variable-files"></a>
|
|
|
|
### Variable Definitions (`.tfvars`) Files
|
|
|
|
To set lots of variables, it is more convenient to specify their values in
|
|
a _variable definitions file_ (with a filename ending in either `.tfvars`
|
|
or `.tfvars.json`) and then specify that file on the command line with
|
|
`-var-file`:
|
|
|
|
```
|
|
tofu apply -var-file="testing.tfvars"
|
|
```
|
|
|
|
A variable definitions file uses the same basic syntax as OpenTofu language
|
|
files, but consists only of variable name assignments:
|
|
|
|
```hcl
|
|
image_id = "ami-abc123"
|
|
availability_zone_names = [
|
|
"us-east-1a",
|
|
"us-west-1c",
|
|
]
|
|
```
|
|
|
|
OpenTofu also automatically loads a number of variable definitions files
|
|
if they are present:
|
|
|
|
* Files named exactly `terraform.tfvars` or `terraform.tfvars.json`.
|
|
* Any files with names ending in `.auto.tfvars` or `.auto.tfvars.json`.
|
|
|
|
Files whose names end with `.json` are parsed instead as JSON objects, with
|
|
the root object properties corresponding to variable names:
|
|
|
|
```json
|
|
{
|
|
"image_id": "ami-abc123",
|
|
"availability_zone_names": ["us-west-1a", "us-west-1c"]
|
|
}
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
As a fallback for the other ways of defining variables, OpenTofu searches
|
|
the environment of its own process for environment variables named `TF_VAR_`
|
|
followed by the name of a declared variable.
|
|
|
|
This can be useful when running OpenTofu in automation, or when running a
|
|
sequence of OpenTofu commands in succession with the same variables.
|
|
For example, at a `bash` prompt on a Unix system:
|
|
|
|
```
|
|
$ export TF_VAR_image_id=ami-abc123
|
|
$ tofu plan
|
|
...
|
|
```
|
|
|
|
On operating systems where environment variable names are case-sensitive,
|
|
OpenTofu matches the variable name exactly as given in configuration, and
|
|
so the required environment variable name will usually have a mix of upper
|
|
and lower case letters as in the above example.
|
|
|
|
### Complex-typed Values
|
|
|
|
When variable values are provided in a variable definitions file, you can use
|
|
OpenTofu's usual syntax for
|
|
[literal expressions](../../language/expressions/types.mdx#literal-expressions)
|
|
to assign complex-typed values, like lists and maps.
|
|
|
|
Some special rules apply to the `-var` command line option and to environment
|
|
variables. For convenience, OpenTofu defaults to interpreting `-var` and
|
|
environment variable values as literal strings, which need only shell quoting,
|
|
and no special quoting for OpenTofu. For example, in a Unix-style shell:
|
|
|
|
```
|
|
$ export TF_VAR_image_id='ami-abc123'
|
|
```
|
|
|
|
However, if a root module variable uses a [type constraint](#type-constraints)
|
|
to require a complex value (list, set, map, object, or tuple), OpenTofu will
|
|
instead attempt to parse its value using the same syntax used within variable
|
|
definitions files, which requires careful attention to the string escaping rules
|
|
in your shell:
|
|
|
|
```
|
|
$ export TF_VAR_availability_zone_names='["us-west-1b","us-west-1d"]'
|
|
```
|
|
|
|
For readability, and to avoid the need to worry about shell escaping, we
|
|
recommend always setting complex variable values via variable definitions files.
|
|
For more information on quoting and escaping for `-var` arguments,
|
|
see
|
|
[Input Variables on the Command Line](../../cli/commands/plan.mdx#input-variables-on-the-command-line).
|
|
|
|
### Values for Undeclared Variables
|
|
|
|
If you have defined a variable value, but not its corresponding `variable {}`
|
|
definition, you may get an error or warning depending on how you have provided
|
|
that value.
|
|
|
|
If you provide values for undeclared variables defined as [environment variables](#environment-variables)
|
|
you will not get an error or warning. This is because environment variables may
|
|
be declared but not used in all configurations that might be run.
|
|
|
|
If you provide values for undeclared variables defined [in a file](#variable-definitions-tfvars-files)
|
|
you will get a warning. This is to help in cases where you have provided a variable
|
|
value _meant_ for a variable declaration, but perhaps there is a mistake in the
|
|
value definition. For example, the following configuration:
|
|
|
|
```hcl
|
|
variable "moose" {
|
|
type = string
|
|
}
|
|
```
|
|
|
|
And the following `.tfvars` file:
|
|
|
|
```hcl
|
|
mosse = "Moose"
|
|
```
|
|
|
|
Will cause OpenTofu to warn you that there is no variable declared `"mosse"`, which can help
|
|
you spot this mistake.
|
|
|
|
If you use `.tfvars` files across multiple configurations and expect to continue to see this warning,
|
|
you can use the [`-compact-warnings`](../../cli/commands/plan.mdx#compact-warnings)
|
|
option to simplify your output.
|
|
|
|
If you provide values for undeclared variables on the [command line](#variables-on-the-command-line),
|
|
OpenTofu will return an error. To avoid this error, either declare a variable block for the value, or remove
|
|
the variable value from your OpenTofu call.
|
|
|
|
### Variable Definition Precedence
|
|
|
|
The above mechanisms for setting variables can be used together in any
|
|
combination. If the same variable is assigned multiple values, OpenTofu uses
|
|
the _last_ value it finds, overriding any previous values. Note that the same
|
|
variable cannot be assigned multiple values within a single source.
|
|
|
|
OpenTofu loads variables in the following order, with later sources taking
|
|
precedence over earlier ones:
|
|
|
|
* Environment variables
|
|
* The `terraform.tfvars` file, if present.
|
|
* The `terraform.tfvars.json` file, if present.
|
|
* Any `*.auto.tfvars` or `*.auto.tfvars.json` files, processed in lexical order
|
|
of their filenames.
|
|
* Any `-var` and `-var-file` options on the command line, in the order they
|
|
are provided.
|
|
|
|
:::warning Important
|
|
Variables with map and object
|
|
values behave the same way as other variables: the last value found overrides
|
|
the previous values. This is a change from previous versions of OpenTofu, which
|
|
would _merge_ map values instead of overriding them.
|
|
:::
|