terraform-aws-modules / terraform-aws-dms

Terraform module to create AWS DMS (Database Migration Service) resources 🇺🇦
https://registry.terraform.io/modules/terraform-aws-modules/dms/aws
Apache License 2.0
62 stars 94 forks source link

AWS DMS Subnet Group creation requires the IAM Role to exist before it is created #6

Closed ricbartm closed 2 years ago

ricbartm commented 2 years ago

Describe the bug This is a race condition. We have seen the DMS Subnet Group creation failing because the IAM Role does not exist yet in the account.

Looks like the aws_dms_replication_subnet_group.this resource needs a dependency on aws_iam_role.dms_access_for_endpoint

Error: AccessDeniedFault: The IAM Role arn:aws:iam::REDACTED:role/dms-vpc-role is not configured properly.
with module.dms[0].aws_dms_replication_subnet_group.this[0]
on .terraform/modules/dms/main.tf line 89, in resource "aws_dms_replication_subnet_group" "this":
resource "aws_dms_replication_subnet_group" "this" {

To Reproduce It's a race condition. Provisioning a DMS task from scratch several times will cause the bug to show up.

Expected behavior Provisioning of DMS resources apply in the first attempt.

Additional context

module "dms" {
  source  = "clowdhaus/dms/aws"
  version = "1.0.2"
  count   = var.deploy_dms_resources ? 1 : 0

  # Subnet group
  repl_subnet_group_name        = local.identifier
  repl_subnet_group_description = "DMS Subnet group - ${local.identifier}-${local.workspace}"
  repl_subnet_group_subnet_ids  = tolist(data.aws_subnet_ids.services_data.ids)

  # Instance
  repl_instance_allocated_storage            = var.dms_allocated_storage
  repl_instance_auto_minor_version_upgrade   = true
  repl_instance_allow_major_version_upgrade  = true
  repl_instance_apply_immediately            = true
  repl_instance_engine_version               = var.dms_engine_version
  repl_instance_multi_az                     = true
  repl_instance_preferred_maintenance_window = var.dms_maintenance_window
  repl_instance_publicly_accessible          = false
  repl_instance_class                        = var.dms_instance_type
  repl_instance_id                           = local.identifier
  repl_instance_vpc_security_group_ids       = [module.rds.cluster_security_group_id]

  certificates = {
    source = {
      certificate_id  = "${local.identifier}-source",
      certificate_pem = file("ca_pem_files/${local.identifier}-source-ca.pem")
    },
    destination = {
      certificate_id  = "${local.identifier}-destination",
      certificate_pem = file("ca_pem_files/${local.identifier}-destination-ca.pem")
    }
  }

  endpoints = {
    source = {
      database_name               = "name"
      endpoint_id                 = "${local.identifier}-source"
      endpoint_type               = "source"
      engine_name                 = "mysql"
      extra_connection_attributes = ""
      username                    = var.dms_source_db_username
      password                    = var.dms_source_db_password
      port                        = 3306
      server_name                 = var.dms_source_db_host
      ssl_mode                    = "verify-ca"
      certificate_key             = "source"
      tags                        = var.tags
    }

    destination = {
      database_name               = "name"
      endpoint_id                 = "${local.identifier}-destination"
      endpoint_type               = "target"
      engine_name                 = "aurora"
      extra_connection_attributes = ""
      username                    = jsondecode(data.aws_secretsmanager_secret_version.rds_cluster.secret_string)["username"]
      password                    = jsondecode(data.aws_secretsmanager_secret_version.rds_cluster.secret_string)["password"]
      port                        = module.rds.cluster_port
      server_name                 = module.rds.cluster_writer_endpoint
      ssl_mode                    = "verify-full"
      certificate_key             = "destination"
      tags                        = var.tags
    }
  }

  replication_tasks = {
    replication_task = {
      replication_task_id       = local.identifier
      migration_type            = "full-load-and-cdc"
      replication_task_settings = file("configs/task_settings.json")
      table_mappings            = file("configs/table_mappings.json")
      source_endpoint_key       = "source"
      target_endpoint_key       = "destination"
      tags                      = var.tags
    }
  }

  tags = var.tags
}
bryantbiggs commented 2 years ago

:tada: This issue has been resolved in version 1.0.4 :tada:

The release is available on GitHub release

Your semantic-release bot :package::rocket:

ricbartm commented 2 years ago

Thanks for fixing this issue upstream. I planned to send a PR but got my week cannibalised, and you have been faster than me. 🎉 ❤️

bryantbiggs commented 2 years ago

thanks to @henworth 🎉

github-actions[bot] commented 1 year ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.