Open untcha opened 9 months ago
Thanks for reporting this!
I believe this is a consequence of a core assumption that tfautomv
makes: if it finds all the correct moves then Terraform's plan will be empty. By that assumption, if Terraform plans to replace a resource it's because the original resource was moved elsewhere and another resource was moved to where the first resource was. My understanding is that in your case this assumption was wrong, and that the aws_route
resources were really changing. But a wrong assumption is no excuse to generate broken code.
I'm trying to wrap my head around how tfautomv
should handle this sort of situation. I don't think that ignoring resources planned for replacement is the solution, because there are legitimate cases where such resources need to be moved. For instance:
- resource "random_pet" "alpha" {
+ resource "random_pet" "bravo" {
length = 2
}
- resource "random_pet" "bravo" {
+ resource "random_pet" "charlie" {
length = 3
}
In this example, Terraform would plan to replace the random_pet.bravo
resource but it was in fact moved to random_pet.charlie
and replaced by random_pet.alpha
. That being said, I'm not sure that tfautomv
handles that case perfectly either 😅 In this example, tfautomv
would need to generate 2 moves in a specific order, and I don't think it has logic to make sure of that.
The specific issue you describe is a bit more complex, because there is no valid order for the moves. Here's a variation on the previous example:
- resource "random_pet" "alpha" {
+ resource "random_pet" "bravo" {
length = 2
}
- resource "random_pet" "bravo" {
+ resource "random_pet" "alpha" {
length = 3
}
In this case, tfautomv
would need to swap the two resources. There's no way to do that atomically (Terraform processes moves one by one). I don't know if it's possible to move a resource to a third temporary address, with no matching code, or if this case simply can't be handled and tfautomv
should log that it needs the user's help here.
Now back to your specific case. I think the issue can be reproduced this way (I'll need to actually test this later):
resource "random_integer" "alpha" {
min = 1
- max = 2
+ max = 3
}
resource "random_pet" "alpha" {
length = random_integer.alpha.result
}
resource "random_integer" "bravo" {
min = 1
- max = 2
+ max = 3
}
resource "random_pet" "bravo" {
length = random_integer.bravo.result
}
In this example, both random_pet.alpha
and random_pet.bravo
are planned for replacement. The question is: how is tfautomv
supposed to know that it shouldn't move these random_pet
resources? I think the answer may be: because they have multiple matches. In this case, random_pet.alpha
matches both random_pet.bravo
and itself. Therefore, tfautomv
can't be sure where to move so it shouldn't move it.
I think that the bug here isn't that tfautomv
moves resources planned for replacement, but rather that tfautomv
doesn't consider the possibility of a resource matching itself.
This is a pretty subtle bug so I may be missing something. What is your take on this? 🤔
Hi Arthur,
first, sorry for the late reply (we were very busy with a big (state) migration - very successful thanks to tfautomv
😃), and thanks a lot for the detailed answer.
After we looked at your examples above, we believe that there are cases where the generation of moved blocks for replace actions is meaningful. But since tfautomv
is currently not able to reliably create these moved blocks in the correct order, we believe that the default should be to not act on terraform replace action.
Instead, we propose to add a parameter/flag e.g. --force-replace
to allow generation of moved blocks as it is currently implemented in latest version of tfautomv
, but without this parameter/flag no moved blocks should be created for replace actions.
What do you think about this proposal?
We found another issue when using
tfautomv
.The following shows automatically created moved blocks for 2 replaced "aws_route" resources. Which were cross-moved one to the other.
Resulting in this error:
The following is an original terraform plan output log when NOT using
tfautomv
which clearly proves that terraform already realized that the resource address has not changed.We believe that
tfautomv
should never act on replaced resources.In
pkg/engine/plan.go
in theSummarizeJSONPlan
function we wanted to identify the involved change actions. The "replace" results from the followingdelete
andcreate
actions in combination, which we simply printed out.Because
tfautomv
acts on each delete and create individually it tries to find an unnecessary "move partner" resource and only the other replaced one is available.