-
Notifications
You must be signed in to change notification settings - Fork 9.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Terraform changes a lot of resources when removing an element from the middle of a list #14275
Comments
Hi @joshuaspence! This is an issue we've had on our radar for a while now and have some ideas to deal with it, which will hopefully be included as part of a set of configuration language improvements coming in the future. The most promising idea so far is to add a new Thanks for reporting it! |
@apparentlymart Until said functionality is available, any thoughts around adding a CLI command to compact a list in the state file (e.g.
At this point |
That's an interesting idea, @ewbankkit! My first reaction to it is being a little nervous about it, since it's a single command that could create a lot of disruption in a state that would be hard to recover from if it's a mistake. However, perhaps as one of a suite of operations it would be okay, so that mistakes would be no more costly than accidentally running
This way if I make a mistake with the "remove one instance" operation I can use the "insert" operation to renumber everything back again, and then hopefully I expect no matter how we were to present it these commands would be a bit arcane and edge-casey, but this would still be superior to having users manually edit the state file to renumber things. I'm a little unsure as to what to name these three operations so that they are self-explaining and make sense together as a set. If you have any more thoughts here, maybe let's discuss this in a separate issue. |
The way we worked around this is by scripting a .tfstate transform. It moves to the end of a list the resources we want to remove... |
We also use count to create a lot of instances of various resource types (aws_ecr_repository is one example). We provide a list of repo names and use count to iterate. But, as mentioned here if you either add a new entry to the list in any position other than the end, or, if you delete an entry from anywhere other than the last, Terraform we destroy and recreate every resource from that point. Doesn't this sound like a case for passing a map into a resource so that resource creation / deletion is based on the explicit key rather than rely on the ordinal position in a list ? I suppose if we could interpolate the resource name itself that might do it, but I'm not sure how practical that is ? Anyway, whatever the underlaying implementation, this problem is really hurting us. We currently use Terraform 0.9.11. Is a solution likely in the near term ? Can you suggest any other work-arounds other than manipulating the data backend state file (not something I'm especially attracted towards) ? Kind Regards Fraser. |
I wrote a utility for editing count in the state file, but would like to see a fix as well. |
@apparentlymart Do you have any idea of what the timeframe might be for a fix to this issue? Thanks! |
I am running into this issue with generation of ECR repos. I'd be interested to know where this is on your radar @apparentlymart? I assume the current workaround is to utilise a map as per @goffinf's suggestion? |
If we replace Index by the values on tfstate, this can solve the problem if value is unique on list and this work perfectly on map. On this case, we can create iterator and use value to not change count function. If we want to use more complexe date we can store position on tfstate and manage rewrire index data with diff on variable list or map. |
@sebglon could you show an example of your first suggestion please |
yes on tfstate you put index on resources. For list if i use value if it is not duplicated, i can use the same. instead of using count, you can create iterate function to make it work. |
Could anybody help to figure out timeframe or any workaround, except removing resources from state and importing them back? |
Hi @rkul, as a workaround, you can use |
@pdecat Thank you, I appreciate your response, but it might be too hard to move half of list elements every time. |
I also worked around by reimporting all the resources ( |
Hi all! Sorry for the long silence here... there's a handful of overlapping issues on this topic and so it's often hard to keep up with updates in all of them. 😖 I think the best sum-up of progress here is over in #17179. To summarize: we'd like to address this not by adding new commands to manipulate the state but instead by creating the possibility for the multiple instances of a resource block to be identified by map keys (strings) rather than indexes. For @joshuaspence's original use-case, for example: # NOT YET IMPLEMENTED, and details may change before release
variable "zone_names" {
type = "list"
default = []
}
resource "aws_route53_zone" "ctld" {
# this is the new "for expression" syntax included in the improved configuration language, coming soon.
# turns a list like ["example.com"] into a map like {"example.com" => "example.com"}
for_each = {for name in var.zone_names: name => name}
name = each.value
}
resource "aws_route53_record" "www" {
for_each = {for name in var.zone_names: name => name}
zone_id = aws_route53_zone.ctld[each.key].id
name = "www"
type = "A"
alias {
# ...
}
} Since the resource instances in the above example would be identified by the strings in Our expectation is that Since this issue was (due to my early comments) primarily focused on ways to work around the problem via new plumbing commands, I'm going to close this one just to consolidate ongoing discussion in #17179. I'll post more updates there when we're ready to finalize the details and do the final implementation of the Thanks for sharing your workarounds here, everyone! |
This worked for me. Whenever there is a destroy of a specific instance. I manually moved the ids as mentioned above using "terraform state mv" command and updated my vars files (vars as an input to terraform scripts(.tf files)) accordingly. Temporary fix until we get a solution. But that's ok. We rarely do delete |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. |
We have a lot of AWS Route53 zones which are setup in exactly the same way. As such, we are using
count
and alist
variable to manage these. The code basically looks like this:However, the problem with this is that Terraform references resources using a numeric identifier. As such, if we remove an element from the middle of the list then Terraform will want to recreate all resources with a larger numeric index. This can be minimally reproduce with the following code snippet:
Run
terraform apply
and then remove"bar"
fromvar.names
. The subsequent plan is as follows:I thought that one possible way to fix this would be if Terraform could index a list of resources by its identifier rather than its sequence in a list.
The text was updated successfully, but these errors were encountered: