mongodb / terraform-provider-mongodbatlas

Terraform MongoDB Atlas Provider: Deploy, update, and manage MongoDB Atlas infrastructure as code through HashiCorp Terraform
https://registry.terraform.io/providers/mongodb/mongodbatlas
Mozilla Public License 2.0
241 stars 167 forks source link

Migration to mongodbatlas_cloud_provider_access_setup / authorization #451

Closed JohnPolansky closed 3 years ago

JohnPolansky commented 3 years ago

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

leofigy commented 3 years ago

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

Regarding the procedure, I think there are two missing steps

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

JohnPolansky commented 3 years ago

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 commented 3 years ago

Internal ticket INTMDB-206 for doc add

themantissa commented 3 years ago

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.