# AWS with Terraform Tutorial: Terraform Tools (20)

> The essential tools for Terraform and OpenTofu: fmt, validate, TFLint, Trivy, Checkov, terraform-docs, Infracost and pre-commit hooks.

- Source: https://www.itwonderlab.com/aws-terraform-tutorial-terraform-tools/
- Published: 2026-10-05
- Updated: 2026-10-05
- Author: Javier Ruiz Jiménez (https://www.javierruizjimenez.com/)
- Site: IT Wonder Lab (https://www.itwonderlab.com/)

---

## Essential Terraform and OpenTofu tools

**Format, validate, lint, scan, document and estimate the cost of your Terraform and OpenTofu code before it reaches AWS.**

Welcome to our tutorial series about [Terraform or OpenTofu on AWS](https://www.itwonderlab.com/tag/aws-terraform-tutorial/). Infrastructure code deserves the same care as application code: it should be formatted consistently, checked automatically and reviewed. The tools in this section find most problems in seconds, **before** `tofu apply` creates (and bills) anything. They work the same with Terraform and OpenTofu; the examples use `tofu`.

![AWS with Terraform: The Essential Guide, 21 sections. Select a section to open its tutorial.](https://www.itwonderlab.com/media/tutorials/AWS-Terraform-Essentials/ITWL-Tutorials-AWS-Terraform-Essentials-Steps.svg)

### Prerequisites

Read the previous sections of the tutorial, listed in the [series index](#series) at the end of this page. The examples use the project with modules from [Terraform Modules](https://www.itwonderlab.com/aws-terraform-tutorial-terraform-modules/).

### The built-in commands

OpenTofu and Terraform already include the first line of defense.

| Command | What it does |
|---|---|
| `tofu fmt -recursive` | Rewrites the files with the canonical style. Use `-check -diff` in CI to fail when a file is not formatted |
| `tofu validate` | Checks the syntax and the consistency of the configuration (types, references, required arguments). It does not call AWS |
| `tofu plan` | Shows what would change. Save it with `-out=tfplan` and read it with `tofu show tfplan` |
| `tofu console` | An interactive prompt to try expressions and functions against the real state |
| `tofu graph` | Prints the dependency graph in DOT format |
| `tofu state list`, `tofu state show <address>` | Inspect what is in the state |

```shell
$ tofu fmt -recursive -check -diff
$ tofu init -backend=false
$ tofu validate
Success! The configuration is valid.
```

`tofu init -backend=false` downloads providers and modules without touching the remote state, which is what a validation job needs.

Try an expression with `tofu console`:

```shell
$ tofu console
> cidrsubnet("172.21.0.0/19", 4, 1)
"172.21.2.0/23"
> module.network.subnet_ids["ditwl-sn-za-pro-pub-00"]
"subnet-09da811e23c212363"
```

To see the dependencies as an image (needs [Graphviz](https://graphviz.org/)):

```shell
$ tofu graph | dot -Tsvg > graph.svg
```

### TFLint: finds mistakes that `validate` cannot see

[TFLint](https://github.com/terraform-linters/tflint) is a linter. With the AWS ruleset it detects invalid instance types, deprecated arguments, unused variables or missing required versions.

```hcl title=".tflint.hcl"
plugin "terraform" {
  enabled = true
  preset  = "recommended"
}

plugin "aws" {
  enabled = true
  version = "0.40.0" # replace with the latest release of tflint-ruleset-aws
  source  = "github.com/terraform-linters/tflint-ruleset-aws"
}
```

```shell
$ tflint --init
$ tflint --recursive
```

### Security scanners: Trivy and Checkov

Misconfigurations are the most common cause of cloud incidents: an open security group, a public bucket, an unencrypted volume. Static scanners read the code and report them before deployment.

- **[Trivy](https://trivy.dev/)** scans Terraform and OpenTofu code (it includes the rules of the former tfsec) and also container images and dependencies.
- **[Checkov](https://www.checkov.io/)** has thousands of policies for AWS, Azure and GCP and supports custom policies.

```shell
$ trivy config .
$ checkov -d .
```

For example, both report the rule that the tutorial broke on purpose in [AWS Security Groups](https://www.itwonderlab.com/aws-terraform-tutorial-aws-security-groups/): SSH (port 22) open to `0.0.0.0/0`. When a finding is accepted, document the exception in the code, for example `#trivy:ignore:<rule-id>` or `#checkov:skip=<id>:reason`, so it is visible in the review.

### terraform-docs: documentation that does not get old

[terraform-docs](https://terraform-docs.io/) generates the inputs, outputs and requirements of a module from the code. Put these markers in the README of the module:

```markdown
<!-- BEGIN_TF_DOCS -->
<!-- END_TF_DOCS -->
```

and run:

```shell
$ terraform-docs markdown table --output-file README.md --output-mode inject modules/network
```

The tables between the markers are replaced and the rest of the file is kept.

### Infracost: the price before the apply

[Infracost](https://www.infracost.io/) estimates the monthly cost of the infrastructure from the code and, in a pull request, shows how much each change adds or saves.

```shell
$ infracost breakdown --path .
$ infracost diff --path . --compare-to infracost-base.json
```

It would have shown, for example, the difference between two and three NAT Gateways or the cost of the load balancer from [AWS Load Balancers](https://www.itwonderlab.com/aws-terraform-tutorial-aws-load-balancers/).

### Pre-commit: run everything before every commit

The [pre-commit](https://pre-commit.com/) framework runs the tools automatically when you commit. The [pre-commit-terraform](https://github.com/antonbabenko/pre-commit-terraform) collection has a hook for each tool above. By default it looks for the `terraform` binary: the `--tf-path` argument selects OpenTofu.

```yaml title=".pre-commit-config.yaml"
repos:
  - repo: https://github.com/antonbabenko/pre-commit-terraform
    rev: v1.99.0 # replace with the latest release
    hooks:
      - id: terraform_fmt
        args: [--hook-config=--tf-path=tofu]
      - id: terraform_validate
        args: [--hook-config=--tf-path=tofu]
      - id: terraform_tflint
      - id: terraform_trivy
      - id: terraform_docs
```

```shell
$ pip install pre-commit
$ pre-commit install
$ pre-commit run --all-files
```

The same checks run again in the pipeline of the next section, because a local hook can always be skipped.

### Other useful tools

- **Version managers**: [tenv](https://tofuutils.github.io/tenv/) installs and switches between OpenTofu, Terraform and Terragrunt versions, using the version in the `.opentofu-version` or `.terraform-version` file of the project.
- **Import existing resources**: an `import` block adopts a resource created by hand into the state, and `tofu plan` shows the result before anything is saved:

  ```hcl
  import {
    to = aws_s3_bucket.logs
    id = "ditwl-logs-bucket"
  }
  ```

- **State surgery**: `tofu state mv`, `tofu state rm` and `moved` / `removed` blocks, to reorganize the code without destroying resources (see [Terraform Modules](https://www.itwonderlab.com/aws-terraform-tutorial-terraform-modules/)).
- **Debugging**: `TF_LOG=debug tofu plan` prints the API calls and the internal decisions.
- **[Terragrunt](https://terragrunt.gruntwork.io/)**: a wrapper to keep configurations DRY when there are many environments and states.
- **Editor support**: the OpenTofu and Terraform language servers give completion, hover documentation and diagnostics in VS Code, IntelliJ and Neovim.

### A recommended order

1. `tofu fmt` and `tofu validate`: seconds, always.
2. TFLint: seconds, catches provider-specific mistakes.
3. Trivy or Checkov: seconds to a minute, security.
4. `tofu plan`: needs credentials, shows the real change.
5. Infracost: cost, in the pull request.

### Common Questions About Terraform Tools

#### Do these tools work with OpenTofu?

Yes. They read the same HCL language. Where a tool expects the `terraform` binary, there is an option to use `tofu` (as in the `--tf-path` argument above).

#### Which security scanner should I choose: Trivy or Checkov?

Either one. Trivy is one tool for code, containers and dependencies; Checkov has more cloud-specific policies and custom rules in Python or YAML. Many teams run one of them and review the report of the other from time to time.

#### Should the checks fail the build?

Formatting, validation and linting should. For security findings start with warnings, fix the existing ones and then make new high-severity findings fail the build.

### Next Steps

The code is formatted, checked and documented on every commit. The last section runs these checks, the plan and the apply automatically in a pipeline: [Terraform CI/CD](https://www.itwonderlab.com/aws-terraform-tutorial-terraform-cicd/).
