Validate a configuration
What terraform validate checks, and what it can't
Suppose you rename a variable and forget to update one reference, or you pass a string where a resource expects a number. You want to catch that in a second, not after a slow plan or a half-finished apply. That is exactly what terraform validate is for: it runs checks that verify whether a configuration is syntactically valid and internally consistent, regardless of any provided variables or existing state[1].
What it checks
validate works only from your .tf files. It confirms three things: that the HashiCorp Configuration Language (HCL) parses (syntax), that the configuration hangs together (internal consistency, for example that a reference points at something that exists and that there are no dependency cycles), and that the attribute names and value types[1] you wrote match what the referenced resources and providers actually accept. A typo in an argument name, or a number supplied where a string is required, fails here.
What it deliberately does not check
The boundary is the whole point of the command: validate does not validate remote services, such as remote state or provider APIs[1]. It never reads your state file and never generates an execution plan, so it cannot tell you whether your credentials work, whether a name is still free, or whether a resource can actually be created. It also cannot see drift, because detecting drift means comparing against the real world, and validate never contacts the real world.
The practical consequence, and the single most common misconception, is that a passing validate does not promise a successful apply. It proves the configuration is well-formed and type-correct; proving it will actually build requires terraform plan and terraform apply. Read validate as the compiler-style check you run before you spend time planning.
Prerequisites: initialize first, then validate
validate is not the first command you run in a directory. Validation requires an initialized working directory with any referenced plugins and modules installed[1], because it cannot type-check against a provider whose schema it has not downloaded. On a fresh checkout, terraform validate fails until you run terraform init[2] first.
Initialize without a backend when you only want to type-check
If all you want is the static check, you do not need remote state configured. Run terraform init -backend=false[2], which installs the providers and modules but skips backend initialization. This is the usual setup in a continuous integration (CI) job whose only task is to validate a module: it avoids wiring up credentials for a backend the job will never touch.
Running it
Once the directory is initialized, terraform validate takes no target: it checks the configuration in the current directory. It is read-only and contacts nothing, so it returns almost immediately. Two options are worth knowing:
| Option | Effect |
|---|---|
-json | Emits the result as machine-readable JSON (covered in the next section). |
-no-color | Suppresses color codes, which keeps CI logs readable. |
When validate finds a problem it reports an error with a source location, and Terraform does not continue validating once it catches an error[3], so you fix that error and re-run, repeating until the run is clean. The figure traces that loop: initialize once, validate, then either move on to terraform plan or fix and re-run.
Machine-readable output for automation
The reason validate fits cleanly into pipelines is its structured output. It is safe to run this command automatically, for example as a post-save check in a text editor or as a test step for a reusable module in a CI system[1], and the -json flag turns its result into a stable object a script can parse.
The -json result object
terraform validate -json prints a single JSON object. Its top-level fields are:
| Field | Type | Meaning |
|---|---|---|
format_version | string | Output format version, "1.0" since Terraform 1.1.0. |
valid | bool | Whether the configuration passed. |
error_count | number | How many errors were found. |
warning_count | number | How many warnings were found. |
diagnostics | array | One object per error or warning. |
Each entry in diagnostics[1] carries a severity of "error" or "warning", a short summary, an optional detail, and an optional range locating the offending source by filename with start and end positions. A script decides pass or fail by reading valid (or error_count) and can surface diagnostics inline in a pull request. The figure lays out that object and its nested diagnostic fields.
Validate as a module's unit test
validate is primarily useful for general verification of reusable modules[1]. A module author cannot run a real plan for every consumer, but validate confirms, cheaply and offline, that the module's own attribute names and value types are internally correct. Wiring terraform init -backend=false && terraform validate into CI gives every push a fast structural gate that needs no cloud credentials.
Exam-pattern recognition
TA-004 items on validate are definitional and lean on one boundary: what a static, offline check can and cannot prove. Keep that boundary sharp and the questions answer themselves.
A common stem describes a symptom and asks whether terraform validate would catch it. If the symptom is structural (a wrong attribute name, a type mismatch, an unresolved reference, a dependency cycle), validate catches it. If the symptom needs the real world (bad credentials, a name already taken, a quota exceeded, drift since the last apply), validate does not, because it never contacts provider APIs or remote state. The trap answer claims a clean validate guarantees a successful apply; reject it, since validate proves form and types only.
Another stem gives a fresh checkout and a failing terraform validate and asks why. The answer is that the directory is not initialized: run terraform init (or terraform init -backend=false) first so the providers and modules are installed. A distractor suggests running terraform plan or terraform refresh to fix it, but those also need an initialized directory and do far more than validate asks.
A CI-flavored stem asks how to check a module without cloud access. The answer pairs terraform init -backend=false with terraform validate, optionally -json for machine-readable output. Distractors reach for terraform plan, which contacts real infrastructure, or terraform fmt, which only fixes formatting and does not verify names or types.
Finally, watch the validate-versus-fmt-versus-plan distinction. terraform fmt rewrites style, terraform validate checks static correctness without touching infrastructure, and terraform plan compares your configuration against refreshed, real state. A question that asks which command previews real changes wants plan, not validate.
Three configuration checks, ordered by depth
| Aspect | terraform fmt | terraform validate | terraform plan |
|---|---|---|---|
| What it checks | Formatting and style only | Syntax, internal consistency, attribute names and value types | Desired configuration against real, refreshed state |
| Needs terraform init first? | No | Yes, providers and modules must be installed | Yes |
| Contacts provider APIs or state? | No | No | Yes, refreshes state by default |
| Changes anything? | Rewrites file style unless -check or -write=false | No, read-only | No, preview only |
| Typical use | Canonical formatting before commit | Fast correctness check in CI or an editor | Review the real changes before apply |
Decision tree
Sharp facts the exam loves — give these one last read before exam day.
Cheat sheet
Sharp facts the exam loves — scan these before test day.
- validate checks syntax and internal consistency
terraform validate verifies that a configuration is syntactically valid and internally consistent, regardless of any provided variables or existing state.
13 questions test this
- A terraform validate check passes in CI, but an engineer now needs to verify the same configuration in the context of a specific run, meaning a particular target workspace and a specific set of input
- An engineer clones a repository containing Terraform configuration and immediately runs terraform validate without running terraform init first. The command errors out before it checks the configurati
- A platform engineer wants to confirm that the Terraform files in a working directory are syntactically valid and internally consistent, but the target cloud account is currently offline and she does n
- A configuration declares an input variable named region that is required and has no default. No .tfvars file is present and no value is supplied on the command line. A teammate then runs terraform val
- A platform team wants a CI job that confirms a reusable module's Terraform files are syntactically valid and internally consistent on every pull request. The CI runner has no cloud credentials and mus
- A developer assigns a string to an argument that a resource expects to be a number, and also misspells another argument name so that it does not exist on that resource type. Running terraform validate
- An engineer configures an S3 remote backend and a cloud provider block, then runs terraform validate, expecting it to confirm that the remote state bucket is reachable and that the provider credential
- A developer runs `terraform fmt` on a module and, seeing it exit cleanly after tidying the indentation, tells a teammate the configuration is now confirmed correct. The teammate is skeptical and sugge
- An engineer relies on `terraform validate` to catch typos in resource argument names — for example writing `ami_id` where the resource type expects `ami` — before opening a pull request. For `terrafor
- In your continuous-integration pipeline, a terraform validate step runs against a module directory on every pull request. A teammate who is new to Terraform asks what a passing validate result actuall
- A developer sets `instance_type = "t2.mikro"` on a resource, accidentally misspelling a real machine size, and then runs `terraform validate` in a working directory that has already been initialized.
- A module author has no cloud credentials on her laptop and cannot deploy anything, but she wants to confirm that a reusable module's resource argument names and value types are correct before she publ
- While reviewing a reusable module before publishing it, an author already knows that terraform validate confirms the files parse correctly. She wants to understand what additional correctness check va
- validate checks attribute names and value types
terraform validate confirms that argument names and value types are correct for the resources and providers referenced, catching type mismatches and unknown attributes before a plan.
8 questions test this
- An engineer clones a repository containing Terraform configuration and immediately runs terraform validate without running terraform init first. The command errors out before it checks the configurati
- A developer assigns a string to an argument that a resource expects to be a number, and also misspells another argument name so that it does not exist on that resource type. Running terraform validate
- A developer runs `terraform fmt` on a module and, seeing it exit cleanly after tidying the indentation, tells a teammate the configuration is now confirmed correct. The teammate is skeptical and sugge
- An engineer relies on `terraform validate` to catch typos in resource argument names — for example writing `ami_id` where the resource type expects `ami` — before opening a pull request. For `terrafor
- A developer sets `instance_type = "t2.mikro"` on a resource, accidentally misspelling a real machine size, and then runs `terraform validate` in a working directory that has already been initialized.
- A module author has no cloud credentials on her laptop and cannot deploy anything, but she wants to confirm that a reusable module's resource argument names and value types are correct before she publ
- An engineer wants a local, offline command that will catch a misspelled (nonexistent) resource argument and an argument assigned the wrong value type, checking these against the provider schema withou
- While reviewing a reusable module before publishing it, an author already knows that terraform validate confirms the files parse correctly. She wants to understand what additional correctness check va
- validate does not check remote services
terraform validate does not validate remote services such as provider APIs or remote state, so it cannot confirm that credentials work or that a resource can actually be created.
Trap Assuming a passing validate guarantees a successful apply; it checks configuration correctness only, not real infrastructure or API access.
11 questions test this
- An engineer wants a command that, unlike `terraform validate`, actually reconciles the configuration against real remote objects by contacting the provider API and reading current state, so they can p
- A configuration is set up to store its state in a remote backend, but that backend is temporarily unreachable from the engineer's network. The engineer wants to check that a reusable module's configur
- A module author on a locked-down build agent has no access to the remote state backend but needs to confirm that a reusable module is internally consistent as part of a CI job. What is the correct way
- Ahead of a scheduled production deployment, an engineer wants a fast pre-flight check that the cloud provider credentials configured in their shell actually authenticate and that the provider's API is
- During testing, an engineer runs `terraform validate -var 'region=xx-fake-1'`, deliberately passing a region value that no cloud provider actually offers. The configuration is otherwise well-formed, a
- A new team member asks how `terraform validate` and `terraform plan` differ in terms of what infrastructure and state they actually touch when run with no extra flags. Which statement correctly distin
- A platform team's CI pipeline runs `terraform validate` on every pull request, and the command exits successfully for a change that adds a new cloud resource. A reviewer argues that because validate p
- A module author's CI pipeline runs only `terraform fmt` and `terraform validate` before publishing a reusable module to the private registry. A consumer later finds that `terraform apply` fails agains
- An engineer hard-codes an AMI ID into an `aws_instance` resource, but that AMI does not exist in the target account or region. The HCL is otherwise well-formed. They run `terraform validate` after `te
- An engineer clones a Terraform project onto a fresh laptop that has no cloud provider credentials configured at all. After running `terraform init`, they run `terraform validate` against the configura
- A team is documenting each command in their Terraform workflow. For `terraform validate`, which statement best describes the scope of what the command actually checks in a configuration directory?
- validate is not a plan
terraform validate does not read state or generate an execution plan, so it will not surface drift or runtime errors that only appear when Terraform contacts real infrastructure.
- validate requires an initialized directory
terraform validate requires an already-initialized working directory with referenced providers and modules installed; run terraform init (optionally with -backend=false) first.
Trap Thinking validate works on a fresh checkout without init; it needs providers and modules installed to type-check the configuration.
12 questions test this
- A platform engineer clones a teammate's Terraform repository onto a brand-new workstation and, before running anything else, immediately runs `terraform validate` to lint the HCL. Instead of a validat
- Your CI runner must run `terraform validate` on a configuration, but it has no credentials for the remote backend and you do not want initialization to contact or configure that backend. Which single
- While writing a Makefile target that runs `terraform validate`, an engineer must add a prior step that installs the referenced provider plugins and child modules into the working directory, since vali
- A developer clones a repository whose configuration references a cloud provider and a published registry module, then runs `terraform validate` on the untouched checkout expecting a quick syntax lint.
- A teammate is compiling a checklist of what `terraform validate` needs in order to run against a configuration as they set up a shared CI lint stage. Which of the following does `terraform validate` a
- A continuous integration job checks out your module into a clean container image and runs `terraform validate` as its first lint step, but every build fails at that step because the referenced provide
- Your root configuration includes a `module` block whose `source` points to a module on the public Terraform Registry. On a freshly cloned copy of the repository you run `terraform validate`, and it fa
- During a code review, a colleague insists that `terraform validate` is a purely offline syntax check and should therefore succeed on a fresh checkout with no setup at all. Which statement most accurat
- To let `terraform validate` run inside a CI container that has no backend credentials, an engineer initializes the directory with `terraform init -backend=false`. In terms of what actually gets set up
- Before adding `terraform validate` to an automated check, a developer is unsure whether it will refuse to run when no input variable values have been supplied and no state file exists yet for the conf
- An engineer wants a check that confirms their HCL is syntactically valid and internally consistent WITHOUT contacting the remote backend or any provider's API, and is unsure what setup that check need
- The `terraform validate` documentation notes that it is safe to run automatically, for example as a post-save editor check or a CI test step. A developer wires it into a pre-commit hook, but the hook
- validate supports JSON output and CI use
terraform validate -json produces machine-readable output, and the command is safe to run automatically, for example as an editor post-save check or a CI test step for a reusable module.