How it works
The explanation, with examples you can run.
Variables with types and validation
variable "env" { type = string description = "Deployment environment." default = "dev" validation { condition = contains(["dev", "staging", "prod"], var.env) error_message = "env must be dev, staging or prod." }} variable "replicas" { type = number default = 2} variable "tags" { type = map(string) default = {}}Types (string, number, bool, list(...), map(...), object({...}), set(...)) convert and check input. Validation rules run before planning. Running terraform plan -var env=qa on a configuration with this env variable (Terraform 1.5.7; the line numbers are from that larger file) stops immediately:
Error: Invalid value for variable on main.tf line 9: 9: variable "env" { ├──────────────── │ var.env is "qa" env must be dev, staging or prod. This was checked by the validation rule at main.tf:13,3-13.Values come from, in increasing priority: environment variables (TF_VAR_env), terraform.tfvars, *.auto.tfvars files, and -var or -var-file on the command line. A variable without a default must be set somewhere; in CI, an interactive prompt for it means the job hangs.
Locals
locals { name_prefix = "${var.env}-checkout" tags = merge(var.tags, { environment = var.env managed_by = "terraform" })} resource "random_pet" "bucket_suffix" { prefix = local.name_prefix}Use locals for derived values and naming conventions. Do not overuse them: a local that is used once just hides where a value comes from.
Outputs
output "bucket_name" { value = random_pet.bucket_suffix.id description = "Name for the artefact bucket."} output "db_password" { value = random_password.db.result sensitive = true}terraform output prints them (sensitive ones as <sensitive>; terraform output -raw db_password still prints the value). Inside a module, outputs are the only way the caller can see anything: module.network.private_subnet_ids. Across separate configurations, prefer passing values through a parameter store or the terraform_remote_state data source sparingly, since the latter gives read access to the whole of the other state.
Habits
- Give every variable a
descriptionand a precisetype;anyis an escape hatch, not a default. - Keep secrets out of
.tfvarsfiles in Git. Pass them from a secret manager or the environment, and remember that they end up in state unless you use ephemeral values (see the secrets topic). - Mark outputs
sensitivewhen they are, so they do not appear in CI logs. - Use
nullable = falseand optional object attributes (optional(string, "default")) to make inputs strict but convenient.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.