v1 - Variables I & O
v1 - Variables I & O
io
/docs/language/values/variables.html
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,
the calling module should pass values in the module block.
»
Declaring an Input Variable
Each input variable accepted by a module must be declared using a variable
block:
variable "image_id" {
Just SKIM
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.
»
Arguments
Terraform CLI defines the following optional arguments for variable declarations:
»
Default values
»
Type Constraints
Type constraints are created from a mixture of type keywords and type
constructors. The
supported type keywords are:
string
number
bool
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.
If both the type and default arguments are specified, the given default
value must be
convertible to the specified type.
»
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:
variable "image_id" {
type = string
»
Custom Validation Rules
variable "image_id" {
type = string
validation {
The condition argument is an expression that must use the value of the
variable to
return true if the value is valid, or false if it is invalid.
The expression can refer only to
the variable that the condition applies to,
and must not produce errors.
variable "image_id" {
type = string
validation {
»
Suppressing Values in CLI Output
variable "user_information" {
type = object({
name = string
address = string
})
sensitive = true
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:
+ name = (sensitive)
+ address = (sensitive)
In some cases where you use a sensitive variable inside a nested block, Terraform
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.
~ nested_block {
»
Cases where Terraform may disclose a sensitive variable
+ length = 2
+ prefix = (sensitive)
+ separator = "-"
...
random_pet.animal: Creating...
»
Using Input Variable Values
Within the module that declared a variable, its value can be accessed from
within
expressions as var.<NAME>,
where <NAME> matches the label given in the declaration
block:
instance_type = "t2.micro"
ami = var.image_id
»
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:
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.
»
Variables on the Command Line
To specify individual variables on the command line, use the -var option
when running the
terraform plan and terraform apply commands:
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.
You can use the -var option multiple times in a single command to set several
different
variables.
»
Variable Definitions (.tfvars) Files
A variable definitions file uses the same basic syntax as Terraform language
files, but
consists only of variable name assignments:
image_id = "ami-abc123"
availability_zone_names = [
"us-east-1a",
"us-west-1c",
Files whose names end with .json are parsed instead as JSON objects, with
the root
object properties corresponding to variable names:
"image_id": "ami-abc123",
»
Environment Variables
As a fallback for the other ways of defining variables, Terraform searches
the environment
of its own process for environment variables named TF_VAR_
followed by the name of a
declared variable.
$ export TF_VAR_image_id=ami-abc123
$ terraform plan
...
»
Complex-typed Values
When variable values are provided in a variable definitions file, you can use
Terraform's
usual syntax for
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, Terraform defaults to interpreting -var and
environment variable values
as literal strings, which need only shell quoting,
and no special quoting for Terraform. For
example, in a Unix-style shell:
$ export TF_VAR_image_id='ami-abc123'
$ 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.
»
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.
variable "moose" {
type = string
Will cause Terraform 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
option to simplify your output.
»
Variable Definition Precedence
The above mechanisms for setting variables can be used together in any
combination. If
the same variable is assigned multiple values, Terraform uses
the last value it finds,
overriding any previous values. Note that the same
variable cannot be assigned multiple
values within a single source.
Terraform 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. (This includes variables set by a Terraform Cloud
workspace.)
www.terraform.io
/docs/language/values/outputs.html
Output values are like the return values of a Terraform module, and have several
uses:
A child module can use outputs to expose a subset of its resource attributes
to a
parent module.
A root module can use outputs to print certain values in the CLI output after
running
terraform apply.
When using remote state, root module outputs can be
accessed by other
configurations via a
terraform_remote_state data source.
»
Declaring an Output Value
Each output value exported by a module must be declared using an output
block:
output "instance_ip_addr" {
value = aws_instance.server.private_ip
The label immediately after the output keyword is the name, which must be a
valid
identifier. In a root module, this name is
displayed to the user; in a child module, it can be
used to access the output's
value.
»
Accessing Child Module Outputs
In a parent module, outputs of child modules are available in expressions as
module.
<MODULE NAME>.<OUTPUT NAME>. For example, if a child module named
web_server
declared an output named instance_ip_addr, you could access that
value as
module.web_server.instance_ip_addr.
»
Optional Arguments
output blocks can optionally include description, sensitive, and depends_on
arguments, which are described in the following sections.
»
description — Output Value Documentation
Because the output values of a module are part of its user interface, you can
briefly
describe the purpose of each value using the optional description
argument:
output "instance_ip_addr" {
value = aws_instance.server.private_ip
»
sensitive — Suppressing Values in CLI Output
output "db_password" {
value = aws_db_instance.db.password
sensitive = true
# main.tf
module "foo" {
source = "./mod"
output "out" {
value = "xyz"
sensitive = true
output "a" {
value = "secret"
sensitive = true
When we run a plan or apply, the sensitive value is redacted from output:
+ some_attribute = (sensitive)
Changes to Outputs:
»
depends_on — Explicit Output Dependencies
Since output values are just a means for passing data out of a module, it is
usually not
necessary to worry about their relationships with other nodes in
the dependency graph.
However, when a parent module accesses an output value exported by one of its
child
modules, the dependencies of that output value allow Terraform to
correctly determine the
dependencies between resources defined in different
modules.
Just as with
resource dependencies,
Terraform analyzes the value expression for an
output value and automatically
determines a set of dependencies, but in less-common
cases there are
dependencies that cannot be recognized implicitly. In these rare cases,
the
depends_on argument can be used to create additional explicit dependencies:
output "instance_ip_addr" {
value = aws_instance.server.private_ip
depends_on = [
aws_security_group_rule.local_access,
The depends_on argument should be used only as a last resort. When using it,
always
include a comment explaining why it is being used, to help future
maintainers understand
the purpose of the additional dependency.