Warning
This project is in early development. APIs, commands, and configurations may introduce breaking changes between releases.
tfskel is a CLI tool that helps you run Terraform without the operational chaos.
It standardizes project structure, reduces drift, and makes plans easier to reason about, so you can spend less time managing Terraform and more time terraforming your infrastructure. No wrappers. No unnecessary abstraction. With tfskel Just well-structured, scalable Terraform that stays maintainable as you grow.
Terraform itself isn’t hard. Managing it at scale is.
As infrastructure grows, so does the operational overhead — inconsistent folder structures, version drift, massive plan reviews, and environments slowly falling out of sync. Teams end up spending more time maintaining Terraform than actually building infrastructure.
tfskel removes that friction.
It gives you a clean, opinionated foundation that keeps your Terraform projects structured, consistent, and predictable from day one. Instead of reinventing layouts and fixing drift, you can focus on delivering Infrastructure as Code with confidence. No copy-paste cycles. No structural chaos. No hidden abstraction layers. Just well-organized, scalable Terraform — built to grow with your infrastructure.
tfskel is not a Terraform wrapper. It’s an operational discipline tool for Terraform.
- Enforce consistent project structure across environments
- Scaffold Terraform code using clean, maintainable templates
- Upgrade generated files in-place when templates or config change (
--upgrade) - Preview changes safely with
--dry-runbefore writing anything - Detect AWS provider and Terraform version drift across the entire repo
- Analyze Terraform plans to make reviews easier and safer with custom resources severity
- Stay vanilla — no wrappers, no lock-in, just Terraform
Note
⭐️ If you find tfskel useful, consider starring the repo to stay updated and support the project. ⭐️
- Install a specific version (recommended)
curl -fsSL https://raw.githubusercontent.com/ishuar/tfskel/main/install.sh | TFSKEL_VERSION=<RELEASED_VERSION> bash- Install latest version
curl -fsSL https://raw.githubusercontent.com/ishuar/tfskel/main/install.sh | bash- Custom install directory
curl -fsSL https://raw.githubusercontent.com/ishuar/tfskel/main/install.sh | INSTALL_DIR=~/.local/bin bashgo install github.com/ishuar/tfskel@latest ## or released versionMake sure $HOME/go/bin is in your PATH.
Caution
This project is developed with AI assistance. Please review the code carefully and perform your own due diligence. Thank you 🙏
# 1. Create the repo layout, .tfskel.yaml, .mise.toml, lint config, and shared workflows
tfskel init --workflows
# 2. Fill in provider.aws.account_mapping and backend.s3.bucket_name in .tfskel.yaml
# 3. Create a root module for one app
tfskel scaffold myapp --env dev --region eu-central-1
# 4. Add the per-environment GitHub Actions plan/apply workflow
tfskel scaffold workflows --env dev
# 5. Check the repo is still in sync with .tfskel.yaml
tfskel validate
# 6. Review a plan before applying it
terraform plan -out plan.bin && terraform show -json plan.bin > plan.json
tfskel review plan --json-file plan.jsonAdd --dry-run to any command to see what it would write without touching disk.
The full flag reference for every command is generated from the CLI itself and lives in docs/reference/. Run tfskel <command> --help for the same text in the terminal. For running tfskel in GitHub Actions, including the workflows it generates and the exit codes to gate on, see docs/ci-usage.md.
👉 For an end-to-end walkthrough, see tfskel-demo PR #2: a new Terraform monorepo in four steps using the built-in GitHub Actions workflows.
| Command | What it does | Reference |
|---|---|---|
tfskel init |
Create the repo layout and config files | init |
tfskel scaffold <app-dir> |
Create a root module from templates | scaffold |
tfskel scaffold workflows |
Create the per-environment plan/apply workflow | scaffold workflows |
tfskel validate |
Report version drift and missing tools, exit 2 on findings |
validate |
tfskel review plan |
Summarize a plan JSON, flag risky changes, optional AI summary | review plan |
tfskel version |
Print version, commit, and build info | version |
Every command accepts --config, --verbose, --dry-run, and --no-color. Exit code 1 always means an error, so gate CI on the specific finding codes above, not on != 0.
Creates the env/region layout, .tfskel.yaml, .mise.toml, lint and pre-commit config. Add --workflows for the shared reusable GitHub Actions workflows.
tfskel init --workflowsCreates a root module under envs/<env>/<region>/<app-dir> with backend.tf and versions.tf rendered from templates. scaffold workflows adds the per-environment plan/apply caller workflow.
tfskel scaffold myapp --env dev --region eu-central-1
tfskel scaffold workflows --env devReports Terraform and provider version drift across the repo plus missing or outdated tools. Exits 2 when it finds something, so it works as a CI gate.
tfskel validateSummarizes a plan JSON file and flags critical changes. --detailed-exitcode exits 2 on changes and 3 on deletions or replacements; --ai adds a written summary (see below).
terraform plan -out plan.bin && terraform show -json plan.bin > plan.json
tfskel review plan --json-file plan.json --detailed-exitcodetfskel review plan --ai asks an AI model to explain the plan in plain words below the table: what could break, security concerns, and how to roll back.
- Pick a provider. Anthropic Claude is the default. For Google Gemini, set
TFSKEL_AI_PROVIDER=gemini. - Set the API key in your environment:
ANTHROPIC_API_KEYfor Claude,GEMINI_API_KEYfor Gemini. Keys are never read from the config file or flags. - Run
tfskel review plan --json-file plan.json --ai.
Only changed attributes are sent, sensitive values are replaced with <redacted>, and output values are never sent. If the key is missing or the API call fails, tfskel warns and carries on with the same exit code, so CI never fails because of --ai. Works with --format table only. Model and token limit come from --ai-model, --ai-max-tokens, or ai.model and ai.max_tokens in .tfskel.yaml. See the review plan reference for all AI flags and defaults.
Note: The AI summary does not replace scanners like
tfsec,checkov, ortrivy. Use both.
What is sent, how redaction works, and every failure mode are in docs/ai-review.md.
Create a .tfskel.yaml in your project root. Precedence is CLI flags → config file → defaults.
- docs/configuration.md documents every key, its default, and the validation behind each error.
.tfskel.example.yamlis the annotated copy. backend.s3.bucket_name,workflows.aws_role_arn, andworkflows.aws_role_nameaccept Go template syntax. The available placeholders, template functions, and custom template rules are in docs/templates.md.
Every generated file carries a source marker recording the template and content hash that produced it. --upgrade on init, scaffold, and scaffold workflows re-renders only files whose marker no longer matches, and --force extends that to files without a marker. The decision rules, templates.upgrade, and --upgrade-all are in docs/upgrading.md.
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have any suggestion that would make this project better, feel free to fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement" with your suggestion.
Tip
See CONTRIBUTING.md for guidelines.
- Fork the repository on GitHub
- Clone your fork and create a new branch
- Make your changes
- Run tests and checks
- Push your branch and open a pull request
git clone https://github.com/<your-username>/tfskel.git
cd tfskel
git checkout -b my-feature-branch
make test # Run tests
make check # Run all quality checksImportant
Please keep your pull requests small and focused. This will make it easier to review and merge.
Released under MIT LICENSE



