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

Migration to mongodbatlas_cloud_provider_access_setup / authorization #451

Closed
JohnPolansky opened this issue May 2, 2021 · 4 comments
Closed

Comments

@JohnPolansky
Copy link

JohnPolansky commented May 2, 2021

Terraform CLI and Terraform MongoDB Atlas Provider Version

Terraform v0.15.1
on darwin_amd64
+ provider registry.terraform.io/hashicorp/aws v3.38.0
+ provider registry.terraform.io/hashicorp/kubernetes v2.1.0
+ provider registry.terraform.io/hashicorp/null v3.1.0
+ provider registry.terraform.io/hashicorp/time v0.6.0
+ provider registry.terraform.io/hashicorp/tls v3.1.0
+ provider registry.terraform.io/mongodb/mongodbatlas v0.9.0

Terraform Configuration File

Before Config (requires 2 applies)

resource "mongodbatlas_encryption_at_rest" "cloud" {
  project_id = mongodbatlas_project.cloud.id

  aws_kms = {
    enabled = true
    customer_master_key_id = aws_kms_key.mongodb-key.key_id
    region                 = var.mongodb.config.region 
    role_id                = mongodbatlas_cloud_provider_access.cloud.role_id
  }
}

resource "mongodbatlas_cloud_provider_access" "cloud" {
  project_id           = mongodbatlas_project.cloud.id
  provider_name        = "AWS"
  iam_assumed_role_arn = "arn:aws:iam::${var.aws.config.account_id}:role/${var.mongodb.config.project}-atlas_kms_access"
}

After Config (single apply)

resource "mongodbatlas_encryption_at_rest" "cloud" {
  project_id = mongodbatlas_project.cloud.id

  aws_kms = {
    enabled                = true
    customer_master_key_id = aws_kms_key.mongodb-key.key_id
    region                 = var.mongodb.config.region
    # role_id                = mongodbatlas_cloud_provider_access.cloud.role_id
    role_id = mongodbatlas_cloud_provider_access_setup.setup_only.role_id
  }
  depends_on = [mongodbatlas_cloud_provider_access_setup.setup_only, mongodbatlas_cloud_provider_access_authorization.auth_role ]
}

resource "mongodbatlas_cloud_provider_access_setup" "setup_only" {

  project_id    = mongodbatlas_project.cloud.id
  provider_name = "AWS"
}

resource "mongodbatlas_cloud_provider_access_authorization" "auth_role" {

  project_id = mongodbatlas_cloud_provider_access_setup.setup_only.project_id
  role_id    = mongodbatlas_cloud_provider_access_setup.setup_only.role_id

  aws = {
    iam_assumed_role_arn = "arn:aws:iam::${var.aws.config.account_id}:role/${var.mongodb.config.project}-atlas_kms_access"
  }
}

So I replace the old config with the new config on an existing MongoAtlas Project that had active clusters/data/encryption_at_rest already configured. Now I'm honestly not sure what I expected to happen I suppose I just hoped it would seamless transfer the config over.

However that obviously didn't happen instead I got errors:

│ Error: error deleting cloud provider access DELETE https://cloud.mongodb.com/api/atlas/v1.0/groups/XXXXXXXXXXXXXXXXXXXX/cloudProviderAccess/AWS/XXXXXXXXXXXXXXXXXXXX: 400 (request "AWS_IAM_ROLE_IN_USE") Cannot remove the AWS IAM role because it is still in use.
│
│
╵
╷
│ Error: error cloud provider access authorization PATCH https://cloud.mongodb.com/api/atlas/v1.0/groups/XXXXXXXXXXXXXXXXXXXX/cloudProviderAccess/XXXXXXXXXXXXXXXXXXXX: 409 (request "DUPLICATE_IAM_ASSUMED_ROLE_ARN") An AWS IAM Role has already been configured for the specified IAM Role ARN (arn:aws:iam::123456789000:role/cloud-trial-atlas_kms_access).
│
│   with module.mongodb.mongodbatlas_cloud_provider_access_authorization.auth_role,
│   on mongo-atlas/atlas-cluster.tf line 73, in resource "mongodbatlas_cloud_provider_access_authorization" "auth_role":
│   73: resource "mongodbatlas_cloud_provider_access_authorization" "auth_role" {

Obviously the errors make sense.. it's trying to delete an existing IAM ROLE that is being actively used by a mongo cluster, and trying to create a new one to replace it. So then I thought well maybe I can try and use import to "reclaim" the existing role thats how you do other TF objects normally. However again failure (or maybe I'm doing it wrong)

module.mongodb.mongodbatlas_cloud_provider_access_authorization.auth_role: Importing from ID "arn:aws:iam::123456789000:role/cloud-trial-atlas_kms_access"...
╷
│ Error: resource mongodbatlas_cloud_provider_access_authorization doesn't support import

So I guess my question by now should be obvious, what are the "migration steps" from using older 2 apply method to the single apply method? Right now the only way I can see it's possible is to completely delete all my clusters so nothing is using the encryption keys, and then apply but as I have several active clusters with active data this isn't very practical.

Lastly I was thinking, assuming my assumptions are correct, that there should be a WARNING on the terraform cloud_provider_access page to warn people that migrating between the two different methods requires destructive operations.

fingers-crossed I've missed something obvious or you can provide a path forward. Thanks for the help.

John

@JohnPolansky JohnPolansky changed the title Transition to mongodbatlas_cloud_provider_access_setup / authorization Migration to mongodbatlas_cloud_provider_access_setup / authorization May 2, 2021
@leofigy
Copy link
Contributor

leofigy commented May 3, 2021

Hello @JohnPolansky , thanks for reaching. of course we will need a migration guide.

Regarding the procedure, I think there are two missing steps

  • First do not remove the original resource 'til the import is complete
  • Second the import should go in mongodbatlas_cloud_provider_access_setup.

I mean, in your updated config

terraform import mongodbatlas_cloud_provider_access_setup.unique <project_id>-AWS-<role-id>

This will populate the state with the existing resource values, adding the authorization resource after that it will just try to patch, but it will not show the duplicate error.

So the procedure

  • Add the mongodbatlas_cloud_provider_access_setup resource, and perform the import command as well
  • Add the mongodbatlas_cloud_provider_access_authorization
  • Do a terraform plan/apply
  • Remove the old resource terraform state rm mongodbatlas_cloud_provider_access.test_role
  • Remove the resource from the config
  • Do a terraform plan (no changes detected)

@JohnPolansky
Copy link
Author

Awesome @leofigy! Thanks so much both for the quick reply and the awesome answer, I'm very happy to report your detailed migration steps worked perfectly in 2 out of 2 of my use-cases.

Thank you very much for saving me a bunch of time having to delete and rebuild the mongo clusters.

I've gone ahead and closed this ticket as resolved, I would appreciate if you can make sure to get these migration steps in the provider docs, they will save other people a lot of time.

@themantissa
Copy link
Collaborator

Internal ticket INTMDB-206 for doc add

@themantissa
Copy link
Collaborator

For anyone following - https://registry.terraform.io/providers/mongodb/mongodbatlas/latest/docs/guides/0.9.1-upgrade-guide now has the upgrade guide from 2 apply to 1 apply.

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

No branches or pull requests

3 participants