All skills
jeffallan avatar

/terraform-engineer

@d0e7f4e
by jeffallanjeffallan/claude-skills12k stars
1,124

Use when implementing infrastructure as code with Terraform across AWS, Azure, or GCP. Invoke for module development (create reusable modules, manage module versioning), state management (migrate backends, import existing resources, resolve state conflicts), provider configuration, multi-environment workflows, and infrastructure testing.

Use this Skill: https://skilld.dev/gh/jeffallan/claude-skills/terraform-engineer

This session only. Nothing lands on disk.

referencesmodule-patterns.md

≈1.5k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Terraform Module Patterns

Module Structure

terraform-aws-vpc/
├── main.tf           # Primary resource definitions
├── variables.tf      # Input variable declarations
├── outputs.tf        # Output value definitions
├── versions.tf       # Provider version constraints
├── README.md         # Module documentation
├── examples/
│   └── complete/
│       ├── main.tf
│       └── variables.tf
└── tests/
    └── vpc_test.go

Basic Module Pattern

main.tf

resource "aws_vpc" "this" {
  cidr_block           = var.cidr_block
  enable_dns_hostnames = var.enable_dns_hostnames
  enable_dns_support   = var.enable_dns_support

  tags = merge(
    var.tags,
    {
      Name = var.name
    }
  )
}

resource "aws_subnet" "private" {
  for_each = var.private_subnets

  vpc_id            = aws_vpc.this.id
  cidr_block        = each.value.cidr_block
  availability_zone = each.value.az

  tags = merge(
    var.tags,
    {
      Name = "${var.name}-private-${each.key}"
      Type = "private"
    }
  )
}

variables.tf

variable "name" {
  description = "Name prefix for all resources"
  type        = string

  validation {
    condition     = length(var.name) > 0 && length(var.name) <= 32
    error_message = "Name must be 1-32 characters"
  }
}

variable "cidr_block" {
  description = "CIDR block for VPC"
  type        = string

  validation {
    condition     = can(cidrhost(var.cidr_block, 0))
    error_message = "Must be valid IPv4 CIDR block"
  }
}

variable "private_subnets" {
  description = "Map of private subnet configurations"
  type = map(object({
    cidr_block = string
    az         = string
  }))
  default = {}
}

variable "tags" {
  description = "Common tags for all resources"
  type        = map(string)
  default     = {}
}

variable "enable_dns_hostnames" {
  description = "Enable DNS hostnames in VPC"
  type        = bool
  default     = true
}

variable "enable_dns_support" {
  description = "Enable DNS support in VPC"
  type        = bool
  default     = true
}

outputs.tf

output "vpc_id" {
  description = "ID of the VPC"
  value       = aws_vpc.this.id
}

output "vpc_cidr_block" {
  description = "CIDR block of the VPC"
  value       = aws_vpc.this.cidr_block
}

output "private_subnet_ids" {
  description = "IDs of private subnets"
  value       = { for k, v in aws_subnet.private : k => v.id }
}

output "private_subnet_cidrs" {
  description = "CIDR blocks of private subnets"
  value       = { for k, v in aws_subnet.private : k => v.cidr_block }
}

versions.tf

terraform {
  required_version = ">= 1.5.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

Module Composition

# Composite module using child modules
module "networking" {
  source = "./modules/vpc"

  name       = "production"
  cidr_block = "10.0.0.0/16"

  private_subnets = {
    app1 = { cidr_block = "10.0.1.0/24", az = "us-east-1a" }
    app2 = { cidr_block = "10.0.2.0/24", az = "us-east-1b" }
  }

  tags = local.common_tags
}

module "security" {
  source = "./modules/security-groups"

  vpc_id = module.networking.vpc_id

  security_groups = {
    web = {
      ingress = [
        { from_port = 443, to_port = 443, protocol = "tcp", cidr_blocks = ["0.0.0.0/0"] }
      ]
    }
  }
}

Dynamic Blocks

resource "aws_security_group" "this" {
  name   = var.name
  vpc_id = var.vpc_id

  dynamic "ingress" {
    for_each = var.ingress_rules
    content {
      from_port   = ingress.value.from_port
      to_port     = ingress.value.to_port
      protocol    = ingress.value.protocol
      cidr_blocks = ingress.value.cidr_blocks
      description = ingress.value.description
    }
  }

  dynamic "egress" {
    for_each = var.egress_rules
    content {
      from_port   = egress.value.from_port
      to_port     = egress.value.to_port
      protocol    = egress.value.protocol
      cidr_blocks = egress.value.cidr_blocks
      description = egress.value.description
    }
  }
}

Conditional Resources

# Create NAT gateway only if enabled
resource "aws_nat_gateway" "this" {
  count = var.enable_nat_gateway ? 1 : 0

  allocation_id = aws_eip.nat[0].id
  subnet_id     = aws_subnet.public[0].id

  tags = {
    Name = "${var.name}-nat"
  }

  depends_on = [aws_internet_gateway.this]
}

# Use for_each for multiple optional resources
resource "aws_route53_zone" "private" {
  for_each = var.create_private_zone ? { main = var.domain_name } : {}

  name = each.value

  vpc {
    vpc_id = aws_vpc.this.id
  }
}

Module Versioning

# Pin to specific version
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "5.1.2"

  # ... configuration
}

# Use version constraints
module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 19.0"  # >= 19.0, < 20.0

  # ... configuration
}

# Reference Git tags
module "custom" {
  source = "git::https://github.com/org/terraform-modules.git//vpc?ref=v1.2.3"

  # ... configuration
}

Module Testing Example

# examples/complete/main.tf
module "vpc_test" {
  source = "../.."

  name       = "test-vpc"
  cidr_block = "10.100.0.0/16"

  private_subnets = {
    app = { cidr_block = "10.100.1.0/24", az = "us-east-1a" }
  }

  tags = {
    Environment = "test"
    ManagedBy   = "terraform"
  }
}

output "vpc_id" {
  value = module.vpc_test.vpc_id
}

Best Practices

  • Keep modules focused and single-purpose
  • Use for_each over count for resources
  • Validate all inputs with validation blocks
  • Document all variables and outputs
  • Use semantic versioning (MAJOR.MINOR.PATCH)
  • Provide complete examples
  • Test modules before publishing
  • Use consistent naming conventions
  • Tag all taggable resources
  • Avoid hardcoded values

Source: SKILL.md on GitHub

1 alert16d5 checks · Risk CRITICAL
  • Gen Agent Trust Hub16d

    This skill is flagged as highly risky due to multiple confirmed detections by automated security scanners. The main skill definition file is classified as malware by file reputation services, and an included documentation link is blacklisted as malicious. Additionally, the skill's workflow involving the execution of Terraform commands on user-supplied code introduces an indirect prompt injection surface.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    4/6 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at d0e7f4e. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 2 months ago
Other metadata
metadata
{
  "author": "https://github.com/Jeffallan",
  "version": "1.1.0",
  "domain": "infrastructure",
  "triggers": "Terraform, infrastructure as code, IaC, terraform module, terraform state, AWS provider, Azure provider, GCP provider, terraform plan, terraform apply",
  "role": "specialist",
  "scope": "implementation",
  "output-format": "code",
  "related-skills": "cloud-architect, devops-engineer, kubernetes-specialist"
}
  • Infrastructure
  • terraform
  • aws
  • azure
  • gcp
  • iac
  • modules
  • state-management
  • providers

README badge

README badge for jeffallan/claude-skills/terraform-engineer

Writes Terraform modules and state configurations for AWS, Azure, and GCP infrastructure. Handles module design, remote backend setup with locking, provider version pinning, and validation workflows using terraform fmt, terraform validate, and tflint.

Generated from the current SKILL.md.

Does this skill support AWS, Azure, and GCP?
Yes. The skill covers provider configuration and patterns for all three cloud platforms, with examples for AWS S3 and references to provider-specific guidance.
What does this skill do if terraform plan fails?
The skill includes error recovery steps for state drift, provider auth errors, and dependency issues. It guides you through terraform refresh, terraform import, credential verification, and explicit depends_on fixes before re-planning.
Does this skill handle state management?
Yes. It covers remote backend setup with locking and encryption (S3 + DynamoDB example included), workspace management, state migrations, and resource import workflows.
Will this skill create modules for me?
Yes. The skill designs and implements reusable modules with input validation, clear outputs, semantic versioning, and documentation. It enforces module interface patterns and prevents circular dependencies.
Does this skill test Terraform code?
The skill runs terraform fmt and terraform validate before every plan, plus tflint for linting. It references detailed testing and policy-as-code guidance in bundled documentation.

Generated from the current SKILL.md. These answers refresh after source changes.