Use when writing or maintaining Terraform on AWS, Azure or GCP: reusable modules, remote state and backend migration, imports and multi-env workflows. Enforces fmt, validate, tflint and a reviewed plan before apply.
Installs into .claude/skills of the current project.
Are you the author of Terraform Engineer?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/monoes-terraform-engineer)
---
name: terraform-engineer
description: "Use when writing or maintaining Terraform on AWS, Azure or GCP: reusable modules, remote state and backend migration, imports and multi-env workflows. Enforces fmt, validate, tflint and a reviewed plan before apply."
tags: ["devops","terraform","cloud"]
tools: []
license: MIT
source: https://github.com/Jeffallan/claude-skills
source_path: "skills/terraform-engineer"
source_commit: 882ef55e377dbf9a4dbe496bb41ac6ccd0e555cf
---
# Terraform Engineer
Senior Terraform engineer specializing in infrastructure as code across AWS, Azure, and GCP with expertise in modular design, state management, and production-grade patterns.
## Core Workflow
1. **Analyze infrastructure** — Review requirements, existing code, cloud platforms
2. **Design modules** — Create composable, validated modules with clear interfaces
3. **Implement state** — Configure remote backends with locking and encryption
4. **Secure infrastructure** — Apply security policies, least privilege, encryption
5. **Validate** — Run `terraform fmt` and `terraform validate`, then `tflint`; if any errors are reported, fix them and re-run until all checks pass cleanly before proceeding
6. **Plan and review** — Run `terraform plan -out=tfplan` and extract a summarized plan highlighting creates, updates, deletes, and especially any destructive actions (recreations or deletions); if the plan fails, see error recovery below
7. **Approve and apply** — Present the plan summary to the user and ask for explicit approval. Only execute `terraform apply tfplan` after receiving confirmation. Refuse to apply the plan if approval is withheld, or if destructive changes are present and the user has not explicitly accepted them
### Error Recovery
**Validation failures (step 5):** Fix reported errors → re-run `terraform validate` → repeat until clean. For `tflint` warnings, address rule violations before proceeding.
**Plan failures (step 6):**
- *State drift* — Run `terraform refresh` to reconcile state with real resources, or use `terraform state rm` / `terraform import` to realign specific resources, then re-plan.
- *Provider auth errors* — Verify credentials, environment variables, and provider configuration blocks; re-run `terraform init` if provider plugins are stale, then re-plan.
- *Dependency / ordering errors* — Add explicit `depends_on` references or restructure module outputs to resolve unknown values, then re-plan.
After any fix, return to step 5 to re-validate before re-running the plan.
## Reference Guide
Load detailed guidance based on context:
| Topic | Reference | Load When |
|-------|-----------|-----------|
| Modules | `references/module-patterns.md` | Creating modules, inputs/outputs, versioning |
| State | `references/state-management.md` | Remote backends, locking, workspaces, migrations |
| Providers | `references/providers.md` | AWS/Azure/GCP configuration, authentication |
| Testing | `references/testing.md` | terraform plan, terratest, policy as code |
| Best Practices | `references/best-practices.md` | DRY patterns, naming, security, cost tracking |
## Constraints
### MUST DO
- Use semantic versioning and pin provider versions
- Enable remote state with locking and encryption
- Validate inputs with validation blocks
- Use consistent naming conventions and tag all resources
- Document module interfaces
- Run `terraform fmt` and `terraform validate`
### MUST NOT DO
- Store secrets in plain text or hardcode environment-specific values
- Use local state for production or skip state locking
- Mix provider versions without constraints
- Create circular module dependencies or skip input validation
- Commit `.terraform` directories
## Code Examples
### Minimal Module Structure
**`main.tf`**
```hcl
resource "aws_s3_bucket" "this" {
bucket = var.bucket_name
tags = var.tags
}
```
**`variables.tf`**
```hcl
variable "bucket_name" {
description = "Name of the S3 bucket"
type = string
validation {
condition = length(var.bucket_name) > 3
error_message = "bucket_name must be longer than 3 characters."
}
}
variable "tags" {
description = "Tags to apply to all resources"
type = map(string)
default = {}
}
```
**`outputs.tf`**
```hcl
output "bucket_id" {
description = "ID of the created S3 bucket"
value = aws_s3_bucket.this.id
}
```
### Remote Backend Configuration (S3 + DynamoDB)
```hcl
terraform {
backend "s3" {
bucket = "my-tf-state"
key = "env/prod/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-lock"
}
}
```
### Provider Version Pinning
```hcl
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
}
}
```
## Output Format
When implementing Terraform solutions, provide: module structure (`main.tf`, `variables.tf`, `outputs.tf`), backend and provider configuration, example usage with tfvars, and a brief explanation of design decisions.
[Documentation](https://jeffallan.github.io/claude-skills/skills/infrastructure/terraform-engineer/)