Skip to main content
DevOps Insightsguides & answers

Terraform · troubleshooting

Error: Reference to undeclared resource

Terraform found a reference to a resource that does not exist in the module where the reference is written. Usually a typo, a resource that lives in another module, or a data source referenced without the "data." prefix.

Reproduced on Terraform 1.14.0, . Where the text says “reproduced”, the behaviour was run on that version, not taken from documentation.

First published

New to this? Read what is actually happening first, then come back to the steps.

On this page · 8 sections

Before you start

  • The configuration directory, and terraform init already run in it.

Run this first

step 1 of 1
terraform validate

Look for The module named at the end of each message, and any Did you mean line

Reports every undeclared reference without contacting any provider.

Work out which cause you have

A few questions to narrow the list. Every answer ends in a command that confirms or rules the cause out — this cannot see your cluster, so nothing here is a certainty until you have checked.

Narrow it down

0 answered · nothing is sent anywhere

Which fits your case?

Cause space

4 of 4 still possible

  • The type or name is misspelt, or the resource was renamedCommon
  • The resource lives in another moduleCommon
  • A data source referenced without data.Common
  • The resource is in a different directory or configurationOccasional

Nothing ruled out yet. Answer the question above and the branches your answer eliminates will strike through here.

Or diagnose it manually

In this order. The first command usually contains the whole answer.

  1. Step 1

    terraform validate

    Reports every undeclared reference without contacting any provider.

    Look for The module named at the end of each message, and any Did you mean line

Every cause, and how to fix it

Ordered by how often each one turns out to be the answer.

The type or name is misspelt, or the resource was renamed

Common

The reference and the resource block disagree by a character, or the block was renamed and some references were not updated.

Confirm

grep -rn 'resource "TYPE"' --include='*.tf' .

The exact name the resource block uses. A match in a subdirectory is in a different module: see the next cause

Fix

  • Correct the reference to match the block.
  • If you renamed a resource that already exists, also add a moved block from the old address to the new one (it tells Terraform the existing object now has a new address), or the next plan destroys and recreates it.

The resource lives in another module

Common

Modules cannot see each other's resources. A resource inside a child module is invisible to the root, and a root resource is invisible inside the child.

Confirm

grep -rln 'resource "TYPE" "NAME"' --include='*.tf' .

A file in a different directory from the one with the reference

Fix

  • Child to root: add an output to the child module and read module.CHILD.OUTPUT.
  • Root to child: add a variable to the child module and pass the value in the module block.
output "vpc_id" {
  value = terraform_data.vpc.id
}

In the child module; then use module.net.vpc_id in the root. Reproduced on Terraform 1.14.0.

A data source referenced without data.

Common

A data block is referenced as data.TYPE.NAME. Without the prefix Terraform looks for a resource block of that name, and does not find one.

Confirm

terraform validate

Did you mean the data resource data.TYPE.NAME?

Fix

  • Add data. in front of the reference.

The resource is in a different directory or configuration

Occasional

Terraform loads only the .tf files at the top level of the directory you run it in; subdirectories are separate modules and are not included unless a module block loads them. A resource managed by a different configuration, with its own state, is not visible at all.

Confirm

ls *.tf; pwd

The file with the resource is not in this list

Fix

  • Run Terraform in the directory that declares the resource, or load that directory with a module block.
  • For a resource managed by another configuration, read it with a data source or that configuration's outputs (terraform_remote_state), instead of referencing it directly.

Understanding it properly

Skip this if you are mid-incident — the working part of the page is above. Worth reading afterwards, because understanding the mechanism is what stops the next one.

In plain terms

Each Terraform module has its own separate set of names. A reference such as aws_instance.web only looks inside the module whose files contain it, never in parent or child modules and never in other folders. When nothing with that type and name is declared there, Terraform stops before planning anything.

Words used on this page

Module
The .tf files in one directory. The root module is the directory you run Terraform in; each module block loads another one.
Managed resource
A resource block. Terraform's error calls it managed to tell it apart from a data resource, which is a data block.
Module output
The only way a value leaves a module: an output block inside it, read from outside as module.NAME.OUTPUT.
What is actually happening

Reproduced on Terraform 1.14.0 with terraform validate. A misspelt name (terraform_data.webb where the resource is web) printed Error: Reference to undeclared resource and A managed resource "terraform_data" "webb" has not been declared in the root module, with no suggestion of the right name.

A resource declared in a child module and referenced from the root printed the same message. The reverse, a root resource referenced from inside the module, said "has not been declared in module.net." The last words of the message name the module Terraform searched, which is the fastest clue.

A data block referenced without data. at the front printed the same error, and here Terraform added "Did you mean the data resource data.terraform_remote_state.shared?"

How to tell this is your problem
WhereWhat you see
terraform validate, plan or applyError: Reference to undeclared resource ... A managed resource "TYPE" "NAME" has not been declared in the root module.
Inside a module... has not been declared in module.NAME.
Data sourceDid you mean the data resource data.TYPE.NAME?

How to know it is actually fixed

  • terraform validate prints Success! The configuration is valid.

Stopping it happening again

  • Run terraform validate in CI on every pull request.
  • When renaming resources, search for every reference and add a moved block in the same change.

Sources

Behaviour described here is drawn from official documentation. Where a figure could not be confirmed on an official page it is attributed in the text rather than stated as canonical.

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere

Something wrong or out of date? Report it