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
242 stars 168 forks source link

New single apply cloud provider access requires encryption_at_rest_provider set in mongodbatlas_cluster #452

Closed andrew-raczka closed 3 years ago

andrew-raczka commented 3 years ago

Terraform CLI and Terraform MongoDB Atlas Provider Version

Terraform v0.14.9
+ provider registry.terraform.io/hashicorp/aws v3.38
+ provider registry.terraform.io/mongodb/mongodbatlas v0.9.0

Terraform Configuration File

resource "mongodbatlas_cluster" "cluster" {
  project_id   = mongodbatlas_project.mongo_project.id
  name         = "${var.acc_short_alias}-${local.str_platform}-${local.str_tech_app}"
  cluster_type = var.cluster_type 

  provider_backup_enabled      = true
  pit_enabled                  = true
  auto_scaling_disk_gb_enabled = true
  mongo_db_major_version       = var.mongo_db_major_version
  # encryption_at_rest_provider  = "AWS"

  // Provider Settings "block"
  provider_name               = local.map_cluster.provider_name
  disk_size_gb                = var.disk_size_gb
  provider_volume_type        = var.provider_volume_type
  provider_instance_size_name = var.provider_instance_size_name
  provider_region_name        = local.map_cluster.provider_region_name 
}

resource "mongodbatlas_cloud_provider_access_setup" "mongo_cpa_setup" {
   project_id = mongodbatlas_project.mongo_project.id
   provider_name = "AWS"
}

resource "mongodbatlas_cloud_provider_access_authorization" "auth_role" {
   project_id =  mongodbatlas_cloud_provider_access_setup.mongo_cpa_setup.project_id
   role_id    =  mongodbatlas_cloud_provider_access_setup.mongo_cpa_setup.role_id

   aws = {
      iam_assumed_role_arn = aws_iam_role.mongo_encryption_role.arn
   }
}

resource "aws_iam_role" "mongo_encryption_role" {
  name               = "${var.acc_short_alias}-mongodb-encryption-role"
  tags               = var.map_tags
  assume_role_policy = jsonencode({
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": mongodbatlas_cloud_provider_access_setup.mongo_cpa_setup.aws.atlas_aws_account_arn
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": mongodbatlas_cloud_provider_access_setup.mongo_cpa_setup.aws.atlas_assumed_role_external_id
        }
      }
    }
  ]
})
}

resource "aws_iam_role_policy" "mongo_encryption_role_policy" {
  name   = "${var.acc_short_alias}-mongodb-encryption-role-policy"
  role   = aws_iam_role.mongo_encryption_role.id
  policy = jsonencode({
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "kms:Decrypt",
        "kms:Encrypt",
        "kms:DescribeKey"
      ],
      "Resource": "${var.key_arn}"
    }
  ]
})
}

resource "mongodbatlas_encryption_at_rest" "mongo_encryption" {
  project_id               = mongodbatlas_project.mongo_project.id
  aws_kms = {
    enabled                = true
    # role_id                = mongodbatlas_cloud_provider_access.mongo_cpa.role_id
    role_id                = mongodbatlas_cloud_provider_access_authorization.auth_role.role_id
    customer_master_key_id = data.aws_kms_key.kms.arn
    region                 = local.map_cluster.provider_region_name
  }
}

Steps to Reproduce

  1. 'terraform plan'
  2. 'terraform apply'

Expected Behavior

The cluster should be encrypted.

Actual Behavior

The cluster is not encrypted.

Additional Context

When using the two-apply method to deploy cloud provider access and encryption the officially documented steps work as intended when enabling CMEK encryption. When using the single-apply method, the encryption_at_rest_provider must be set within the mongodbatlas_cluster resource for CMEK encryption to be enabled. This attribute is not required and/or set by default with the two-apply method.

leofigy commented 3 years ago

Hello @andrew-raczka thanks for reaching. So reading in the documentation the parameter is optional but required to use encryption at rest.

https://registry.terraform.io/providers/mongodb/mongodbatlas/latest/docs/resources/cluster#encryption_at_rest_provider

Letting @themantissa and @nikhil-mongo to comment from a product perspective :)

themantissa commented 3 years ago

The parameter is required if the cluster is to be encrypted at rest w/ the customer key. It is marked as optional since it's not required to create a cluster. It is required irregardless of how cloud provider access is applied - which is a resource about IAM roles, not specifically encryption at rest - what causes it to be required is the mongodbatlas_encryption_at_rest resource. Hope that helps clear it up.

andrew-raczka commented 3 years ago

@themantissa I have not seen this to be the case. I've previously run the two-step apply for cloud provider access followed by creating the mongodbatlas_encryption_at_rest resource without encryption_at_rest_provider = "AWS" in the mongodbatlas_cluster resource and encryption was turned on successfully.

themantissa commented 3 years ago

@andrew-raczka as far as I'm aware nothing has changed and this has always been the case. If you've seen otherwise I'm not sure why you did.