Syntic

Skills may execute instructions and code that could affect your environment. Marketplace scans reduce risk but do not guarantee safety. Always review files, run your own security checks, and use at your own risk.

EngineeringFree Safe

terraform-patterns

Security Scan Summary

Status: Safe

Source: Syntic Skills registry

Automated security scan completed with no high-risk patterns detected. Manual review is still required.

About This Skill

Use when designing Terraform modules, managing state backends, reviewing Terraform security, planning multi-region deployments, or following IaC best practices.

Downloadable SKILL.md

Download SKILL.md and place it in your Syntic skills folder. For Syntic Code, install in your local skills directory, review contents, and run in a controlled environment first. Acknowledge the risk notice above to enable the download.

SKILL.md
---
name: terraform-patterns
description: Use when designing Terraform modules, managing state backends, reviewing Terraform security, planning multi-region deployments, or following IaC best practices.
category: Engineering
version: 1.0.0
tools: []
---

# Terraform Patterns

Predictable infrastructure. Secure state. Modules that compose. No drift.

An opinionated Terraform methodology that turns sprawling HCL into well-structured, secure, production-grade infrastructure code: module design, state management, provider patterns, security hardening, and CI/CD integration. Not a Terraform tutorial — a set of concrete decisions about how to write infrastructure code that doesn't break at 3 AM.

Applies whenever `.tf` files, HCL, Terraform modules, state management, or provider configuration come up, or the user wants to provision infrastructure with Terraform.

## Code Review Checklist

**Module structure:** variables have descriptions and type constraints; outputs expose only what consumers need; resources use consistent naming (`{provider}_{type}_{purpose}`); locals are used for computed values and DRY expressions; nothing is hardcoded — everything is parameterized or in locals.

**State and backend:** a remote backend is configured (S3, GCS, Azure Blob, Terraform Cloud); state locking is enabled (DynamoDB for S3, native for others); state is encrypted at rest; no secrets are stored in state, or state access is restricted; workspaces or directory isolation separate environments.

**Providers:** version constraints use the pessimistic operator (`~> 5.0`); a `required_providers` block exists inside `terraform {}`; provider aliases handle multi-region or multi-account; child modules never configure providers themselves.

**Security:** no hardcoded secrets, keys, or passwords; IAM follows least privilege; encryption is enabled for storage, databases, and secrets; security groups aren't overly permissive (no `0.0.0.0/0` ingress on sensitive ports); sensitive variables are marked `sensitive = true`.

## Module Design Checklist

**Structure:** `main.tf` (primary resources), `variables.tf` (all inputs with descriptions and types), `outputs.tf` (all outputs with descriptions), `versions.tf` (the `terraform {}` block with `required_providers`), `locals.tf` (computed values and naming conventions), `data.tf` (data sources), `README.md` (usage examples and variable documentation).

**Variables:** every variable has a description, type, and validation where applicable; sensitive values are marked `sensitive = true`; defaults are provided for optional settings; related settings use object types (`variable "config" { type = object({...}) }`); constraints use `validation { condition = ... }` blocks.

**Outputs:** expose IDs, ARNs, and endpoints that consumers actually need; every output has a description; sensitive outputs are marked `sensitive = true`; never output an entire resource, only the specific attributes needed.

**Composition:** the root module calls child modules; child modules never call other child modules; values are passed explicitly, no hidden data-source lookups inside child modules; provider configuration lives only in the root module; reference children with `module "name" { source = "./modules/name" }`.

## Security Audit Reference

**Code-level, by severity:** Critical — hardcoded secrets in `.tf` files (fix: variables with `sensitive = true` or a vault), IAM policy with `*` actions (fix: scope to specific actions/resources), a security group open to `0.0.0.0/0` on port 22/3389 (fix: restrict to known CIDR blocks or use SSM/bastion). High — an S3 bucket without encryption (`server_side_encryption_configuration`), an S3 bucket with public access (`aws_s3_bucket_public_access_block`), RDS without encryption (`storage_encrypted = true`), RDS publicly accessible (`publicly_accessible = false`). Medium — CloudTrail not enabled, missing `prevent_destroy` on stateful resources, secret-holding variables missing `sensitive = true`.

**State-level, by severity:** Critical — a local state file (migrate to a remote backend with encryption). High — remote state without encryption (enable SSE-S3 or KMS), no state locking (DynamoDB for S3, native for TF Cloud). Medium — state accessible to all team members (restrict via IAM policies or TF Cloud teams).

