Skip to content
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

Migrating resources from 1 state to another. #25

Closed
sidewinder12s opened this issue May 7, 2021 · 4 comments
Closed

Migrating resources from 1 state to another. #25

sidewinder12s opened this issue May 7, 2021 · 4 comments

Comments

@sidewinder12s
Copy link

I've got a few resources and modules I am trying to move from a monolithic state into smaller broken up states.

New state is entirely new, has just the resources and modules I want to move from the old state. I am using this tfmigrate config to test:

migration "multi_state" "mv_test" {
  from_dir = "."
  to_dir   = "../new_state"
  actions = [
    "mv aws_security_group.foo aws_security_group.foo",
    "mv aws_security_group.bar aws_security_group.bar",
    "mv module.s3-bucket-test module.s3-bucket-test",
  ]
}

When I test planned this, it always showed the new_state state had unexpected diffs, with it creating all the resources new and which failed the tfmigrate plan. I tried adding the force flag, which still showed the diff, but went ahead and applied it since this is a small test.

This seemed to properly migrate the 3 resources from the old state into the new state, with the new state showing no changes on plan.

Is this the intended workflow when doing a multi_state migration? Is the force flag required?

@minamijoyo
Copy link
Owner

@sidewinder12s It's not intentional. The force flag should not be required.
I'm not sure why the diff detected without your Terraform configurations. Could you provide the minimum example so that we can easily reproduce and debug the issue?

@sidewinder12s
Copy link
Author

I first applied Old state, then no diff.

New state was entirely new, so tfmigrate was the first thing to initialize the new state locally and remotely.

My actual goal outside of this test case is to move a few modules out of a large monolithic state into a dedicated, new, empty state.

Old State:

data "aws_caller_identity" "current" {}

resource "aws_security_group" "foo" {
  name = "foo"
}

resource "aws_security_group" "bar" {
  name = "bar"
}

module "s3-bucket-test" {
  source      = "../../../../modules/s3"
  bucket_name = "gweb-testing-2020-02-12-1304"
  temporary_bucket = true
}

New State:

data "aws_caller_identity" "current" {}

resource "aws_security_group" "foo" {
  name = "foo"
}

resource "aws_security_group" "bar" {
  name = "bar"
}

module "s3-bucket-test" {
  source      = "../../../../modules/s3"
  bucket_name = "gweb-testing-2020-02-12-1304"
  temporary_bucket = true
}

Actual output:

2021/05/08 10:13:37 [INFO] AWS Auth provider used: "SharedCredentialsProvider"
2021/05/08 10:13:38 [INFO] [runner] unapplied migration files: [tfmigrate.hcl]
2021/05/08 10:13:38 [INFO] [runner] load migration file: tfmigrate.hcl
2021/05/08 10:13:38 [INFO] [migrator] multi start state migrator plan
2021/05/08 10:13:38 [INFO] [migrator@.] terraform version: 0.14.10
2021/05/08 10:13:38 [INFO] [migrator@.] initialize work dir
2021/05/08 10:13:42 [INFO] [migrator@.] get the current remote state
2021/05/08 10:13:44 [INFO] [migrator@.] override backend to local
2021/05/08 10:13:44 [INFO] [executor@.] create an override file
2021/05/08 10:13:44 [INFO] [executor@.] switch backend to local
2021/05/08 10:13:46 [INFO] [migrator@../new_state] terraform version: 0.14.10
2021/05/08 10:13:46 [INFO] [migrator@../new_state] initialize work dir
2021/05/08 10:13:54 [INFO] [migrator@../new_state] get the current remote state
2021/05/08 10:13:56 [INFO] [migrator@../new_state] override backend to local
2021/05/08 10:13:56 [INFO] [executor@../new_state] create an override file
2021/05/08 10:13:56 [INFO] [executor@../new_state] switch backend to local
2021/05/08 10:13:58 [INFO] [migrator] compute new states (. => ../new_state)
2021/05/08 10:13:59 [INFO] [migrator@.] check diffs
2021/05/08 10:14:06 [ERROR] [migrator@.] unexpected diffs
2021/05/08 10:14:06 [INFO] [executor@../new_state] remove the override file
2021/05/08 10:14:06 [INFO] [executor@../new_state] switch back to remote
2021/05/08 10:14:20 [INFO] [executor@.] remove the override file
2021/05/08 10:14:20 [INFO] [executor@.] switch back to remote
terraform plan command returns unexpected diffs: failed to run command (exited 2): terraform plan -state=/tmp/tmp539983648 -out=/tmp/tfplan734123519 -input=false -no-color -detailed-exitcode
stdout:

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_security_group.bar will be created
  + resource "aws_security_group" "bar" {
      + arn                    = (known after apply)
      + description            = "Managed by Terraform"
      + egress                 = (known after apply)
      + id                     = (known after apply)
      + ingress                = (known after apply)
      + name                   = "bar"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + vpc_id                 = (known after apply)
    }

  # aws_security_group.foo will be created
  + resource "aws_security_group" "foo" {
      + arn                    = (known after apply)
      + description            = "Managed by Terraform"
      + egress                 = (known after apply)
      + id                     = (known after apply)
      + ingress                = (known after apply)
      + name                   = "foo"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + vpc_id                 = (known after apply)
    }

  # module.s3-bucket-test.aws_s3_bucket.this will be created
  + resource "aws_s3_bucket" "this" {
      + acceleration_status         = (known after apply)
      + acl                         = "private"
      + arn                         = (known after apply)
      + bucket                      = "gweb-testing-2020-02-12-1304"
      + bucket_domain_name          = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + region                      = (known after apply)
      + request_payer               = "BucketOwner"
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + lifecycle_rule {
          + abort_incomplete_multipart_upload_days = 3
          + enabled                                = true
          + id                                     = "full_bucket_abort_multipart_upload"
        }
      + lifecycle_rule {
          + enabled = false
          + id      = "full_bucket_intelligent_tiering_transition"

          + transition {
              + days          = 7
              + storage_class = "INTELLIGENT_TIERING"
            }
        }
      + lifecycle_rule {
          + enabled = true
          + id      = "full_bucket_ttl_bucket_expiration"

          + expiration {
              + days = 1
            }
        }

      + server_side_encryption_configuration {
          + rule {
              + apply_server_side_encryption_by_default {
                  + sse_algorithm = "AES256"
                }
            }
        }

      + versioning {
          + enabled    = false
          + mfa_delete = false
        }
    }

  # module.s3-bucket-test.aws_s3_bucket_metric.entire_bucket["true"] will be created
  + resource "aws_s3_bucket_metric" "entire_bucket" {
      + bucket = "gweb-testing-2020-02-12-1304"
      + id     = (known after apply)
      + name   = "EntireBucket"
    }

  # module.s3-bucket-test.aws_s3_bucket_ownership_controls.this will be created
  + resource "aws_s3_bucket_ownership_controls" "this" {
      + bucket = (known after apply)
      + id     = (known after apply)

      + rule {
          + object_ownership = "BucketOwnerPreferred"
        }
    }

  # module.s3-bucket-test.aws_s3_bucket_policy.policy_basic will be created
  + resource "aws_s3_bucket_policy" "policy_basic" {
      + bucket = (known after apply)
      + id     = (known after apply)
      + policy = (known after apply)
    }

  # module.s3-bucket-test.aws_s3_bucket_public_access_block.this will be created
  + resource "aws_s3_bucket_public_access_block" "this" {
      + block_public_acls       = true
      + block_public_policy     = false
      + bucket                  = (known after apply)
      + id                      = (known after apply)
      + ignore_public_acls      = false
      + restrict_public_buckets = false
    }

Plan: 7 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

This plan was saved to: /tmp/tfplan734123519

To perform exactly these actions, run the following command to apply:
    terraform apply "/tmp/tfplan734123519"


stderr:

@minamijoyo
Copy link
Owner

@sidewinder12s Looking at the log, the diff detected in the from_dir( . ). The plan will create moved resources in the from_dir. This means that the states will be moved, but the resources still have been defined in the configurations and will be created again in the from_dir. Could you confirm that you removed the Terraform configurations of moved resources in the from_dir?

@sidewinder12s
Copy link
Author

Ah that is it. Was not clear I needed to do that. Commented out the old state and it planned successfully.

~/Downloads/tfmigrate plan
2021/05/10 11:44:12 [INFO] AWS Auth provider used: "SharedCredentialsProvider"
2021/05/10 11:44:13 [INFO] [runner] unapplied migration files: [tfmigrate.hcl]
2021/05/10 11:44:13 [INFO] [runner] load migration file: tfmigrate.hcl
2021/05/10 11:44:13 [INFO] [migrator] multi start state migrator plan
2021/05/10 11:44:13 [INFO] [migrator@.] terraform version: 0.14.10
2021/05/10 11:44:13 [INFO] [migrator@.] initialize work dir
2021/05/10 11:44:16 [INFO] [migrator@.] get the current remote state
2021/05/10 11:44:19 [INFO] [migrator@.] override backend to local
2021/05/10 11:44:19 [INFO] [executor@.] create an override file
2021/05/10 11:44:19 [INFO] [executor@.] switch backend to local
2021/05/10 11:44:20 [INFO] [migrator@../new_state] terraform version: 0.14.10
2021/05/10 11:44:20 [INFO] [migrator@../new_state] initialize work dir
2021/05/10 11:44:23 [INFO] [migrator@../new_state] get the current remote state
2021/05/10 11:44:25 [INFO] [migrator@../new_state] override backend to local
2021/05/10 11:44:25 [INFO] [executor@../new_state] create an override file
2021/05/10 11:44:25 [INFO] [executor@../new_state] switch backend to local
2021/05/10 11:44:27 [INFO] [migrator] compute new states (. => ../new_state)
2021/05/10 11:44:28 [INFO] [migrator@.] check diffs
2021/05/10 11:44:35 [INFO] [migrator@../new_state] check diffs
2021/05/10 11:44:45 [INFO] [executor@../new_state] remove the override file
2021/05/10 11:44:45 [INFO] [executor@../new_state] switch back to remote
2021/05/10 11:44:49 [INFO] [executor@.] remove the override file
2021/05/10 11:44:49 [INFO] [executor@.] switch back to remote
2021/05/10 11:44:52 [INFO] [migrator] multi state migrator plan success!

Thank you for the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants