Implement security best practices including secrets management, policy as code, and compliance scanning
Adds security best practices to Terraform configurations including secrets management, policy enforcement, and compliance scanning. Use when creating or reviewing Terraform files to implement encryption, secrets handling, and security policies.
/plugin marketplace add pluginagentmarketplace/custom-plugin-terraform/plugin install terraform-assistant@pluginagentmarketplace-terraformThis skill inherits all available tools. When active, it can use any tool Claude has access to.
assets/config.yamlassets/schema.jsonreferences/GUIDE.mdreferences/PATTERNS.mdscripts/validate.pyProduction security patterns for Terraform including secrets, policies, and compliance.
provider "vault" {
address = var.vault_address
}
data "vault_kv_secret_v2" "db" {
mount = "secret"
name = "database/prod"
}
resource "aws_db_instance" "main" {
username = data.vault_kv_secret_v2.db.data["username"]
password = data.vault_kv_secret_v2.db.data["password"]
}
resource "aws_secretsmanager_secret" "db" {
name = "${var.project}/database"
recovery_window_in_days = 30
}
data "aws_secretsmanager_secret_version" "db" {
secret_id = aws_secretsmanager_secret.db.id
}
locals {
db_credentials = jsondecode(data.aws_secretsmanager_secret_version.db.secret_string)
}
data "azurerm_key_vault_secret" "db_password" {
name = "db-password"
key_vault_id = azurerm_key_vault.main.id
}
resource "azurerm_mssql_server" "main" {
administrator_login_password = data.azurerm_key_vault_secret.db_password.value
}
# restrict-instance-types.sentinel
import "tfplan/v2" as tfplan
allowed_types = ["t3.micro", "t3.small", "t3.medium"]
main = rule {
all tfplan.resource_changes as _, rc {
rc.type is "aws_instance" implies
rc.change.after.instance_type in allowed_types
}
}
# policy/terraform.rego
package terraform.security
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket"
resource.change.after.acl == "public-read"
msg := sprintf("Public S3 bucket: %s", [resource.address])
}
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_db_instance"
resource.change.after.storage_encrypted != true
msg := sprintf("Unencrypted RDS: %s", [resource.address])
}
# .pre-commit-config.yaml
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.83.6
hooks:
- id: terraform_fmt
- id: terraform_validate
- id: terraform_tflint
- id: terraform_checkov
args: [--args=--quiet]
- repo: https://github.com/aquasecurity/tfsec
rev: v1.28.4
hooks:
- id: tfsec
# .checkov.yml
framework:
- terraform
soft-fail: false
check:
- CKV_AWS_*
skip-check:
- CKV_AWS_144 # S3 cross-region replication
resource "aws_kms_key" "main" {
description = "Main encryption key"
deletion_window_in_days = 30
enable_key_rotation = true
policy = data.aws_iam_policy_document.kms.json
}
resource "aws_kms_alias" "main" {
name = "alias/${var.project}"
target_key_id = aws_kms_key.main.key_id
}
# S3
resource "aws_s3_bucket_server_side_encryption_configuration" "main" {
bucket = aws_s3_bucket.main.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
kms_master_key_id = aws_kms_key.main.arn
}
}
}
# RDS
resource "aws_db_instance" "main" {
storage_encrypted = true
kms_key_id = aws_kms_key.main.arn
}
# EBS
resource "aws_ebs_encryption_by_default" "main" {
enabled = true
}
# Mark variables as sensitive
variable "db_password" {
type = string
sensitive = true
}
# Mark outputs as sensitive
output "credentials" {
value = local.db_credentials
sensitive = true
}
# Prevent secrets in logs
resource "aws_db_instance" "main" {
password = var.db_password
lifecycle {
ignore_changes = [password]
}
}
| Issue | Cause | Solution |
|---|---|---|
| Secrets in state | Direct value usage | Use data sources |
| Policy failures | Non-compliant resource | Fix or add exception |
| AccessDenied | Missing KMS permissions | Check key policy |
| Scan false positives | Overly strict rules | Add skip-check |
Skill("terraform-security")
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.