Input variables
Input variables form a configuration interface; values can come from defaults, tfvars, environment, or CLI according to precedence. Add types and validation to fail early. Do not commit secret tfvars.
variable "instance_type" {
type = string
default = "t3.micro"
}
variable "env" {
type = string
validation {
condition = contains(["dev", "test", "prod"], var.env)
error_message = "env must be dev, test, or prod."
}
}
variable "tags" {
type = map(string)
default = {}
}
Types include string, number, bool, list(...), map(...), and object({...}). terraform.tfvars and any *.auto.tfvars file load automatically; an environment variable such as TF_VAR_env=dev also sets a value. From lowest to highest, precedence runs: default, environment, tfvars files, then -var and -var-file on the command line.
| CLI | Use case |
|---|---|
-var='name=value' |
Small deliberate override |
-var-file=prod.tfvars |
Environment-specific values |
terraform output name |
Read one output |
flowchart LR TV["terraform.tfvars<br/>env = dev"] --> V["variables.tf<br/>type, default"] V --> M["module vpc<br/>source = ./modules/vpc"] DS["data source<br/>latest AMI"] --> R["resource<br/>aws_instance"] M --> R R --> O["outputs.tf<br/>instance_ip"] %% step TV: Values for one environment live in a tfvars file. %% step V: Variables declare the inputs with types, defaults and validation. %% step M: A module packages resources behind a small interface of inputs and outputs. %% step DS: Data sources read existing information, such as the latest AMI ID. %% step R: Resources use those values; count and for_each repeat them. %% step O: Outputs pass values to people or to other modules.
Data sources, locals, and outputs
data "aws_availability_zones" "available" {}
output "public_ip" {
value = aws_instance.web.public_ip
}
A data source reads; a resource manages lifecycle. locals name intermediate values so one expression is not repeated. An output is calculated from state after plan or apply and can feed other automation. sensitive = true hides normal display but does not encrypt the value in state.
Repeating resources
count = 3 creates three copies addressed as aws_instance.web[0] and so on. for_each over a map or set creates one copy per key, such as aws_instance.web["api"], which keeps addresses stable when an item is removed from the middle.
Modules
A module packages resources as a reusable unit with inputs and outputs. Every directory of .tf files is a module; the one you run from is the root module.
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
cidr = "10.0.0.0/16"
}
Read a module's outputs as module.vpc.vpc_id. Pin the version or ref of an external module, review its source, and run terraform init after adding or changing a source. The public Terraform Registry lists community and official modules.
The built-in templatefile() function replaces the old template provider for local template files.