Provides best practices for Terraform variables, locals, and outputs to create reusable and clean module interfaces.
Install
mkdir -p .claude/skills/terraform-values && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/15330" && unzip -o skill.zip -d .claude/skills/terraform-values && rm skill.zipInstalls to .claude/skills/terraform-values
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Manage Terraform values including input variables, local values, and output values. Use when asked about "variables", "locals", "outputs", "input values", "how to pass values", "variable validation", "sensitive values", or when defining module interfaces, reusing expressions, or exposing data. Covers variable types, defaults, validation, precedence, locals usage patterns, and output configuration.Key capabilities
- →Define input variables for Terraform modules
- →Create local values for reusable expressions within modules
- →Configure output values to export module data
- →Implement variable validation rules
- →Manage sensitive values to prevent exposure in CLI output
How it works
The skill guides the management of Terraform values, including input variables, local values, and output values. It specifies HCL object syntax rules, variable arguments like type and default, and best practices for each value type.
Inputs & outputs
When to use terraform-values
- →Defining module interfaces
- →Setting up variable validation
- →Managing terraform output values
About this skill
Terraform Values
Comprehensive guide to managing values in Terraform modules including input variables, local values, and output values. Learn how to create flexible, composable, and reusable modules.
When to Use This Skill
- User asks about "variables", "locals", "outputs", "input values"
- Questions about "how to pass values to modules"
- "Variable validation", "type constraints", "sensitive values"
- Defining module interfaces and boundaries
- Reusing expressions within modules
- Exposing module data to CLI, HCP Terraform, or other configurations
- Variable precedence and assignment methods
Value Types Overview
Object Syntax in Lists and Maps
HCL object syntax rules:
- Single-line object: Always use commas between key-value pairs.
Example:
log_sources = [ { name = "php", container = "app" }, { name = "nginx", container = "web" } ] - Multi-line object: Each key on a separate line, no commas needed.
Example:
log_sources = [ { name = "php" container = "app" }, { name = "nginx" container = "web" } ]
Maps and objects in variables, locals, and tests must follow these conventions.
Terraform uses three types of values to manage data flow:
| Type | Purpose | Scope | Reference |
|---|---|---|---|
| Variables | Module inputs | Module-specific | var.<NAME> |
| Locals | Reusable expressions | Module-scoped | local.<NAME> |
| Outputs | Module data export | Cross-module | output.<NAME> or module.<NAME>.<OUTPUT> |
Value Flow:
Variables (input) → Locals (processing) → Resources → Outputs (export)
Input Variables
Variables define the input interface of your module, letting consumers customize behavior without modifying source code.
Variable Definition
Basic Syntax:
variable "name" {
type = type_constraint
description = "Description of the variable"
default = default_value
sensitive = true/false
nullable = true/false
validation {
# Validation rules
}
}
Complete Example:
variable "instance_type" {
type = string
description = "EC2 instance type for the web server"
default = "t2.micro"
validation {
condition = can(regex("^t[23]\\.", var.instance_type))
error_message = "Instance type must be t2 or t3 family."
}
}
variable "subnet_id" {
type = string
description = "Subnet ID where the web server will be deployed"
# No default - required input
}
variable "environment" {
type = string
description = "Deployment environment name"
default = "dev"
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging, or prod."
}
}
Variable Arguments
type
Specifies the value type constraint:
Simple Types:
variable "name" {
type = string
}
variable "count" {
type = number
}
variable "enabled" {
type = bool
}
Collection Types:
variable "tags" {
type = map(string)
}
variable "subnet_ids" {
type = list(string)
}
variable "ports" {
type = set(number)
}
Structural Types:
variable "config" {
type = object({
name = string
port = number
enabled = bool
})
}
variable "instances" {
type = list(object({
name = string
size = string
}))
}
variable "settings" {
type = map(object({
value = string
enabled = bool
}))
}
Optional Attributes:
variable "server" {
type = object({
name = string
port = optional(number, 80) # Default: 80
enabled = optional(bool, true) # Default: true
tags = optional(map(string), {}) # Default: {}
})
}
Any Type:
variable "custom_data" {
type = any
description = "Custom data of any type"
}
description
Always provide clear descriptions:
# ✅ Good - Specific and helpful
variable "subnet_id" {
type = string
description = "Subnet ID where the web server will be deployed"
}
# ❌ Bad - Vague
variable "subnet_id" {
type = string
description = "Subnet"
}
default
Makes variables optional:
# Required variable (no default)
variable "vpc_id" {
type = string
description = "VPC ID for resource deployment"
}
# Optional variable (has default)
variable "instance_type" {
type = string
description = "EC2 instance type"
default = "t2.micro"
}
# Complex default
variable "tags" {
type = map(string)
description = "Resource tags"
default = {
Terraform = "true"
ManagedBy = "terraform"
}
}
sensitive
Prevents values from appearing in CLI output:
variable "database_password" {
type = string
description = "Password for the RDS database instance"
sensitive = true
}
Behavior:
$ terraform plan
# Password value not shown in plan output
$ terraform output database_password
database_password = <sensitive>
Warning: Sensitive values are still stored in state. Use ephemeral (Terraform 1.10+) to omit from state entirely.
nullable
Controls whether null is accepted:
# Allows null (default behavior)
variable "optional_value" {
type = string
nullable = true
default = null
}
# Rejects null
variable "required_value" {
type = string
nullable = false
# If no value provided, Terraform errors
}
validation
Add custom validation rules:
Basic Validation:
variable "environment" {
type = string
description = "Deployment environment"
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging, or prod."
}
}
Regex Validation:
variable "subnet_id" {
type = string
description = "AWS subnet ID"
validation {
condition = can(regex("^subnet-[a-f0-9]{8,17}$", var.subnet_id))
error_message = "Subnet ID must be a valid AWS subnet ID format."
}
}
Numeric Range Validation:
variable "max_size" {
type = number
description = "Maximum cluster size"
validation {
condition = var.max_size >= 1 && var.max_size <= 10
error_message = "Max size must be between 1 and 10."
}
}
Multiple Validations:
variable "instance_config" {
type = object({
type = string
size = number
})
validation {
condition = contains(["t2.micro", "t2.small", "t2.medium"], var.instance_config.type)
error_message = "Instance type must be t2.micro, t2.small, or t2.medium."
}
validation {
condition = var.instance_config.size >= 8 && var.instance_config.size <= 100
error_message = "Instance size must be between 8 and 100 GB."
}
}
Cross-Field Validation:
variable "min_size" {
type = number
}
variable "max_size" {
type = number
validation {
condition = var.max_size >= var.min_size
error_message = "Max size must be greater than or equal to min size."
}
}
Referencing Variables
Use var.<NAME> syntax:
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
subnet_id = var.subnet_id
tags = {
Environment = var.environment
Name = "${var.environment}-web-server"
}
}
Assigning Variable Values
Value Precedence
Terraform applies variable values in this order (highest to lowest):
- Command-line flags (
-var,-var-file) and HCP Terraform variables - Auto-loaded files (
*.auto.tfvars,*.auto.tfvars.json) in lexical order - terraform.tfvars.json
- terraform.tfvars
- Environment variables (
TF_VAR_*) - Variable default argument
Later sources override earlier ones.
Command-Line Variables
# Single variable
terraform apply -var="instance_type=t3.medium"
# Multiple variables
terraform apply \
-var="instance_type=t3.medium" \
-var="environment=prod"
# Complex types (use JSON)
terraform apply -var='subnet_ids=["subnet-12345","subnet-67890"]'
Variable Definition Files
Create .tfvars files:
# production.tfvars
instance_type = "t3.large"
environment = "prod"
subnet_ids = ["subnet-12345", "subnet-67890"]
enable_monitoring = true
Auto-loaded files:
*.auto.tfvars(loaded automatically)*.auto.tfvars.json(loaded automatically)terraform.tfvars(loaded automatically)terraform.tfvars.json(loaded automatically)
Manual loading:
terraform apply -var-file="production.tfvars"
JSON format:
{
"instance_type": "t3.large",
"environment": "prod",
"subnet_ids": ["subnet-12345", "subnet-67890"],
"enable_monitoring": true
}
Environment Variables
Use TF_VAR_ prefix:
# Simple values
export TF_VAR_instance_type=t3.medium
export TF_VAR_environment=staging
# Complex values (use JSON)
export TF_VAR_subnet_ids='["subnet-12345","subnet-67890"]'
export TF_VAR_config='{"key": "value", "enabled": true}'
terraform apply
HCP Terraform Variables
Set variables in workspace settings:
- Terraform Variables - Input to configuration
- Environment Variables - Shell environment (e.g.,
AWS_ACCESS_KEY_ID) - Variable Sets - Reusable groups applied to multiple workspaces
Variable Best Practices
Do's:
✅ Always add descriptions
variable "instance_type" {
type = string
description = "EC2 instance type for the web server"
default = "t2.micro"
}
✅ Use type constraints
variable "tags" {
type = map(string)
}
✅ Add validation for important values
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging, or prod."
}
✅
Content truncated.
When not to use it
- →When hardcoding values that should be variables
- →When skipping descriptions for variables or outputs
- →When using the 'any' type unnecessarily for variables
Limitations
- →Requires adherence to HCL object syntax rules
- →Sensitive values are still stored in state, only hidden from CLI output
- →Does not cover Terraform versions prior to 1.10 for ephemeral sensitive values
How it compares
This skill provides a complete guide to managing Terraform values with specific HCL syntax rules and best practices, ensuring flexible and reusable modules, unlike an ad-hoc approach to value definition.
Compared to similar skills
terraform-values side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| terraform-values (this skill) | 0 | 3mo | Review | Intermediate |
| aws-solution-architect | 20 | 3mo | Review | Advanced |
| terraform-module-library | 7 | 4mo | No flags | Advanced |
| azure-deployment-preflight | 7 | 6mo | Review | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
aws-solution-architect
alirezarezvani
Design AWS architectures for startups using serverless patterns and IaC templates. Use when asked to design serverless architecture, create CloudFormation templates, optimize AWS costs, set up CI/CD pipelines, or migrate to AWS. Covers Lambda, API Gateway, DynamoDB, ECS, Aurora, and cost optimization.
terraform-module-library
wshobson
Build reusable Terraform modules for AWS, Azure, and GCP infrastructure following infrastructure-as-code best practices. Use when creating infrastructure modules, standardizing cloud provisioning, or implementing reusable IaC components.
azure-deployment-preflight
github
Performs comprehensive preflight validation of Bicep deployments to Azure, including template syntax validation, what-if analysis, and permission checks. Use this skill before any deployment to Azure to preview changes, identify potential issues, and ensure the deployment will succeed. Activate when users mention deploying to Azure, validating Bicep files, checking deployment permissions, previewing infrastructure changes, running what-if, or preparing for azd provision.
terraform-azurerm-set-diff-analyzer
github
Analyze Terraform plan JSON output for AzureRM Provider to distinguish between false-positive diffs (order-only changes in Set-type attributes) and actual resource changes. Use when reviewing terraform plan output for Azure resources like Application Gateway, Load Balancer, Firewall, Front Door, NSG, and other resources with Set-type attributes that cause spurious diffs due to internal ordering changes.
terraform-skill
sickn33
Terraform infrastructure as code best practices
aws-advisor
tech-leads-club
Expert AWS Cloud Advisor for architecture design, security review, and implementation guidance. Leverages AWS MCP tools for accurate, documentation-backed answers. Use when user asks about AWS architecture, security, service selection, migrations, troubleshooting, or learning AWS. Triggers on AWS, Lambda, S3, EC2, ECS, EKS, DynamoDB, RDS, CloudFormation, CDK, Terraform, Serverless, SAM, IAM, VPC, API Gateway, or any AWS service.