terraform icon indicating copy to clipboard operation
terraform copied to clipboard

State commands are failing on empty (non-pushed) state

Open DJAlPee opened this issue 3 years ago • 3 comments

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:

  1. When remote state does not exist, upload empty state on init
  2. For all state commands, check local/temporary state file, if remote state does not exist

DJAlPee avatar May 11 '21 09:05 DJAlPee

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.

jbardin avatar May 11 '21 12:05 jbardin

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!

DJAlPee avatar May 11 '21 14:05 DJAlPee

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.

apparentlymart avatar May 11 '21 17:05 apparentlymart