## Module Design Patterns

**Flat module** (small/medium projects, <20 resources, one team owns everything): a single directory with `main.tf`, `variables.tf`, `outputs.tf`, `versions.tf`, `terraform.tfvars` (not committed), and `backend.tf`.

**Nested modules** (medium/large projects, multiple environments, team collaboration): an `environments/{dev,staging,prod}/` tree where each environment calls into a shared `modules/{networking,compute,database}/` tree with environment-specific parameters and state backends.

**Mono-repo with Terragrunt** (large-scale, many environments, DRY configuration, team-level isolation): a root `terragrunt.hcl`, reusable `modules/{vpc,eks,rds}/`, and per-environment directories where each module invocation gets its own `terragrunt.hcl` with environment overrides.

## Provider Configuration Patterns

**Version pinning:** pin `required_version` on the Terraform binary itself, and pin each provider with the pessimistic operator, e.g. `version = "~> 5.0"` allows 5.x but blocks 6.0.

**Multi-region with aliases:** declare a default provider block for the primary region and an aliased block (`alias = "west"`) for a secondary region; resources that need the secondary region reference `provider = aws.west` explicitly.

**Multi-account with assume role:** an aliased provider block can assume a cross-account IAM role via `assume_role { role_arn = "..." }`, letting one root module provision into another AWS account.

**Multi-cloud:** a single root module can declare `required_providers` for AWS, Azure, and GCP simultaneously and configure each (`provider "aws"`, `provider "azurerm"` with a `features {}` block, `provider "google"`) when a deployment genuinely spans clouds.

## State Management Decision Tree

Single developer, small project -> local state, but migrate to remote as soon as possible. Otherwise: on Terraform Cloud/Enterprise -> use its native backend (built-in locking, encryption, RBAC). On AWS -> S3 + DynamoDB (encryption, locking, versioning). On GCP -> a GCS bucket (native locking, encryption). On Azure -> Azure Blob Storage (native locking, encryption). Otherwise -> Consul or a PostgreSQL backend.

For environment isolation, prefer separate state files per environment — either separate directories (`dev/`, `staging/`, `prod/`) or Terraform workspaces (simpler but less isolation). Never use a single state file for all environments.

## CI/CD Integration Patterns

**Plan/apply split:** run `terraform init`, `terraform validate`, and `terraform plan -out=tfplan` on pull requests (post the plan as a PR comment for review); run `terraform apply -auto-approve` only on pushes to the main branch, gated behind a protected `production` environment.

**Drift detection:** on a schedule (e.g. weekday mornings), run `terraform plan -detailed-exitcode`; exit code 2 means drift was detected between the configured state and real infrastructure — alert the team (Slack, PagerDuty) rather than silently ignoring it.

## Proactive Triggers

Flag these without being asked: no remote backend configured (migrate to S3/GCS/Azure Blob with locking and encryption); a provider without a version constraint (add `version = "~> X.0"` to prevent breaking upgrades); hardcoded secrets in `.tf` files (use `sensitive = true` variables, or integrate Vault/SSM); an IAM policy with `"Action": "*"` (scope to specific actions — no wildcard actions in production); a security group open to `0.0.0.0/0` on SSH/RDP (restrict to a bastion CIDR or use SSM Session Manager); no state locking (enable a DynamoDB table for S3 backends, or use TF Cloud); resources without tags (add `default_tags` in the provider block — tags are mandatory for cost tracking); missing `prevent_destroy` on databases/storage (add a `lifecycle` block to prevent accidental deletion).

Bundle Download

Includes SKILL.md and bundled support files where provided. Risk acknowledgement is required.

Install Targets

Syntic App

  1. 1. Create a dedicated folder for this skill in your local skills library.
  2. 2. Place SKILL.md into that folder.
  3. 3. Restart Syntic and invoke this skill on matching tasks.

Syntic Code (CLI)

  1. 1. Save SKILL.md in your local Syntic Code skills directory.
  2. 2. Keep related files in the same skill folder.
  3. 3. Run in a safe environment and validate outputs.

Source

https://github.com/alirezarezvani/claude-skills/blob/main/engineering/terraform-patterns/skills/terraform-patterns/SKILL.md

Open Source Link
Engineering

Related Skills