-
Notifications
You must be signed in to change notification settings - Fork 10.1k
Description
Terraform Version
% terraform version
Terraform v1.15.0-dev
on darwin_arm64Terraform Configuration Files
Any configuration can be used to reproduce this issue.
Debug Output
N/A
Expected Behavior
Terraform should raise an error, or at least warning, if a terraform apply command tries to apply a plan against a workspace that doesn't match the workspace that the plan was prepared against. An explicit message saying something like 'the plan expected workspace A but the working directory currently has workspace B selected' would help users figure out what's gone wrong in their workflow.
Actual Behavior
Assume that a plan was raised against workspace A and a user tries to apply it against workspace B.
The actual behaviour varies depending on the type of plan and what state already exists for workspace B.
- If the plan is create-only, starting from a position of empty state, and workspace B has no state yet then the apply will complete successfully
- If the plan is create-only, starting from a position of empty state, and workspace B has a prior state then the apply will fail with error
Saved plan is stale. - If the plan is changing existing resources, i.e. planned using prior state in workspace A, and workspace B has no prior state then the apply will fail with a
different state lineageerror.
In case 2 & 3 the apply stops before making any changes to state, however the error messages don't clearly point out that mismatched workspaces are the underlying cause.
In case 1 users will find that the new state file is persisted in a different location than they expected. The output from the apply command doesn't say which workspace the apply affected, so the user might not notice the issue immediately.
Steps to Reproduce
See #37919 for E2E tests reproducing the 3 cases above.
To reproduce the 3 cases I described above:
Case 1
terraform init- While default workspace selected, run
terraform plan -out=tfplanto create a plan file - Run
terraform workspace create foobarto create and select a custom workspace - Run
terraform apply tfplanto apply the plan file - See that new state is created for the custom workspace
Case 2
terraform init- Run
terraform workspace create foobarto create and select a custom workspace terraform applyto create some state in the custom workspaceterraform workspace select defaultto change workspace to the empty default workspace- Run
terraform plan -out=tfplanto create a plan file.- This plan describes creating resources from an empty state starting point
terraform workspace select foobarto change to the custom workspace again- Run
terraform apply tfplanto apply the plan file - There should be an error reporting the plan is stale.
Case 3
terraform initterraform applyto create state in the default workspace- Change the configuration so that there's a diff when
planis run next - Run
terraform plan -out=tfplanto create a plan file.- The plan will describe changing existing resources
- Run
terraform workspace create foobarto create and select a custom workspace - Run
terraform apply tfplanto apply the plan file - There should be an error reporting that there's a mismatch of state lineage.
Additional Context
The BackendForLocalPlan method has a godoc comment that suggests that it asserts the plan's workspace matches the current workspace:
terraform/internal/command/meta_backend.go
Lines 330 to 332 in 64015ca
| // The current workspace name is also stored as part of the plan, and so this | |
| // method will check that it matches the currently-selected workspace name | |
| // and produce error diagnostics if not. |
It doesn't look like this was implemented at the time (see commit) that method was written.
This work has also touched the BackendForLocalPlan method #25262 but this just validates that the current workspace name is valid. It doesn't include comparison to the value in the plan file.
I'm going to open a PR adding that assertion, but I'll also ask around to see if this is something that was purposefully dropped in the past. Currently Terraform does protect against any existing state being affected in these scenarios, and there might be considerations around HCP Terraform that make this assertion trickier to implement smoothly for all backends in use.
References
- Reproductions in E2E tests: do not merge: Show that planning for one workspace, switching, and then applying the plan in the wrong workspace doesn't fail #37919
Generative AI / LLM assisted development?
No response