-
Notifications
You must be signed in to change notification settings - Fork 9.7k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Unable to "state mv" to a for_each resource #22301
Comments
Thank you for reporting this bug @jkburges ! We get an interesting different error when wrapping the resource in single quotes:
Here is a configuration one can use to reproduce this without creating resources that cost money - just comment out the
This might be a red herring, but it's worth looking at addrs.ParseTargetStr to make sure |
I think there are more problems around this than just rename resources in the state file. From what I've seen you can't remove resources in the state file either, and it's not possible to Here's the output I get when I try to remove a resource from a state: $ terraform state rm github_team_repository.developers["babaganush"]
Error: Index value required
on line 1:
(source code not available)
Index brackets must contain either a literal number or a literal string. |
Hi @Tenzer! I think you are running into something different - how different shells escape quotes.
|
Oh, that's interesting. I tried I wonder if that's something that can be detected by Terraform so it can provide more helpful information? That probably belongs in another bug report though. |
Hi @teamterraform,
I am using single quotes, also - but your error looks the same to me apart from the names? Your example differs from mine (aside from the resource type) in that you've used |
|
I am able to move resources within my state file, converting from count to for_each.
|
I think this is a different scenario to what I describe. I am trying to move two explicitly/separately defined resources to a |
When importing state, wrapping with single quotes isn't working with PowerShell. Escaping the double quotes with a backtick (how you'd normally escape things in pwsh) also doesn't work. What would be the correct syntax in that scenario?
|
@devblackops you might want to give the following syntax a try with PowerShell (since it requires extra escaping):
The documentation will be updated shortly to reflect this: #22318 For any further questions, it might be best to open a topic on the community forum so this bug report can stay on topic. 👍 |
Related Issue: #22375 There seems to be an oddity when using lists with only one element, as in the initial example. This doesn't happen when there are multiple list elements (see #22375 (comment)). I posted a dirty workaround for that in the related issue (#22375 (comment)). It adds the missing index with |
I'm facing the
Apparently, this is intentional:
Line 296 in c9d62bb
Is there any hope to get that changed, e.g. create the target resource with an index in the state even if it is the first instance at that resource address? For context, this prevents me from performing a large refactoring (> 400 resources) when moving from resources definitions (using Update: another work-around to allow the
|
@teamterraform Is there an update on a likely fix for this issue? It looks like it's not just a |
that means for count you can just leave the index off for the first one. But for a for_each there isn't any way to do this, since there is no "first" item. |
We are currently refactoring some modules to use for_each instead of count, and we are facing the same issue:
@teamterraform Any update on this issue, It make it really difficult to upgrade to TF 0.12 and to refactor the code. The workaround that I found is:
Now we will be able to other subnets using
|
Just bumped into this one :( |
This is a major issue which basically blocks migrating to |
The best workaround I've been able to find is @pdecat's hack of manually editing the state to add the resource object with an empty "instances" |
@morgante I posted a workaround in the related issue #22375 . Here is the current version of the script we are using to handle such cases. It uses # Example call: cat state.tfstate | ./move-single-element-tf012.sh "module.k8s.google_container_node_pool.pool" "pool1" > newstate.tfstate
resource_id="$1"
index_key="$2"
module="$(cut -d '.' -f2 <<< "$resource_id" )"
resource_type="$(cut -d '.' -f3 <<< "$resource_id" )"
resource_name="$(cut -d '.' -f4 <<< "$resource_id" )"
jq -M ".resources[
.resources | map(.type == \"${resource_type}\" and .module == \"module.${module}\" and .name == \"$resource_name\") | index(true)
].instances[0] +=
{\"index_key\": \"$index_key\"}" < /dev/stdin As we are only using resources from modules it only works with resources located in modules. But it should be easy enough to make it work for other structures as well. |
Another workaround is to add a dummy element to for_each and run This creates a aws_subnet.subnets[] resource and terraform edit: another workaround is |
Same here:
The destroy command also works:
Terraform file:
So it is possible to create users and delete from state, but if I need to import then, it's impossible, causing a lot of problems.
|
This is definitely the easiest workaround that doesn't involve editing the state directly and doesn't destroy the resource. |
You can also move the entire collection: terraform state list
aws_route53_record.ipv4["dev"]
aws_route53_record.ipv4["test"]
terraform state mv aws_route53_record.ipv4 aws_route53_record.ipv6
terraform state list
aws_route53_record.ipv6["dev"]
aws_route53_record.ipv6["test"] |
Assuming you are moving a for_each collection and not an individual item, or a count collection. |
Was able to find a somewhat simple workaround for going from a Takes two First, as @MetricMike suggested, move the whole collection (works even though its from
Then, move each integer index to the string index (notice it's already in the desired module, just the wrong key)
|
Same problem. This makes converting a bunch of individual imported CloudFlare dns entries into a simple for_each a pain. Additionally because the only way to make resources conditional is |
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. |
It doesn't seem possible to migrate existing code to use
for_each
without having to destroy/create resources.Terraform Version
Expected Behaviour
I should be able to move a resource to a
for_each
name to avoid having to destroy/create it.Actual Behaviour
Trying to
state mv
an existing (non for_each) resource, e.g.:Terraform Configuration Files
Version 1:
Version 2 (converting to
for_each
format):Steps to Reproduce
terraform init
terraform apply
# with <version 1 from above>terraform plan
# with <version 2 from above>At this point, we have some destroys and creates for EC2 instances:
So, we try to do a
terraform state mv
as above, to avoid the planned changes.The text was updated successfully, but these errors were encountered: