How to use Terraform Engineer in Claude Code for infrastructure development
Purpose
This post demonstrates how to use the Terraform Engineer skill in Claude Code to write better infrastructure code and follow best practices.
Environment
- Claude Code with claude-skills plugin
- Terraform 1.5+
- AWS/Azure/GCP (cloud provider of choice)
What is Terraform Engineer?
The Terraform Engineer skill is a specialized agent within the claude-skills ecosystem that helps you write idiomatic Terraform code. It enforces best practices for infrastructure-as-code, including proper state management, module structure, variable validation, and resource naming conventions.
When I work with infrastructure, I use this skill to avoid common mistakes like hardcoding values, missing output declarations, or creating resources that can’t be destroyed cleanly.
Installation and Setup
First, install the claude-skills plugin:
npm install -g @jeffallan/claude-skillsThen activate it in your Claude Code session by asking Claude to use the skill:
Use terraform-engineer skillYou can verify it’s active by checking the skill context in your conversation.
Core Usage Patterns
The Terraform Engineer skill activates when you mention:
- “terraform-engineer”
- “Use terraform patterns”
- “Review my Terraform code”
- “Create infrastructure with Terraform”
It works best when you have actual Terraform files in your project.
Example 1: Creating an EC2 instance
When I asked Claude to create an AWS EC2 instance with terraform-engineer:
Use terraform-engineer to create an EC2 instance in us-east-1The skill generated this structure:
terraform { required_version = ">= 1.5.0" required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } }}
provider "aws" { region = var.aws_region}
resource "aws_instance" "app_server" { ami = data.aws_ami.app_server.id instance_type = var.instance_type tags = { Name = "${var.project_name}-app" Environment = var.environment }}variable "aws_region" { description = "AWS region for resources" type = string default = "us-east-1" validation { condition = can(regex("^us-", var.aws_region)) error_message = "Region must start with 'us-'." }}
variable "instance_type" { description = "EC2 instance type" type = string default = "t3.micro"}
variable "project_name" { description = "Project name for resource naming" type = string}
variable "environment" { description = "Environment name" type = string}Notice what the skill included:
- Variable validation on the region
- Tags for resource identification
- Data source for AMI lookup
- Separate variables file
Example 2: Module structure
I asked terraform-engineer to organize resources into modules:
Use terraform-engineer to create a VPC module with public and private subnetsThe skill created this structure:
modules/ vpc/ main.tf variables.tf outputs.tf README.mdexamples/ simple-vpc/ main.tfThe module outputs.tf file included proper export values:
output "vpc_id" { description = "ID of the VPC" value = aws_vpc.main.id}
output "public_subnet_ids" { description = "List of public subnet IDs" value = aws_subnet.public[*].id}
output "private_subnet_ids" { description = "List of private subnet IDs" value = aws_subnet.private[*].id}This makes the module reusable and self-documenting.
Example 3: State management
When I asked about remote state configuration:
Use terraform-engineer to set up remote state backendThe skill provided this pattern:
terraform { backend "s3" { bucket = "my-terraform-state" key = "prod/terraform.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-state-lock" }}With this explanation:
- S3 bucket stores the state file
- DynamoDB table enables locking
- Encryption protects sensitive data
- Key path isolates environments
Best Practices
DO
- Use variables for all configurable values
- Add validation to variable inputs
- Declare outputs for module reuse
- Tag all resources for identification
- Use data sources to look up existing resources
- Separate modules by function (VPC, compute, database)
- Run
terraform fmtbefore commits - Use
.tfvarsfiles for environment-specific values
DON’T
- Hardcode AMI IDs, region names, or instance types
- Create resources without tags
- Skip output declarations in modules
- Mix environments in one state file
- Use count with modules (use for_each instead)
- Commit
.tfstatefiles to version control - Ignore plan output warnings
Common mistakes I’ve seen
When I first used Terraform without this skill, I made these errors:
Mistake 1: Hardcoded values
# BADresource "aws_instance" "app" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t3.micro"}The skill corrected me to use variables and data sources:
# GOODdata "aws_ami" "app_server" { most_recent = true owners = ["amazon"]
filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] }}
resource "aws_instance" "app" { ami = data.aws_ami.app_server.id instance_type = var.instance_type}Mistake 2: Missing outputs
I created modules without outputs, which made them hard to use. The skill reminded me that outputs are the module’s API.
How to solve common problems
Problem: State file locking
When multiple team members run Terraform simultaneously, you might see:
Error acquiring the state lockThe solution is to use a remote backend with locking:
terraform { backend "s3" { bucket = "my-state-bucket" key = "global/terraform.tfstate" region = "us-east-1" dynamodb_table = "terraform-locks" }}Problem: Drift detection
I found resources changed outside Terraform. The skill suggested:
terraform plan -refresh-onlyThis detects drift without making changes.
Problem: Large plans
When Terraform plans took too long, the skill recommended targeting specific resources:
terraform plan -target=aws_instance.app_serverRelated Skills
The terraform-engineer skill works well with:
- security-review: Check for security issues in your infrastructure
- planning: Design complex multi-region deployments
- code-reviewer: Review Terraform code before committing
Summary
In this post, I showed how to use the Terraform Engineer skill in Claude Code to write better infrastructure code. The key points are:
- Use variables and validation for all inputs
- Structure code in reusable modules
- Always declare outputs
- Use remote state with locking
- Run plan before apply
The skill helps you avoid common mistakes and follow Terraform best practices without memorizing them all.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 claude-skills Documentation
- 👨💻 claude-skills GitHub Repository
- 👨💻 Terraform Official Documentation
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments