tfstateref

package module
v0.0.0-...-c6b8028 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2026 License: MIT Imports: 13 Imported by: 0

README

tfstateref-lint

Lint data "terraform_remote_state" references against the actual tfstate files.

A reference to a state file or output that doesn't exist is only detected when terraform plan runs. This tool reads the real state files with tfstate-lookup and reports broken references before that.

Checks:

  • state-existence: the state referenced by each data "terraform_remote_state" block exists
  • output-reference: each data.terraform_remote_state.X.outputs.Y reference (nested paths, lookup(), same-file local aliases) exists in the state

Supported backends: s3, gcs, azurerm, remote (Terraform Cloud / Enterprise), local, http.

Install

go install github.com/takaishi/tfstateref-lint/cmd/tfstateref-lint@latest

Usage

Credentials for the backend are required to read the state files (e.g. AWS credentials for s3, TFE_TOKEN for remote).

# lint ./terraform/ (default)
tfstateref-lint

# lint specific directories
tfstateref-lint terraform/service_a/staging terraform/service_b/staging

# JSON output
tfstateref-lint --json -q terraform/ | jq .

Logs go to stderr. With --json, results go to stdout:

{
  "dirs": ["terraform/"],
  "errors": [
    {
      "file": "terraform/service_a/staging/app/remote_state.tf",
      "message": "terraform_remote_state \"network\" references s3://amzn-s3-demo-bucket/env/network/terraform.tfstate, but the state could not be read"
    }
  ],
  "state_existence": { "checked": 12, "errors": [] },
  "output_reference": { "checked": 87, "errors": [] }
}

Exit codes: 0 = no errors, 1 = lint errors found, 2 = usage error.

GitHub Actions

name: tfstateref-lint

on:
  pull_request:
    paths:
      - "terraform/**/*.tf"

permissions:
  id-token: write
  contents: read

jobs:
  tfstateref-lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: stable
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/tfstateref-lint
          aws-region: ap-northeast-1
      - run: go install github.com/takaishi/tfstateref-lint/cmd/tfstateref-lint@latest
      - run: tfstateref-lint terraform/

The IAM role only needs s3:GetObject on the tfstate bucket. If state buckets live in multiple AWS accounts, split the job with a matrix and assume a role per account.

Limitations

  • backend, workspace and config values must be literals; blocks using variables are skipped

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrLintFailed = errors.New("lint errors found")

ErrLintFailed is returned when checks ran successfully but found errors.

View Source
var Revision = "HEAD"
View Source
var Version = "dev"

Functions

func RunCLI

func RunCLI(ctx context.Context, args []string) error

Types

type App

type App struct {
	CLI *CLI
}

func New

func New(cli *CLI) *App

func (*App) Run

func (app *App) Run(ctx context.Context) error

type CLI

type CLI struct {
	Dirs    []string    `arg:"" optional:"" help:"Directories to check (default: terraform/)."`
	Verbose bool        `name:"verbose" short:"v" help:"Verbose output (show OK results)."`
	Quiet   bool        `name:"quiet" short:"q" help:"Quiet mode (errors only, no progress)."`
	JSON    bool        `name:"json" help:"Output results as JSON to stdout."`
	Version VersionFlag `name:"version" help:"Show version."`
}

type CheckError

type CheckError struct {
	File    string `json:"file"`
	Message string `json:"message"`
}

CheckError represents a single lint error.

type CheckResult

type CheckResult struct {
	Checked int          `json:"checked"`
	Errors  []CheckError `json:"errors"`
}

CheckResult holds results for a single check.

type Checker

type Checker struct {
	// contains filtered or unexported fields
}

Checker holds the precomputed data and runs the checks.

func NewChecker

func NewChecker(dirs []string, verbose, quiet bool) *Checker

NewChecker creates a new Checker.

func (*Checker) Build

func (c *Checker) Build() error

Build scans the directories to build data needed for checks.

func (*Checker) Run

func (c *Checker) Run(ctx context.Context) *Result

Run executes the remote-state checks, returning the result.

type Result

type Result struct {
	Dirs            []string     `json:"dirs"`
	Errors          []CheckError `json:"errors"`
	StateExistence  *CheckResult `json:"state_existence,omitempty"`
	OutputReference *CheckResult `json:"output_reference,omitempty"`
}

Result is the top-level output structure.

func (*Result) OK

func (r *Result) OK() bool

OK returns true if no errors were found.

type UsageError

type UsageError struct {
	// contains filtered or unexported fields
}

UsageError indicates the tool was invoked incorrectly (exit code 2).

func NewUsageError

func NewUsageError(err error) *UsageError

func (*UsageError) Error

func (e *UsageError) Error() string

func (*UsageError) Unwrap

func (e *UsageError) Unwrap() error

type VersionFlag

type VersionFlag string

func (VersionFlag) BeforeApply

func (v VersionFlag) BeforeApply(app *kong.Kong, vars kong.Vars) error

func (VersionFlag) Decode

func (v VersionFlag) Decode(ctx *kong.DecodeContext) error

func (VersionFlag) IsBool

func (v VersionFlag) IsBool() bool

Directories

Path Synopsis
cmd
tfstateref-lint command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL