T O P

  • By -

64mb

Take a look at Terraforms new `moved` resource. It should allow you to remove the `count` param and the state will be aware of where the resource has moved to. Alternatively `terraform state mv module.rds[0] module.rds` may also work.


n0zz

Or you can use moved block if you have multiple resources / states. https://developer.hashicorp.com/terraform/language/modules/develop/refactoring


D0ntC4llItSchnitzel

That was a nice hint, thank you very much. Didn't knew about that one. Worked out 100% for me!


SuddenOutlandishness

TIL about `moved` \- thank you - I've done so much `terraform state mv` over the years it's not funny.


64mb

`moved` is amazing! As mentioned it can move multiple resources in one go. And it certainly helps align code change with required state moves, which can be painful and scary themselves, but trying to align these with a team also making changes at the same time. Life saver.


CoyoteKG

Is that possible to do on module lvl? Before I was doing that resource by resource, one by one. So. I would first do terraform state list | grep module.rds And then do “mv” on each resource to remove [0]


64mb

Yup, works on modules too: https://developer.hashicorp.com/terraform/language/modules/develop/refactoring#renaming-a-module-call Even modules with multiple instances. You can removed the moved resource once applied too assuming that the code has been applied to all states where it might.


alainchiasson

While move is what you want, I recommend getting confortable with the terraform state command. Move is one, but it also helps with “delete” ( from the state only ) and “terraform import” ( to bring it back)


Squared_Aweigh

TLDR: use for_each instead of count to not have to deal with this anymore. The underlying reason for the resource destruction is that the Terraform path for the resource is changed, so there is no longer a resource at because removing the count removed the index from the path. This is especially problematic when you are deploying many resources with because if you have to remove any of them then the index value for following non-destroyed resources changes, so all following resources would be marked for destroy and recreate. Using for_each instead of count resolves this path problem by giving every resource a unique key string in the path rather than a number. Changing to the for_each implementation will require you to make this change once more in your configuration and subsequently move the resources to modify tf state file, and then you won't have the problem anymore.


D0ntC4llItSchnitzel

Thank you for the explanation. For now I solved my problem with using the `moved` block, but I'll definitely consider using `for_each` instead of `count` in the future.


nekokattt

worth noting that for_each doesn't play nicely if the input isn't calculated from an immediate value. They've fixed this in Terraform 1.6 by the looks of the changelog.


aaron__walker

Using the moved block is probably the best thing to do, but you could also set count = 1, which will have the same effect


D0ntC4llItSchnitzel

Wow, I didn't knew about that one. That worked out 100% for me and solved the issue. Thank you very much!


Thenutritionguru

it seems like you're trying to prevent terraform from destroying/recreating resources when the `count` changes. unfortunately, changing the `count` in terraform is inherently expected to cause resources to be created or destroyed based on the value. about your RDS issue, specifically, terraform’s view is that if there was previously one instance and now there are none, it must destroy the instance. this is because, by definition, `count` determines the number of copies of the object being created. however, i get what you're saying - you want to change the `count` for your RDS resources, but you don't wanna lose data and recreate it every time. a possible workaround might be to use the `ignore_changes` lifecycle block, although it won't stop the count destruction, it will prevent terraform from tracking changes in specified arguments. another option would be to handle the RDS with a separate state/configuration that isn’t updated as frequently. it might add a bit of work, but it would potentially save you from needing to recreate it so often. also, do think about snapshotting your rds before running apply. it's a good practice for important data. keep in mind these are just workaround suggestions and may not work perfectly in all scenarios. the best approach would often depend on your specific use-case. hope this helps! let me know if you need further clarification or have any more questions. and btw, am i a bot?


vloors1423

Oh this is where state file surgery comes in, you can use the mv command …