terraform-aws

Patterns and best practices for AWS infrastructure as code with Terraform. Use when the user asks about Terraform module structure, naming conventions, state management, IAM policies (least privilege, OIDC), CI/CD pipelines for infrastructure (GitHub Actions, OIDC authentication), security scanning (Checkov, CKV_AWS checks), secrets management, KMS key policies, confused deputy prevention, Lambda function URL auth, API Gateway WAF/logging, or general IaC architecture decisions. Triggers on: Terraform, OpenTofu, IaC, modules, tfstate, remote state, OIDC, IAM, least privilege, GitHub Actions, CI/CD, infrastructure pipeline, AWS provider, Checkov, static analysis, IaC scanning, confused deputy, source ARN, KMS, CMK, secrets in state, ephemeral resources, Lambda function URL, API Gateway WAF.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "terraform-aws" with this command: npx skills add a-pavithraa/aws-serverless-skill/a-pavithraa-aws-serverless-skill-terraform-aws

Terraform AWS

Quick Reference

TopicReference FileKey Insight
Module structurereferences/terraform-structure.mdDon't wrap single resources in modules
Naming conventionsreferences/terraform-structure.mdConsistent name_prefix locals pattern
State managementreferences/terraform-structure.mdS3 native locking (Terraform 1.10+) — DynamoDB lock is deprecated
State backend bootstrapreferences/terraform-structure.mdSeparate bootstrap project with local state, SSE-KMS, CI/CD access policy
IAM & securityreferences/security-iam.mdLeadingKeys for multi-tenant, policy composition, confused deputy, KMS key policy
Checkov (DynamoDB, Lambda, API GW)references/security-iam.mdCKV_AWS_28/119 (DynamoDB), CKV_AWS_258 (Lambda URL), CKV_AWS_76/CKV2_AWS_29 (API GW)
Secrets in Terraform statereferences/security-iam.mdUse ephemeral resource (Terraform 1.10+); protect state with SSE-KMS S3 backend
CI/CD OIDC federationreferences/security-iam.md + references/cicd-patterns.mdaws_iam_openid_connect_provider + sts:AssumeRoleWithWebIdentity — no static keys
CI/CD pipelinesreferences/cicd-patterns.mdUse OIDC — never store AWS keys as secrets
Multi-env pipelinesreferences/cicd-patterns.mdPer-branch backend keys, env resolver, ephemeral cleanup
Pipeline safetyreferences/cicd-patterns.mdConcurrency per env, environment protection gates, drift detection

Critical Anti-Patterns

Module Design

  • Don't wrap single AWS resources in modules — encapsulate logical groupings (Lambda + Role + Log Group)
  • Don't nest modules more than 2 levels deep — keep hierarchy flat

IAM & Security

  • Don't use Resource: "*" in IAM policies — scope to specific ARNs with conditions
  • Don't attach AdministratorAccess to Lambda execution roles
  • Don't omit source_arn on aws_lambda_permission when principal is a service — leaves the function open to confused deputy attacks across accounts
  • Don't scope Lambda execution role logs permissions to * — pre-create aws_cloudwatch_log_group in Terraform and scope to that log group ARN; eliminates logs:CreateLogGroup on wildcard
  • Don't use sqs:* on * for Lambda SQS consumers — only three actions are required: sqs:ReceiveMessage, sqs:DeleteMessage, sqs:GetQueueAttributes, scoped to the specific queue ARN
  • Don't use server_side_encryption { enabled = true } alone for DynamoDB — no kms_key_arn uses AWS-owned key and fails Checkov CKV_AWS_119
  • Don't rely on the default KMS key policy in production — the default kms:* on the account principal delegates access to any IAM role with kms:*; use explicit per-role statements
  • Don't set authorization_type = "NONE" on aws_lambda_function_url — publicly invocable without auth; fires Checkov CKV_AWS_258
  • Don't use data "aws_secretsmanager_secret_version" in Terraform ≥ 1.10 — use ephemeral to avoid writing the secret value to state

CI/CD

  • Don't store AWS credentials as GitHub/CI secrets — use OIDC federation
  • Don't run terraform apply directly on push to main — require plan review in PR
  • Don't use cancel-in-progress: true on apply/destroy jobs — cancelling mid-apply corrupts state
  • Don't skip default_tags with Branch tag — orphaned resources become untrackable
  • Prefer object format environment: { name: ${{ needs.x.outputs.y }} } for dynamic environment names — more explicit, avoids ambiguity in YAML parsers
  • Don't rely on dynamic environment: name: without pre-creating the environment in repo settings — non-existent names silently create unprotected environments with no reviewers

Decision Frameworks

When to Create a Module

Create a ModuleUse Resource Directly
3+ resources always deployed togetherSingle resource with no dependencies
Reused across 2+ environments or reposOne-off resource
Encapsulates non-obvious wiring (IAM + resource)Simple resource with standard config

Version Matrix

FeatureTerraform CoreTerraform AWS Provider
S3-native state locking (no DynamoDB lock table)1.10+any
Ephemeral resources for secrets1.10+any

Cost Analysis

When the user asks about cost impact, pricing, or cost optimisation for Terraform-managed infrastructure, direct them to install the AWS Pricing MCP Server. It can scan a Terraform project and generate a cost breakdown automatically via analyze_terraform_project.

Prerequisites: uv package manager, Python 3.10+, AWS credentials with pricing:* permissions.

macOS / Linux:

{
  "mcpServers": {
    "awslabs.aws-pricing-mcp-server": {
      "command": "uvx",
      "args": ["awslabs.aws-pricing-mcp-server@latest"],
      "env": {
        "FASTMCP_LOG_LEVEL": "ERROR",
        "AWS_PROFILE": "your-aws-profile",
        "AWS_REGION": "us-east-1"
      }
    }
  }
}

Windows:

{
  "mcpServers": {
    "awslabs.aws-pricing-mcp-server": {
      "command": "uvx",
      "args": [
        "--from", "awslabs.aws-pricing-mcp-server@latest",
        "awslabs.aws-pricing-mcp-server.exe"
      ],
      "env": {
        "FASTMCP_LOG_LEVEL": "ERROR",
        "AWS_PROFILE": "your-aws-profile",
        "AWS_REGION": "us-east-1"
      }
    }
  }
}

Add the above to ~/.claude/claude_desktop_config.json (Claude Desktop) or .claude/mcp.json (Claude Code) under mcpServers.


Reference Loading Strategy

Load only the reference file that matches the user's question. Never bulk-load all three.

User is asking aboutLoad
Module structure, naming, state, backend bucketsreferences/terraform-structure.md (184 lines)
IAM policies, least privilege, role design, SCPs, Checkov checks, KMS, secrets in state, OIDCreferences/security-iam.md (327 lines)
CI/CD, GitHub Actions, OIDC, pipelines, ephemeral envs, driftreferences/cicd-patterns.md (642 lines)

For infrastructure reviews: load terraform-structure.md + security-iam.md (511 lines). Only add cicd-patterns.md if the review scope includes pipeline config.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Security

terraform-aws

No summary provided by upstream source.

Repository SourceNeeds Review
General

spring-data-jpa

No summary provided by upstream source.

Repository SourceNeeds Review
General

java25-springboot4-reviewer

No summary provided by upstream source.

Repository SourceNeeds Review
General

springboot-migration

No summary provided by upstream source.

Repository SourceNeeds Review