Cloud & DevOpsOpen SourceDeveloper ToolsInfrastructure

OpenTofu 1.13 Built-In Linting: What the Four Rules Catch

OpenTofu 1.13 built-in linting terminal output showing warnings for IaC code

OpenTofu 1.13 ships built-in linting. No TFLint installation. No .tflint.hcl config to maintain. No separate CI step. You append -lint=all to tofu validate, tofu plan, or tofu apply, and static analysis runs inside your normal workflow. The feature is experimental, fully opt-in, and available now in the v1.13.0-beta1 release.

That last part matters: opt-in means it will not break your existing pipelines. You can try it on one project today without touching anything else.

The Commands

The -lint flag works on four commands: validate, plan, apply, and refresh. Use -lint=all to enable every available rule, or list specific rules separated by commas.

# Enable all rules during a plan
tofu plan -lint=all

# Enable specific rules only
tofu plan -lint=core:no-type-variable,core:unused-variable

# Static-only check (no provider access needed)
tofu validate -lint=all

The distinction between validate and plan is meaningful. validate -lint is a pure static pass — it does not talk to any provider. plan -lint runs after the provider has evaluated your configuration, so it can catch issues that only become visible once OpenTofu knows what would actually be provisioned. That is architecturally different from how TFLint works, and it matters for catching runtime-conditional problems early.

The Four Built-In Rules

Version 1.13 ships four rules, all in the core namespace. Per the official linting documentation, these are the first iteration — more are planned.

core:no-type-variable

Flags input variables that have no declared type. Untyped variables accept any value and silently coerce types at runtime, which causes hard-to-debug mismatches when a caller passes a string where a number was expected.

# Triggers core:no-type-variable
variable "instance_type" {
  default = "t3.medium"
}

# Fix: add the type
variable "instance_type" {
  type    = string
  default = "t3.medium"
}

core:count-instead-enabled

The count = var.x ? 1 : 0 pattern for conditional resources has been the standard idiom for years. OpenTofu 1.11 introduced the enabled meta-argument as a cleaner replacement. This rule flags the old pattern and suggests the migration.

# Triggers core:count-instead-enabled
resource "aws_instance" "web" {
  count = var.deploy_web ? 1 : 0
  ami   = var.ami_id
}

# Fix: use enabled (OpenTofu 1.11+)
resource "aws_instance" "web" {
  enabled = var.deploy_web
  ami     = var.ami_id
}

Note that enabled is an OpenTofu-only meta-argument. If you maintain HCL that needs to run on both Terraform and OpenTofu, skip this rule for now.

core:unused-variable

Catches input variables that are declared but never referenced in your configuration. These accumulate over time as infrastructure evolves and old variables get orphaned without anyone noticing.

core:unused-local

The same check for local values. Locals defined and then abandoned are a minor but real maintenance burden, especially in large root modules with long histories.

What the Output Looks Like

$ tofu plan -lint=all

Warning: core:no-type-variable
  on main.tf line 1, in variable "instance_type":
  Variable "instance_type" has no type specified.

Warning: core:unused-variable
  on main.tf line 12, in variable "dead_flag":
  Variable "dead_flag" is declared but never referenced.

These surface as warnings, not errors. The plan still runs. You decide when to treat them as blocking in CI — add a --lint-error-level wrapper if you want failures on warnings.

Why This Beats TFLint for These Checks

TFLint is good. It has hundreds of provider-specific rules and years of production hardening. But integrating it requires a separate binary install, a .tflint.hcl config file, and a dedicated CI step that can drift out of sync with your OpenTofu version. OpenTofu’s built-in linting is zero-config and phase-aware. It runs inside the plan lifecycle, with access to the same evaluated configuration your provider sees.

For the four rules it currently covers, you get equivalent signal with none of the overhead. TFLint still wins on provider-specific depth — checking whether your chosen EC2 instance type actually exists, for example, is not something OpenTofu’s core rules do yet. But for code hygiene and structural patterns, the native approach is simpler to maintain at scale.

Where Terraform Stands

terraform validate checks syntax and basic schema conformance. There is no -lint flag, no unused variable detection, no structural recommendations. TFLint fills that gap as an external community tool. HashiCorp has no announced plans to add native linting to the Terraform CLI in 2026 — the roadmap is focused on Terraform Stacks and the HCP AI Ecosystem.

OpenTofu is adding features that Terraform does not have. It started with state encryption, early variable evaluation, OCI registry support, and the enabled meta-argument. Linting is the latest. The list keeps growing, and the OpenTofu linting vision post makes clear this is the beginning, not a one-off.

What Is Coming Next

After the experimental phase, the OpenTofu roadmap includes custom lint rules written in HCL, reusable rulesets shareable like modules, and a plugin system for complex checks needing provider access. If you publish a team ruleset and pin it like a module, you get organization-wide enforcement without configuring a separate tool in every repository.

Try It Now

The v1.13.0-beta1 build is available. Install it, run tofu plan -lint=all on an existing project, and see what surfaces. The output is informational — nothing breaks. If you have a codebase that accumulated variables over years of iteration, expect to find a few orphans.

OpenTofu’s linting is four rules today. The architecture for what comes next is already in place.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *