Learning objectives
By the end of this module, you should be able to:
- Define typed input variables with validation.
- Use locals to avoid repeating derived expressions.
- Expose outputs intentionally and explain the limits of sensitive markings.
Variables are the module input interface
Input variables accept values from callers, variable files, environment variables and CLI flags. Type constraints and validation move errors earlier in the workflow.
Locals name derived values
locals blocks calculate reusable expressions inside a module. They reduce repetition but are not externally configurable inputs.
Sensitive is a display control, not encryption
Marking a value sensitive suppresses it in many CLI/UI displays, but sensitive values can still be stored in state. Backend protection and secret-management practices remain necessary.
Worked examples
See the idea in practice.
Typed variable with validation
variable "environment" {
type = string
validation {
condition = contains(["dev", "test", "prod"], var.environment)
error_message = "environment must be dev, test or prod"
}
}
locals { name = "app-${var.environment}" }
output "name" { value = local.name }
- Validation fails during planning when the input violates the contract.
- The output creates an intentional root-module interface.
Hands-on lab
Lab — Build a typed module interface
Goal: Use validation, locals and outputs to create a predictable configuration interface.
STEP 1Write configuration
mkdir -p ~/gnu-terraform-labs/module03 && cd ~/gnu-terraform-labs/module03
cat > main.tf <<'EOF'
variable "environment" {
type = string
validation {
condition = contains(["dev", "test", "prod"], var.environment)
error_message = "environment must be dev, test or prod"
}
}
locals {
service_name = "payments-${var.environment}"
}
resource "terraform_data" "service" {
input = local.service_name
}
output "service_name" {
value = terraform_data.service.output
}
EOF
STEP 2Initialize and apply valid input
terraform init
terraform apply -auto-approve -var=environment=dev
STEP 3Read the output
terraform output -raw service_name
STEP 4Prove validation rejects invalid input
terraform plan -var=environment=production
Verify
- The valid output is payments-dev.
- The invalid value fails with the variable validation message.
Expected outcome
- Configuration consumers receive a clear input contract and stable output.
If it fails
- Use -var-file for larger value sets rather than long command lines.
- Remember shell quoting when values contain spaces or special characters.
Real-world connectionWell-designed module inputs and outputs are API contracts; changing them deserves compatibility review.
Avoid these traps
Common mistakes
- Using locals when callers need to configure a value.
- Assuming sensitive values are encrypted automatically.
- Leaving variables untyped when a stable module interface is intended.
Knowledge check
Can you explain it without looking back?
Open each answer only after you have tried to answer the question yourself.
1What are locals for?
Naming reusable derived expressions inside a module.
2What does sensitive = true guarantee?
Primarily display redaction; it does not encrypt state.
3Why add variable validation?
To reject invalid inputs early with a useful message.