TE

terraform-values

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.zip

Installs 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.
400 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Intermediate

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

You give it
Terraform module definition
You get back
Terraform configuration with defined variables, locals, and 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:

TypePurposeScopeReference
VariablesModule inputsModule-specificvar.<NAME>
LocalsReusable expressionsModule-scopedlocal.<NAME>
OutputsModule data exportCross-moduleoutput.<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):

  1. Command-line flags (-var, -var-file) and HCP Terraform variables
  2. Auto-loaded files (*.auto.tfvars, *.auto.tfvars.json) in lexical order
  3. terraform.tfvars.json
  4. terraform.tfvars
  5. Environment variables (TF_VAR_*)
  6. 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.

SkillInstallsUpdatedSafetyDifficulty
terraform-values (this skill)03moReviewIntermediate
aws-solution-architect203moReviewAdvanced
terraform-module-library74moNo flagsAdvanced
azure-deployment-preflight76moReviewAdvanced

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.

2047

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.

759

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.

746

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.

534

terraform-skill

sickn33

Terraform infrastructure as code best practices

829

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.

529

Search skills

Search the agent skills registry