Moving terraform resources to a new code base

3 min read | by Jordi Prats

If we have a set of resources on a set of terraform code that we want to move to another code base, we could use terraform import to import them to the new state but this required make the effort to identify the resources to import. If are going to import the entire state we can make it much easier using terraform state pull and terraform state push

To import the entire state from, let's say project A, into project B we can get into project A, get the state in JSON format using terraform state pull to then pipe it into terraform state push on the project B. It's one of these rare things that it's easier done than said it:

$ cd project_A
$ terraform state pull | (cd ../project_B;  terraform state push -)
Acquiring state lock. This may take a few moments...
Releasing state lock. This may take a few moments...

Once we have the state imported into project B we can use terraform plan to identify what needs to be moved around:

$ terraform plan | grep "resource " -B1
  # module.kms-keys.aws_iam_policy.kms_read_policy[0] will be destroyed
  - resource "aws_iam_policy" "kms_read_policy" {
--
  # module.kms-keys.aws_iam_policy.ssm_read_policy[0] will be destroyed
  - resource "aws_iam_policy" "ssm_read_policy" {
--
  # module.kms-keys.aws_kms_alias.kms_key_alias[0] will be destroyed
  - resource "aws_kms_alias" "kms_key_alias" {
--
  # module.kms-keys.aws_kms_key.kms_key[0] will be destroyed
  - resource "aws_kms_key" "kms_key" {
--
  # module.kms-keys["ec2"].module.kms-keys.aws_iam_policy.kms_read_policy[0] will be created
  + resource "aws_iam_policy" "kms_read_policy" {
--
  # module.kms-keys["ec2"].module.kms-keys.aws_iam_policy.ssm_read_policy[0] will be created
  + resource "aws_iam_policy" "ssm_read_policy" {
--
  # module.kms-keys["ec2"].module.kms-keys.aws_kms_alias.kms_key_alias[0] will be created
  + resource "aws_kms_alias" "kms_key_alias" {
--
  # module.kms-keys["ec2"].module.kms-keys.aws_kms_key.kms_key[0] will be created
  + resource "aws_kms_key" "kms_key" {

Once we know where we want the imported resources to be (lines starting with +) we can move them using terraform mv:

$ terraform state mv 'module.kms-keys' 'module.kms-keys["ec2"].module.kms-keys'
Acquiring state lock. This may take a few moments...
Move "module.kms-keys" to "module.kms-keys[\"ec2\"].module.kms-keys"
Successfully moved 1 object(s).
Releasing state lock. This may take a few moments...

We can also use terraform state pull / terraform state push to keep a local copy of the state as a backup if we are using a remote state


Posted on 30/09/2021

Categories