AgentStack
SKILL verified MIT Self-run

Terraform Modules

skill-sawrus-agent-guides-terraform-modules · by sawrus

Design reusable, well-tested Terraform modules with cloud-agnostic interfaces and safe state management.

No reviews yet
0 installs
14 views
0.0% view→install

Install

$ agentstack add skill-sawrus-agent-guides-terraform-modules

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Terraform Modules? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Skill: Terraform Modules

> Expertise: Reusable module design, for_each patterns, remote state, data sources, module testing with Terratest.

When to load

When writing new Terraform, reviewing IaC PRs, designing module interfaces, or debugging plan/apply failures.

Module Interface Design

# variables.tf — define a clean, minimal interface
variable "project" {
  description = "Project name used in resource naming and tags"
  type        = string
}

variable "environment" {
  description = "Deployment environment (dev|staging|production)"
  type        = string
  validation {
    condition     = contains(["dev", "staging", "production"], var.environment)
    error_message = "environment must be dev, staging, or production."
  }
}

variable "instance_count" {
  description = "Number of instances to create"
  type        = number
  default     = 1
}

# outputs.tf — expose only what callers need
output "instance_ids" {
  description = "List of created instance IDs"
  value       = aws_instance.this[*].id
}

output "private_ips" {
  description = "Private IP addresses"
  value       = aws_instance.this[*].private_ip
  sensitive   = false
}

for_each vs count

# ✅ for_each — stable keys, safe to add/remove
resource "aws_security_group_rule" "allow" {
  for_each    = var.allowed_ports   # map: { "http" = 80, "https" = 443 }
  type        = "ingress"
  from_port   = each.value
  to_port     = each.value
  protocol    = "tcp"
  cidr_blocks = ["0.0.0.0/0"]
}

# ❌ count — index-based, removing item N shifts all subsequent items
resource "aws_instance" "this" {
  count = var.instance_count   # removing instance 0 destroys ALL and recreates
}

# ✅ for_each with map for instances
resource "aws_instance" "this" {
  for_each      = var.instances   # map: { "web-1" = {...}, "web-2" = {...} }
  instance_type = each.value.instance_type
}

Dynamic Blocks

resource "aws_security_group" "this" {
  name = "${var.project}-${var.environment}-sg"

  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
    }
  }
}

Data Sources (cloud-agnostic patterns)

# Latest Ubuntu 22.04 AMI (AWS)
data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["099720109477"]  # Canonical
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
  }
}

# Cross-stack reference via SSM (avoid terraform_remote_state across envs)
data "aws_ssm_parameter" "vpc_id" {
  name = "/${var.environment}/network/vpc_id"
}

Locals for DRY Code

locals {
  name_prefix = "${var.project}-${var.environment}"
  common_tags = {
    Project     = var.project
    Environment = var.environment
    ManagedBy   = "terraform"
    Owner       = var.owner
  }
}

resource "aws_s3_bucket" "this" {
  bucket = "${local.name_prefix}-assets-${random_id.suffix.hex}"
  tags   = local.common_tags
}

moved Block (safe refactoring)

# When renaming a resource — prevents destroy+create
moved {
  from = aws_instance.web
  to   = aws_instance.this["web-1"]
}

CI/CD Integration

# Standard pipeline steps
terraform init -backend-config=environments/${ENV}/backend.hcl
terraform validate
terraform fmt -check -recursive
terraform plan -var-file=environments/${ENV}/terraform.tfvars -out=tfplan
# After approval:
terraform apply tfplan

Anti-Patterns

| Anti-pattern | Fix | |:---|:---| | count for multi-instance | Use for_each with map keys | | Hardcoded region/AZ | Use data source or variable | | ?ref=main module source | Pin to version tag | | Provider config inside module | Provider in root module only | | terraform_remote_state across envs | SSM / Consul KV for cross-stack values | | Sensitive values in outputs without sensitive=true | Mark all secret outputs as sensitive |

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.