Terraform state mv for_each module

Viewed 814

As part of a refactoring we're doing to our infrastructure, I'm trying to create a new hierarchy of modules and resources, and as part of it we are extracting some common infrastructure between modules.
I have a module (let's name it worker) currently at the main.tf file from which I start, which is a module with multiple instance (using a for_each):

module "worker" {
    for_each = local.workers
    source = "../base_service"
}

And now as part of the refactor, we want to create a base module which contains a lot of shared infrastructure:

module "worker" {
    source   = "../base_worker"
}
module "base_worker" {
    for_each = local.workers
    source = "../base_service"
}

This is simplified of course, but basically my module has been moved from module.worker[*] to module.worker.module.base_worker[*]

What I'm trying to do is rename the entire module all at once. I tried to find any built-in way in Terraform to do this but couldn't, and so I end up having to do terraform state mv 'module.worker["worker_name"]' 'module.worker.module.base_worker["worker_name"]' for each worker name in my locals.

When I try to run terraform state mv 'module.worker' 'module.worker.module.base_worker' I get a No source address error, and when I try to run terraform state mv 'module.worker[*]' 'module.worker.module.base_worker' I get a Splat expressions (.*) may not be used here

1 Answers

I just did some refactoring of configuration into a module, and I think I saved some effort by first making this script tf-bulk-move.sh:

#!/bin/bash
set -eo pipefail

tfdir=$1
sed_expr=$2

cd $tfdir
while read line; do
  terraform state mv $line $(echo "$line" | sed -e "$sed_expr")
done < "statelist.txt"

Then in the module dir I ran

$ terraform state list > statelist.txt

And I took out lines for addresses that I didn't want changed. Then I did chmod +x on the script and ran it (this just prepends "module.env." to a bunch of addresses):

$ ./tf-bulk-move.sh ../env/dev "s/^/module.env./"
Related