Skip to content

Repository files navigation

tfclean

tfclean is a tool for cleaning up Terraform configuration files by automatically removing applied moved, import, and removed blocks. This helps maintain clean and readable Terraform configurations by eliminating blocks that have already served their purpose.

Installation

Using Homebrew

brew tap takaishi/tap
brew install takaishi/tap/tfclean

Using go install

# Install specified version
go install github.com/takaishi/tfclean/cmd/tfclean@v0.0.13

# Install latest version
go install github.com/takaishi/tfclean/cmd/tfclean@latest

Using aqua

aqua is a declarative CLI Version Manager. You can install tfclean using aqua:

aqua g -i takaishi/tfclean

Or add to your aqua.yaml:

registries:
  - type: standard
    ref: v4.292.0 # renovate: depName=aquaproj/aqua-registry
packages:
  - name: takaishi/tfclean@v0.7.0  # Use the latest version

Then run:

aqua i

Using GitHub Actions

You can use the official GitHub Action to install tfclean in your workflows:

- uses: takaishi/tfclean@v1
  with:
    version: 'latest' # Optional, defaults to latest

Manual Installation

Download the appropriate binary for your system from the releases page.

Usage

Remove All Blocks

Remove all moved/import/removed blocks regardless of their state:

tfclean /path/to/tffiles

Remove Only Applied Blocks

Remove only the blocks that have been successfully applied (requires access to tfstate).

When using an S3 backend, you can omit --tfstate. tfclean auto-detects the state location by reading terraform { backend "s3" { ... } } from .tf files in the given directory.

# With S3 backend: auto-detect state from .tf files (--tfstate optional)
AWS_PROFILE=your_profile tfclean /path/to/tffiles

# Or specify state location explicitly
AWS_PROFILE=your_profile tfclean --tfstate s3://path/to/tfstate /path/to/tffiles

Multiple tfstate Files

When the same Terraform configuration is backed by several states — for example one per developer, per PR, and dev/prod — pass --tfstate multiple times. A block is removed only if it has been applied in all of the given states; if it is still pending in any one of them, tfclean keeps it.

tfclean \
  --tfstate s3://path/to/dev-alice.tfstate \
  --tfstate s3://path/to/dev-bob.tfstate \
  --tfstate s3://path/to/prod.tfstate \
  /path/to/tffiles

In the example above, a moved block that has been applied to dev-alice and prod but not yet to dev-bob is preserved until it is applied everywhere. Because dropping a state could remove a block that is still pending elsewhere, tfclean treats a failure to read any explicitly given state as a fatal error rather than silently skipping it.

Auto-detection only resolves a single backend from your .tf files, so multiple states must be specified explicitly with --tfstate.

Empty File Cleanup

If cleaning removes the last block from a .tf file and leaves nothing but whitespace or comments, tfclean deletes the file. Files that were already empty/comment-only before the run are left untouched. Deletions show up as deleted files in git status and need to be staged like any other change.

Ignoring Blocks and Files

Sometimes you want to keep a moved, import, or removed block around even though tfclean would otherwise remove it. Add a # tfclean-ignore comment on the line immediately before the block:

# tfclean-ignore: reused across workspaces, keep until the last one is migrated
import {
  to = aws_athena_workgroup.primary
  id = "primary"
}

The reason after the colon is optional but recommended so future readers understand the intent.

To skip an entire file, add a # tfclean-ignore-file comment anywhere in it:

# tfclean-ignore-file

Features

  • Smart Block Removal

    • Removes moved blocks that have been applied
    • Removes import blocks that have been applied
    • Removes removed blocks that have been applied
    • Option to forcefully remove all moved/import/removed blocks
    • Deletes .tf files that become empty (or only whitespace/comments) as a result of cleaning
    • # tfclean-ignore / # tfclean-ignore-file comment annotations to preserve specific blocks or whole files
  • Platform Support

    • Supports both x86_64 and ARM64 architectures
    • Available for Linux and macOS

GitHub Actions Integration

You can automate the cleanup of your Terraform configurations using GitHub Actions. Here's a complete example that creates pull requests for cleanup:

name: tfclean

on:
  push:
    branches:
      - main

permissions:
  pull-requests: write # Required for creating pull requests

jobs:
  tfclean:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      
      # Setup GitHub App token for PR creation
      - uses: actions/create-github-app-token@v1
        id: app-token
        with:
          app-id: ${{ secrets.GITHUB_APP_ID }}
          private-key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}
      
      # Configure AWS credentials if using remote state
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: "aws_role_arn_for_oidc"
          aws-region: "ap-northeast-1"
      
      # Install tfclean
      - uses: takaishi/tfclean@v1
        
      # Run tfclean
      - run: tfclean --tfstate s3://path/to/tfstate /path/to/tffiles
      
      # Create PR if changes detected
      - name: Check changes
        id: diff-check
        run: git diff --exit-code || echo "changes_detected=true" >> $GITHUB_OUTPUT
      
      - name: Create Pull Request
        if: steps.diff-check.outputs.changes_detected == 'true'
        run: |
          branch_name=tfclean_$(date +"%Y%m%d%H%M")
          git switch -c ${branch_name}
          git config --global user.email "bot@example.com"
          git config --global user.name "Terraform Cleanup Bot"
          git add .
          git commit -m "chore: auto-remove applied terraform blocks"
          git push origin ${branch_name}
          gh pr create --base main --head ${branch_name} --title "Auto-remove applied Terraform blocks" --body "This PR removes Terraform blocks that have been successfully applied."
        env:
          GH_TOKEN: ${{ steps.app-token.outputs.token }}

This workflow will:

  1. Run on pushes to the main branch
  2. Install and run tfclean
  3. Create a pull request if any blocks were removed
  4. Use GitHub App authentication for better security

For the GitHub Actions integration, it's recommended to use a GitHub App for authentication instead of personal access tokens. This provides better security and more granular permissions control.

About

tfclean is tool to remove applied moved block, import block, etc

Topics

Resources

Security policy

Stars

116 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages