Repository navigation
Conversation
state_file was only passed to "terraform plan" (and "terraform output"). The commands that change resources did not get it: - state=present applied the saved plan without -state. When the plan had changes, Terraform compared it with the default terraform.tfstate and failed with "Saved plan does not match the given state". - state=absent ran "terraform destroy" without -state, so it reported no changes and left the resources in state_file. The same task in check mode reported changed=true, because its plan did use state_file. Pass the state arguments to both commands, and add an integration test that changes and destroys resources tracked in a custom state file. Fixes ansible-collections#6490 Assisted-by: Claude Opus 5.5 Signed-off-by: YoungjuKim <[email protected]>
24bf688 to
e95bc84
Compare
russoz
left a comment
There was a problem hiding this comment.
hi @fjvbn2003 thanks for your contribution!
I got only one nit to pick in the changelog fragment, other than that it LGTM
| @@ -0,0 +1,2 @@ | |||
| bugfixes: | |||
| - terraform - pass ``state_file`` to the ``apply`` and ``destroy`` commands, not only to ``plan``. Before, ``state=present`` failed with ``Saved plan does not match the given state`` when the plan had changes, and ``state=absent`` did not destroy the resources tracked in ``state_file`` (https://github.com/ansible-collections/community.general/issues/6490, https://github.com/ansible-collections/community.general/pull/12997). | |||
There was a problem hiding this comment.
No need to explain what happened before
| - terraform - pass ``state_file`` to the ``apply`` and ``destroy`` commands, not only to ``plan``. Before, ``state=present`` failed with ``Saved plan does not match the given state`` when the plan had changes, and ``state=absent`` did not destroy the resources tracked in ``state_file`` (https://github.com/ansible-collections/community.general/issues/6490, https://github.com/ansible-collections/community.general/pull/12997). | |
| - terraform - pass ``state_file`` to the ``apply`` and ``destroy`` commands, not only to ``plan`` (https://github.com/ansible-collections/community.general/issues/6490, https://github.com/ansible-collections/community.general/pull/12997). |
There was a problem hiding this comment.
Thanks! Applied the suggestion.
Apply the review suggestion: describe the fix, not the old behaviour. Assisted-by: Claude <[email protected]> Signed-off-by: YoungjuKim <[email protected]>
Backport to stable-13: 💚 backport PR created✅ Backport PR branch: Backported as #13055 🤖 @patchback |
Backport to stable-12: 💚 backport PR created✅ Backport PR branch: Backported as #13056 🤖 @patchback |
|
@fjvbn2003 thanks for contributing! |
…r apply and destroy (#13056) * terraform: use state_file for apply and destroy (#12997) * terraform: use state_file for apply and destroy state_file was only passed to "terraform plan" (and "terraform output"). The commands that change resources did not get it: - state=present applied the saved plan without -state. When the plan had changes, Terraform compared it with the default terraform.tfstate and failed with "Saved plan does not match the given state". - state=absent ran "terraform destroy" without -state, so it reported no changes and left the resources in state_file. The same task in check mode reported changed=true, because its plan did use state_file. Pass the state arguments to both commands, and add an integration test that changes and destroys resources tracked in a custom state file. Fixes #6490 Assisted-by: Claude Opus 5.5 Signed-off-by: YoungjuKim <[email protected]> * Shorten the terraform state_file changelog fragment Apply the review suggestion: describe the fix, not the old behaviour. Assisted-by: Claude <[email protected]> Signed-off-by: YoungjuKim <[email protected]> --------- Signed-off-by: YoungjuKim <[email protected]> (cherry picked from commit 51224d7) * Address differences to main. Co-authored-by: Felix Fontein <[email protected]> --------- Signed-off-by: YoungjuKim <[email protected]> Co-authored-by: Youngju KIM <[email protected]> Co-authored-by: Felix Fontein <[email protected]>
…r apply and destroy (#13055) * terraform: use state_file for apply and destroy (#12997) * terraform: use state_file for apply and destroy state_file was only passed to "terraform plan" (and "terraform output"). The commands that change resources did not get it: - state=present applied the saved plan without -state. When the plan had changes, Terraform compared it with the default terraform.tfstate and failed with "Saved plan does not match the given state". - state=absent ran "terraform destroy" without -state, so it reported no changes and left the resources in state_file. The same task in check mode reported changed=true, because its plan did use state_file. Pass the state arguments to both commands, and add an integration test that changes and destroys resources tracked in a custom state file. Fixes #6490 Assisted-by: Claude Opus 5.5 Signed-off-by: YoungjuKim <[email protected]> * Shorten the terraform state_file changelog fragment Apply the review suggestion: describe the fix, not the old behaviour. Assisted-by: Claude <[email protected]> Signed-off-by: YoungjuKim <[email protected]> --------- Signed-off-by: YoungjuKim <[email protected]> (cherry picked from commit 51224d7) * Address differences to main. Co-authored-by: Felix Fontein <[email protected]> --------- Signed-off-by: YoungjuKim <[email protected]> Co-authored-by: Youngju KIM <[email protected]> Co-authored-by: Felix Fontein <[email protected]>
SUMMARY
Fixes #6490
state_fileis passed toterraform plan(inbuild_plan()) and toterraform output, but not to the commands that change resources:state: presentbuilds the plan with-state <state_file>and then runsterraform apply ... <planfile>without-state. When the plan has changes, Terraform checks the plan against the defaultterraform.tfstateand fails withError: Saved plan does not match the given state(OpenTofu says "... it was created from a different state lineage").state: absentrunsterraform destroywithout-state. It reportsNo changes. No objects need to be destroyed, returnschanged: false, and leaves the resources instate_file. In check mode the same task reportschanged: true, because the check-mode plan usesstate_file. This is the problem reported in Terraform module - ignores state_file when state=absent #6490.This PR:
_state_args(module, state_file)to thedestroycommand forstate: absent;applycommand when the module built the plan itself. When the user givesplan_filewithstate: present, nothing changes, as the docs saystate_file"is ignored when plan is specified";tasks/state_file.yml) that creates a resource withterraform apply -state=custom.tfstate, adds a second resource with the module (state: present,state_file), and destroys both (state: absent,state_file). It checkschangedand the output ofterraform state list -state=custom.tfstate;When
state_filedoes not exist,_state_args()still warns and returns no arguments, so that case behaves as before.ISSUE TYPE
COMPONENT NAME
terraform
ADDITIONAL INFORMATION
I ran the module from
main(e7f0aa1) and from this branch with ansible-core 2.21.5 (from thev2.21.5tag, Python 3.12) and OpenTofu v1.9.0 asbinary_path, with thehashicorp/nullprovider. I did not have a Terraform binary available, so I have not run the new integration test with Terraform 1.1.7 as CI does.apply -state=... <planfile>,destroy -state=...andstate list -state=...are the legacy local-backend flags, which Terraform 1.x still has.state: absentwith a custom state file that holdsnull_resource.one:state: presentwith the same state file and one new resource in the configuration:The new integration test, run as a role (
include_role: terraform,tasks_from: state_file.yml) withterraform_binary_path=tofu:Without
state_file(defaultterraform.tfstate),present,absentin check mode, andabsentbehave the same before and after (allchanged=True, and no resources are left).This change was drafted with AI assistance and reviewed by me.
🤖 Generated with Claude Code