A for_each key inside a module
Two steps, a stable key, and brackets that need quoting on the command line
module.vpc.aws_subnet.private["eu-west-1a"]
Break an address into its steps: the module path first, the resource last. Two things here are what actually break terraform state and -target commands, and neither produces a helpful error.
Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.
The answer appears here
Paste on the left and press Parse. Nothing leaves this tab.
Nothing else to flag.
No formatting problems, and nothing the rules object to. Worth remembering what that covers: this reads the file you pasted, not the account or cluster it will be applied to.
No finding matches that filter.
Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.
Two steps, a stable key, and brackets that need quoting on the command line
module.vpc.aws_subnet.private["eu-west-1a"]
Valid as an expression and rejected as an address, and the error names the resource
aws_instance.web.id
Positional, so removing an earlier element makes this address point somewhere else
aws_instance.web[0]
These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.
terraform state show aws_instance.web.id reports that no such resource is in state. The address is fine up to the attribute, so the error points at the wrong thing.
Instead:Drop everything after the resource name. Keep the attribute only inside expressions.
zsh fails on the glob before Terraform runs; bash silently strips the double quotes and hands Terraform a different address.
Instead:Always single-quote the whole address: terraform state rm 'module.a["k"]'.
web[1] is the second element of a list, not a particular server. Removing web[0] renumbers everything, so the addresses now point at different objects.
Instead:Use for_each keyed by something meaningful when the collection can change in the middle.
Addresses look like the references you write in configuration and are a narrower thing. The two differences below are where the time goes.
aws_instance.web.id is a valid expression and not a valid address. terraform state show and -target want the resource, so the trailing .id makes them report a resource that does not exist, which reads like a state problem rather than one extra component.
terraform state rm module.a["k"] unquoted: zsh fails on the glob before Terraform starts, and bash strips the double quotes so Terraform receives an address that is not what you typed. Wrap the whole address in single quotes, every time, and the problem disappears.
aws_instance.web[0] is the first element of a count. Remove an earlier element and every later index shifts, so this address now names a different object and Terraform destroys and recreates the tail of the list. That is the reason to prefer for_each.
aws_subnet.private["eu-west-1a"] keeps its identity when other keys are added or removed. The key is part of the address, so choosing keys that mean something makes state readable years later.
-target and state list accept module.vpc and act on everything inside it. state show needs a single object and rejects it. Targeting a module is a bigger hammer than people expect, since it pulls in every resource the module declares.
data.aws_ami.ubuntu appears in state list, which inflates the count and confuses cleanup. It is re-read every plan, so removing it from state changes nothing, and destroy ignores it entirely.