A starter template for teams using Claude Code with terraform and Helm in GCP infrastructure. Copy this into your repo and start working safely.
Template repository -- copy .claude/ to your infrastructure repo to get started. For team usage after installation, see the Team Usage Guide.
Provides a starter AGENTS.md for use with your infrastructure repository.
Also this provides safety hooks for Claude Code and that protect your infrastructure workflows:
- Blocks dangerous operations --
terraform apply,destroy,helm install,upgrade,uninstall, and other cluster-mutating commands are completely forbidden - Prompts for safe operations --
terraform plan,helm template,helm lint, and other read-only commands require your explicit approval before running - Audit trail -- Every terraform and helm command attempt is logged with timestamps, decisions, and working directory
- Devcontainer -- Optional but recommended isolated development environment with pinned tool versions and pre-configured tooling
Additionally, this pattern of safety hooks can be extended for other sensitive tooling that your team might use.
# In your terraform repo
git clone https://github.com/your-org/moz-tf-ccode.git /tmp/tf-hooks
cp -r /tmp/tf-hooks/.claude .
cp /tmp/tf-hooks/.gitignore .gitignore # Or merge if you have one# Run automated tests
pytest .claude/hooks/ -v3. Customize Your AGENTS.md file (Optional - see next section)
# Start Claude Code
claudeAsk Claude to help with terraform or Helm:
- "Add a new GKE node pool with these specs: ..."
- "Run terraform plan to check what would change"
- "Lint the staging Helm chart and show me any errors"
- "Render the app chart templates with production values"
Dangerous commands are blocked automatically. Safe commands prompt for your approval.
Claude Code reads AGENTS.md to understand your infrastructure, so customizing it makes Claude more effective at helping with your specific repo.
Interactive setup (recommended): Start Claude Code in your repo and paste this prompt:
I've just installed the Claude Code terraform safety hooks in this repository.
Help me customize the AGENTS.md file for my team by asking me questions about:
- The infrastructure this repository manages
- Who uses this repository (team composition and experience level)
- Our deployment workflow and approval processes
- Any special conventions or constraints for this repo
Ask me one question at a time. After I answer each question, ask the next one.
When you have enough information, show me a draft of the customized AGENTS.md
sections for my review before making any changes.
Claude will guide you through questions and customize the file with your specific infrastructure details. All customizations go in the "REPOSITORY-SPECIFIC CONTEXT" section of AGENTS.md, preserving the template content above it for future updates. Add bullet points as is appropriate for your repo.
Note: This repo uses AGENTS.md (with CLAUDE.md as a symlink) to support multiple AI coding agents. You can use either naming convention in your repos. See DEPLOYMENT.md for details on the interactive setup.
claudeAsk Claude to help with terraform:
- "Add a new GKE node pool with these specs: ..."
- "Run terraform plan to check what would change"
- "Fix this validation error: [paste error]"
Customize the prompt to better suite your organization and plans for the repository.
Manual editing: Edit AGENTS.md directly. Add your details below the "REPOSITORY-SPECIFIC CONTEXT" dividing line -- infrastructure overview, environments, team conventions, and deployment workflow.
Claude Code is your augment, not your replacement. Think of the LLM as an intern:
- You review and approve each action
- You are responsible for the work product
- You submit the final PR and own the changes
- Claude helps you work faster, but you remain the decision maker
These commands are completely forbidden and will never execute:
terraform apply # Must go through PR workflow
terraform destroy # Extremely dangerous
terraform import # Modifies state
terraform state rm/mv # State manipulation
terraform taint/untaint # Affects future applies
terraform force-unlock # Breaks locking safetyAll other terraform commands prompt before execution:
terraform plan -lock=false # Primary use case
terraform init # Module initialization
terraform validate # Syntax checking
terraform fmt # Code formatting
terraform state list/show # Read-only state view
terraform output # View outputs- Quick Start Guide - Get started in 5 minutes
- Usage Guide - Comprehensive documentation for teams
- Testing Guide - How to test and troubleshoot
- Deployment Guide - Rolling out to multiple repos
- AGENTS.md - Project context for AI coding agents (example for your repos, also accessible as CLAUDE.md)
The hooks use Claude Code's native hook system:
-
Pre-execution validation (
.claude/hooks/terraform-validator.py)- Intercepts bash commands before Claude runs them
- Checks against blocked command patterns
- Prompts user for approval on terraform commands
- Blocks execution if command is forbidden
-
Post-execution logging (
.claude/hooks/terraform-logger.py)- Records command results to audit trail
- Captures timestamps, exit codes, success/failure
- Logs stored in
.claude/audit/terraform-YYYY-MM-DD.log(gitignored, rotated daily)
-
Hook configuration (
.claude/settings.json)- Defines which hooks run and when
- Committed to git for team consistency
- Can be customized per repository
Hooks provide technical enforcement rather than relying on Claude's behavior:
- System-level blocking before command execution
- Claude cannot disable or bypass hooks
- Works even if Claude "forgets" the rules
- Auditable and deterministic
The safety architecture uses multiple layers of protection when AI assists with infrastructure:
graph TB
User["User (You)<br/>Reviews & Approves"]
Host["Host Machine<br/>Your laptop/workstation"]
Container["Docker Container<br/>Isolated environment"]
Claude["Claude Code<br/>AI assistant"]
PreHook["Pre-execution Hook<br/>terraform-validator.py"]
PostHook["Post-execution Hook<br/>terraform-logger.py"]
TF["Terraform<br/>Infrastructure changes"]
User -->|Interacts with| Claude
Claude -->|Runs in| Container
Container -->|Isolated from| Host
Claude -->|Attempts command| PreHook
PreHook -->|BLOCK| User
PreHook -->|PROMPT| User
User -->|Approve/Deny| PreHook
PreHook -->|ALLOW| TF
TF -->|Executes in| Container
TF -->|Result| PostHook
PostHook -->|Audit log| Container
style User fill:#e1f5ff
style Container fill:#fff4e1
style PreHook fill:#ffe1e1
style TF fill:#e1ffe1
style PostHook fill:#f0e1ff
Key Protection Layers:
- Host Isolation - Container boundary prevents AI commands from affecting your host machine
- Hook Validation - Pre-execution hook blocks/prompts before any terraform command runs
- User Control - You approve every action; AI cannot proceed without permission
- Audit Trail - Post-execution hook logs all attempts for compliance and review
This multi-layered approach means even if one layer fails, others provide protection.
When using AI coding agents with terraform, the devcontainer provides critical isolation and consistency:
Safety Through Isolation
- AI-executed commands run in container, not on your host machine
- Container boundary provides additional protection layer beyond hooks
- Filesystem operations are sandboxed to container workspace
- Can destroy/rebuild container if AI operations cause issues
- Network policies can restrict container's outbound connections
Consistency Across Team
- Everyone uses identical tool versions (terraform, gcloud, Python)
- Eliminates "works on my machine" issues
- Hooks behave identically across all team members
- No manual installation of 10+ CLI tools
Complete SRE Toolset
- Pre-installed: terraform 1.14.3, tflint, terraform-docs, gcloud, kubectl
- Quality tools: shellcheck, pre-commit, gitleaks, bat, ripgrep, yq
- VSCode extensions auto-configured for terraform and Python
- Auto-formatting enabled for all relevant file types
Security Built-In
- gitleaks scanner prevents accidentally committing secrets
- Pre-commit framework for additional safeguards
- Isolated environment with network controls
- All hook scripts ready to run immediately
Prerequisites:
- Container runtime (Docker, Podman, Rancher Desktop, etc.) installed and running
- VSCode with "Dev Containers" extension
Quick start:
- Open this repository in VSCode
- Click the blue "Reopen in Container" prompt, or
- Command palette: "Dev Containers: Reopen in Container"
First build takes a few minutes. Subsequent starts are fast (cached).
Once running:
- All tools are ready immediately
- Claude Code extension runs in container context
- Hooks execute in container Python environment
- Terraform commands execute in isolated container
If you're not using VSCode, you can build and use the Docker image directly:
# Build the image
cd .devcontainer
docker build -t terraform-sre:local .
# Run interactive shell in container
docker run -it --rm \
-v $(pwd):/workspace \
-w /workspace \
--cap-add=NET_ADMIN \
--cap-add=NET_RAW \
terraform-sre:local /bin/zsh
# Inside the container, hooks work the same way
terraform planNote: When using the Dockerfile directly, you'll need to manually configure credential mounting and environment variables that devcontainer.json normally handles.
The devcontainer complements the hook system by adding a process-level isolation layer:
Without devcontainer:
Your host machine → Claude Code → Hooks → Terraform
With devcontainer (recommended):
Your host machine → Container boundary → Claude Code → Hooks → Terraform
The container provides:
- Filesystem isolation (container can't modify host)
- Network isolation (optional restrictions on outbound calls)
- Process isolation (can kill container if needed)
- Version pinning (same terraform/Python for everyone)
What this protects against:
- Accidental file modifications outside your workspace
- AI mistakes that could affect your host system
- Unintended command execution impacting local environment
- Version inconsistencies across team members
What this does NOT protect against:
- Malicious code intentionally designed to escape containers
- Determined attackers exploiting container escape vulnerabilities
- Social engineering or credential theft
- Bypassing IAM permissions or cloud provider security
Bottom line: This is an operational safety layer for AI-assisted development, not a security boundary against malicious actors. Your existing security controls (IAM, state locking, PR reviews) remain essential.
If you prefer not to use devcontainer, install these tools locally:
# macOS
brew install python3 terraform tflint terraform-docs gcloud kubectl
# Ubuntu/Debian
apt-get install python3 python3-pip
# Then install terraform and cloud tools per vendor docsEnsure Python 3 is available for the hook scripts. Note that tool versions may vary across team members.
See .devcontainer/README.md for:
- Complete tool inventory and versions
- Customization options (adding tools, changing versions)
- Organizational deployment patterns
- Credential management approaches
- Troubleshooting guide
- Pre-commit integration examples
.claude/
├── settings.json # Hook configuration (committed)
├── hooks/
│ ├── terraform-validator.py # Pre-execution validation
│ └── terraform-logger.py # Post-execution logging
├── skills/
│ ├── tf-plan/ # /tf-plan skill
│ ├── helm-check/ # /helm-check skill
│ ├── git-ship/ # /git-ship skill
│ └── review/ # /review skill (self-configuring)
├── docs/
│ ├── README.md # Main usage guide
│ ├── TESTING.md # Testing procedures
│ └── DEPLOYMENT.md # Multi-repo rollout
└── QUICKSTART.md # 5-minute getting started
.devcontainer/
├── devcontainer.json # VSCode devcontainer config
├── Dockerfile # Container with all SRE tools
├── init-firewall.sh # Network configuration script
└── README.md # Complete devcontainer documentation
.gitignore # Excludes audit logs
AGENTS.md # Project context for AI coding agents
CLAUDE.md -> AGENTS.md # Symlink for backwards compatibility
README.md # This file
If your team uses wrapper scripts (like tfwrapper in $PATH), add them to the validator:
Edit .claude/hooks/terraform-validator.py:
When running terraform or helm commands outside the devcontainer, hooks display a non-blocking warning for targeted commands run by Claude Code that encourages using the devcontainer.
Note: Shell aliases (like alias tf=terraform) don't need configuration. They don't work in subprocess calls, so they can't bypass hooks anyway.
If you customize the hooks for your organization:
Track your changes:
- Document customizations in comments within the hook files
- Consider maintaining a
CUSTOMIZATIONS.mdfile listing your changes - Use git to track changes:
git log .claude/hooks/
Upgrading hooks:
- When this project releases new hook versions, you'll need to manually merge changes
- Keep your customizations minimal to simplify updates
- Consider contributing broadly-useful customizations back to this project
Multi-repository consistency:
- Decide if customizations should be per-repo or organization-wide
- For org-wide rules, maintain a canonical hooks repository and copy to other repos
- Document the process for propagating hook updates across your repositories
This is an organizational problem that varies by team structure. Choose an approach that fits your workflow.
Different repos can have different rules:
- Dev repos: More permissive (allow terraform apply with extra confirmation)
- Prod repos: Stricter (additional blocked commands)
See Deployment Guide - Customization for details.
- Python 3.x - For hook scripts (included in devcontainer)
- Claude Code - Download here
- Terraform - Any version (hooks are terraform-agnostic, devcontainer includes 1.14.3)
- GCP authentication -
gcloud auth login(for terraform to work) - Container runtime + VSCode Dev Containers extension - Optional, for isolated development environment (recommended). Supports Docker, Podman, Rancher Desktop, OrbStack, and compatible runtimes
Q: Can I still run terraform apply manually?
A: Yes. The hooks only block Claude Code, not you. Run terraform apply directly in your terminal.
Q: What if hooks cause problems?
A: Temporarily disable by renaming .claude/settings.json to .claude/settings.json.disabled. Restart Claude session.
Q: How do I completely disable the devcontainer and hooks?
A: To remove all safety mechanisms and run Claude Code directly on your host system:
- Close VSCode devcontainer (if using)
- Reopen repository locally (not in container)
- Remove or rename
.claude/settings.jsonto disable hooks
This is not recommended. You lose both container isolation and hook validation, returning to direct AI command execution on your host machine. Only do this if you've determined the safety mechanisms don't fit your workflow after thorough evaluation.
Q: Do I need to authenticate to anything?
A: Just your normal GCP/AWS/etc. authentication for terraform. The hooks themselves require no additional auth.
A: Yes. The hooks only block Claude Code, not you. Run commands directly in your terminal if your organization doesn't have CICD, if it's a dev environment, etc.
A: Yes. Hooks are for local development only. Your CI/CD pipeline is unchanged.
Q: How do I use this devcontainer setup in CI/CD?
A: CI/CD integration is not covered by this project. The devcontainer and hooks are designed for local development workflows with Claude Code. Your CI/CD pipelines (Atlantis, GitLab CI, GitHub Actions, etc.) should continue using their existing terraform execution environments and approval workflows.
Q: What about kubectl, helm, gcloud commands?
A: This repo focuses on terraform. You can adapt the pattern for other tools by modifying the hook scripts.
# 1. Ask Claude to add infrastructure
You: "Add a new Cloud SQL instance for our staging environment"
Claude: [Writes terraform code]
# 2. Review the code changes
You: "Looks good. Run terraform plan to verify"
Claude: "I'll run terraform plan -lock=false"
[PROMPT APPEARS]
Terraform command requires approval:
Command: terraform plan -lock=false
Working directory: /path/to/staging
Allow? (y/n)
You: y
[Plan output shows the new Cloud SQL instance]
# 3. Commit and create PR
You: "/git-ship"
[git-ship checks branch, stages files, drafts commit message, offers to open PR]
# 4. Apply via your standard process
# (After PR approval, Atlantis/CI applies the changes)All terraform command attempts are logged with timestamps. Logs are automatically rotated daily:
# View today's commands
tail -20 .claude/audit/terraform-$(date +%Y-%m-%d).log | jq .
# View all recent commands across dates
cat .claude/audit/terraform-*.log | tail -20 | jq .
# See only blocked attempts from today
cat .claude/audit/terraform-$(date +%Y-%m-%d).log | jq 'select(.decision == "BLOCKED")'
# Example log entry
{
"timestamp": "2026-01-27T14:30:15.123456",
"command": "terraform plan -lock=false",
"decision": "PENDING_APPROVAL",
"working_dir": "/Users/you/repos/infra-prod",
"reason": "Awaiting user approval"
}Log rotation: Logs are automatically rotated by date (e.g., terraform-2026-01-27.log). Old logs persist for your audit needs and can be archived or deleted based on your retention policy.
Questions or issues?
- Review the documentation
- Check the troubleshooting guide
- Open an issue on GitHub
Want to contribute?
- Fork this repository
- Make your changes
- Submit a pull request
- See AGENTS.md for development guidelines
Built for SRE teams managing infrastructure with Claude Code. Safety, auditability, and team confidence as core principles.