terraform
terraform copied to clipboard
State commands are failing on empty (non-pushed) state
Terraform Version
$ terraform version
Terraform v0.15.3
on linux_amd64
WSL2 Ubuntu-20.04
Terraform Configuration Files
terraform {
backend "s3" {}
}
Steps to Reproduce
On a blank environment (no existing state file in backend)!
$ terraform init -backend-config="bucket=${BUCKETNAME}" \
-backend-config="key=terraform.tfstate" \
-backend=true \
-get=true \
-input=false
$ terraform state list
Expected Behavior
it should return nothing and not fail
$ terraform state list
$ echo $?
0
Actual Behavior
$ terraform state list
No state file was found!
State management commands require a state file. Run this command
in a directory where Terraform has been run or use the -state flag
to point the command to a specific state location.
$ echo $?
1
Workaround
$ terraform init -backend-config="bucket=${BUCKETNAME}" \
-backend-config="key=terraform.tfstate" \
-backend=true \
-get=true \
-input=false
# This will push the "empty" state file to the backend
# $ terraform state push .terraform/terraform.tfstate
# See comment from @jbardin below.
$ terraform state list || true
Additional Context
We roll out terraform in CI/CD (concourse). The terraform configuration will be applied on multiple existing and new environments. We don't have the full control, when changes of the configuration will be rolled out to the actual environments. -> Different states across all environments
In the past we had some breaking changes in the configuration (restructuring modules, changing the source of the provider, etc.), which brought the need to manipulate the state during CI/CD rollout (e.g. by using terraform state mv
and terraform state replace-provider
) to avoid failing executions (provider source changed) and unnecessary recreation of resources (resource moved from module to root).
The state manipulations are working fine on existing infrastructure, but are failing on new (empty) environments. It seems, that the state commands (read and write) are only checking the remote state and are failing, if the state is not a the expected place.
I see two possible mitigations:
- When remote state does not exist, upload empty state on
init
- For all
state
commands, check local/temporary state file, if remote state does not exist
Hi @DJAlPee,
Thanks for filing the issue. While the remote state subsystem could be more consistent in this area, I would like to point out for you and others here that pushing the .terraform/terraform.tfstate
file is likely to cause other problems. That file within the .terraform/
directory is not for state storage, uses a different format which is incompatible with current resource state, and only continues to be named terraform.tfstate
for backwards compatibility.
Hi @jbardin,
You are right... In the meantime, I checked other alternatives, how to be more fault tolerant, with empty states. The only solution, I found so far is to ignore the error code (e.g. terraform state list || true
), but that's also not ideal...
I will update this issue, with this information!
Another thing I notice about this error message, not exactly related to the report at hand but maybe worth fixing if we're going to be making changes in this area anyway, is that it talks about the legacy -state
command line option which we only continue to support for backward-compatibility with pre-remote-state workflows on the local backend. Since this situation is using remote state, the -state
option wouldn't do anything at all here, and so it seems confusing to mention it at all.