Home

Awesome

AWS DMS Terraform module

Terraform module which creates AWS DMS (Database Migration Service) resources.

Usage

See examples directory for working examples to reference:

module "database_migration_service" {
  source  = "terraform-aws-modules/dms/aws"
  version = "~> 2.0"

  # Subnet group
  repl_subnet_group_name        = "example"
  repl_subnet_group_description = "DMS Subnet group"
  repl_subnet_group_subnet_ids  = ["subnet-1fe3d837", "subnet-129d66ab", "subnet-1211eef5"]

  # Instance
  repl_instance_allocated_storage            = 64
  repl_instance_auto_minor_version_upgrade   = true
  repl_instance_allow_major_version_upgrade  = true
  repl_instance_apply_immediately            = true
  repl_instance_engine_version               = "3.5.2"
  repl_instance_multi_az                     = true
  repl_instance_preferred_maintenance_window = "sun:10:30-sun:14:30"
  repl_instance_publicly_accessible          = false
  repl_instance_class                        = "dms.t3.large"
  repl_instance_id                           = "example"
  repl_instance_vpc_security_group_ids       = ["sg-12345678"]

  endpoints = {
    source = {
      database_name               = "example"
      endpoint_id                 = "example-source"
      endpoint_type               = "source"
      engine_name                 = "aurora-postgresql"
      extra_connection_attributes = "heartbeatFrequency=1;"
      username                    = "postgresqlUser"
      password                    = "youShouldPickABetterPassword123!"
      port                        = 5432
      server_name                 = "dms-ex-src.cluster-abcdefghijkl.us-east-1.rds.amazonaws.com"
      ssl_mode                    = "none"
      tags                        = { EndpointType = "source" }
    }

    destination = {
      database_name = "example"
      endpoint_id   = "example-destination"
      endpoint_type = "target"
      engine_name   = "aurora"
      username      = "mysqlUser"
      password      = "passwordsDoNotNeedToMatch789?"
      port          = 3306
      server_name   = "dms-ex-dest.cluster-abcdefghijkl.us-east-1.rds.amazonaws.com"
      ssl_mode      = "none"
      tags          = { EndpointType = "destination" }
    }
  }

  replication_tasks = {
    cdc_ex = {
      replication_task_id       = "example-cdc"
      migration_type            = "cdc"
      replication_task_settings = file("task_settings.json")
      table_mappings            = file("table_mappings.json")
      source_endpoint_key       = "source"
      target_endpoint_key       = "destination"
      tags                      = { Task = "PostgreSQL-to-MySQL" }
    }
  }

  event_subscriptions = {
    instance = {
      name                             = "instance-events"
      enabled                          = true
      instance_event_subscription_keys = ["example"]
      source_type                      = "replication-instance"
      sns_topic_arn                    = "arn:aws:sns:us-east-1:012345678910:example-topic"
      event_categories                 = [
        "failure",
        "creation",
        "deletion",
        "maintenance",
        "failover",
        "low storage",
        "configuration change"
      ]
    }
    task = {
      name                         = "task-events"
      enabled                      = true
      task_event_subscription_keys = ["cdc_ex"]
      source_type                  = "replication-task"
      sns_topic_arn                = "arn:aws:sns:us-east-1:012345678910:example-topic"
      event_categories             = [
        "failure",
        "state change",
        "creation",
        "deletion",
        "configuration change"
      ]
    }
  }

  tags = {
    Terraform   = "true"
    Environment = "dev"
  }
}

Combinations

Within DMS you can have multiple combinations of resources depending on your use case. For example (not an exhaustive list of possible combinations):

Simple

<p align="center"> <img src="https://raw.githubusercontent.com/terraform-aws-modules/terraform-aws-dms/master/.github/images/dms_simple.png" alt="DMS Simple" width="100%"> </p>

Multiple endpoints, multiple tasks

<p align="center"> <img src="https://raw.githubusercontent.com/terraform-aws-modules/terraform-aws-dms/master/.github/images/dms_complex.png" alt="DMS Complex" width="100%"> </p>

In order to accommodate a flexible, multi-resource combinatorial module, keys and maps are used for cross-referencing resources created within the module.

Given the following example (not complete, only showing the relevant attributes):

module "database_migration_service" {
  source  = "terraform-aws-modules/dms/aws"
  version = "~> 2.0"

  # This value is used when subscribing to instance event notifications
  repl_instance_id = "readme-example"

  endpoints = {
    # These keys are used to map endpoints within task definitions by this key `source1`
    source1 = {
      endpoint_type = "source"
      ...
    }

    destination1 = {
      endpoint_type = "target"
      ...
    }

    destination2 = {
      endpoint_type = "target"
      ...
    }
  }

To create replication tasks, you simply reference the relevant keys from the endpoints map in the source_endpoint_key/target_endpoint_key fields:

  ...

  replication_tasks = {
    src1_dest1 = {
      ...
      source_endpoint_key = "source1"
      target_endpoint_key = "destination1"
    }
    src1_dest2 = {
      ...
      source_endpoint_key = "source1"
      target_endpoint_key = "destination2"
    }
  }

  ...

Continuing the same lookup pattern, to create event subscriptions, you simply reference the replication instance ID in the instance_event_subscription_keys field when subscribing to instance notifications, or the replication_tasks keys in the task_event_subscription_keys to subscribe to the tasks notifications (all or only select keys for select tasks):

  ...

  event_subscriptions = {
    instance = {
      instance_event_subscription_keys = ["readme-example"]
      ...
    }
    task = {
      task_event_subscription_keys = ["src1_dest1", "src1_dest2]
      ...
    }
  }

  ...

Tasks

Tasks are the "jobs" that perform the necessary actions of migrating from source to target, including any transformations and/or mappings of the data in transit. Tasks are largely controlled by task settings that are defined in a JSON document.

<p align="center"> <img src="https://raw.githubusercontent.com/terraform-aws-modules/terraform-aws-dms/master/.github/images/replication_task.png" alt="Replication Task" width="100%"> </p>

Example task settings JSON document:


{
  "TargetMetadata": {
    "TargetSchema": "",
    "SupportLobs": true,
    "FullLobMode": false,
    "LobChunkSize": 64,
    "LimitedSizeLobMode": true,
    "LobMaxSize": 32,
    "BatchApplyEnabled": true
  },
  "FullLoadSettings": {
    "TargetTablePrepMode": "DO_NOTHING",
    "CreatePkAfterFullLoad": false,
    "StopTaskCachedChangesApplied": false,
    "StopTaskCachedChangesNotApplied": false,
    "MaxFullLoadSubTasks": 8,
    "TransactionConsistencyTimeout": 600,
    "CommitRate": 10000
  },
  "Logging": {
    "EnableLogging": false
  },
  "ControlTablesSettings": {
    "ControlSchema":"",
    "HistoryTimeslotInMinutes":5,
    "HistoryTableEnabled": false,
    "SuspendedTablesTableEnabled": false,
    "StatusTableEnabled": false
  },
  "StreamBufferSettings": {
    "StreamBufferCount": 3,
    "StreamBufferSizeInMB": 8
  },
  "ChangeProcessingTuning": {
    "BatchApplyPreserveTransaction": true,
    "BatchApplyTimeoutMin": 1,
    "BatchApplyTimeoutMax": 30,
    "BatchApplyMemoryLimit": 500,
    "BatchSplitSize": 0,
    "MinTransactionSize": 1000,
    "CommitTimeout": 1,
    "MemoryLimitTotal": 1024,
    "MemoryKeepTime": 60,
    "StatementCacheSize": 50
  },
  "ChangeProcessingDdlHandlingPolicy": {
    "HandleSourceTableDropped": true,
    "HandleSourceTableTruncated": true,
    "HandleSourceTableAltered": true
  },
  "ErrorBehavior": {
    "DataErrorPolicy": "LOG_ERROR",
    "DataTruncationErrorPolicy":"LOG_ERROR",
    "DataErrorEscalationPolicy":"SUSPEND_TABLE",
    "DataErrorEscalationCount": 50,
    "TableErrorPolicy":"SUSPEND_TABLE",
    "TableErrorEscalationPolicy":"STOP_TASK",
    "TableErrorEscalationCount": 50,
    "RecoverableErrorCount": 0,
    "RecoverableErrorInterval": 5,
    "RecoverableErrorThrottling": true,
    "RecoverableErrorThrottlingMax": 1800,
    "ApplyErrorDeletePolicy":"IGNORE_RECORD",
    "ApplyErrorInsertPolicy":"LOG_ERROR",
    "ApplyErrorUpdatePolicy":"LOG_ERROR",
    "ApplyErrorEscalationPolicy":"LOG_ERROR",
    "ApplyErrorEscalationCount": 0,
    "FullLoadIgnoreConflicts": true
  }
}

Examples

Examples codified under the examples are intended to give users references for how to use the module(s) as well as testing/validating changes to the source code of the module. If contributing to the project, please be sure to make any appropriate updates to the relevant examples to allow maintainers to test your changes and to keep the examples up to date for users. Thank you!

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

Requirements

NameVersion
<a name="requirement_terraform"></a> terraform>= 1.0
<a name="requirement_aws"></a> aws>= 5.32
<a name="requirement_time"></a> time>= 0.9

Providers

NameVersion
<a name="provider_aws"></a> aws>= 5.32
<a name="provider_time"></a> time>= 0.9

Modules

No modules.

Resources

NameType
aws_dms_certificate.thisresource
aws_dms_endpoint.thisresource
aws_dms_event_subscription.thisresource
aws_dms_replication_config.thisresource
aws_dms_replication_instance.thisresource
aws_dms_replication_subnet_group.thisresource
aws_dms_replication_task.thisresource
aws_dms_s3_endpoint.thisresource
aws_iam_policy.accessresource
aws_iam_role.accessresource
aws_iam_role.dms_access_for_endpointresource
aws_iam_role.dms_cloudwatch_logs_roleresource
aws_iam_role.dms_vpc_roleresource
aws_iam_role_policy_attachment.accessresource
aws_iam_role_policy_attachment.access_additionalresource
time_sleep.wait_for_dependency_resourcesresource
aws_caller_identity.currentdata source
aws_iam_policy_document.accessdata source
aws_iam_policy_document.access_assumedata source
aws_iam_policy_document.dms_assume_roledata source
aws_iam_policy_document.dms_assume_role_redshiftdata source
aws_partition.currentdata source
aws_region.currentdata source

Inputs

NameDescriptionTypeDefaultRequired
<a name="input_access_iam_role_description"></a> access_iam_role_descriptionDescription of the rolestringnullno
<a name="input_access_iam_role_name"></a> access_iam_role_nameName to use on IAM role createdstringnullno
<a name="input_access_iam_role_path"></a> access_iam_role_pathIAM role pathstringnullno
<a name="input_access_iam_role_permissions_boundary"></a> access_iam_role_permissions_boundaryARN of the policy that is used to set the permissions boundary for the IAM rolestringnullno
<a name="input_access_iam_role_policies"></a> access_iam_role_policiesMap of IAM role policy ARNs to attach to the IAM rolemap(string){}no
<a name="input_access_iam_role_tags"></a> access_iam_role_tagsA map of additional tags to add to the IAM role createdmap(string){}no
<a name="input_access_iam_role_use_name_prefix"></a> access_iam_role_use_name_prefixDetermines whether the IAM role name (access_iam_role_name) is used as a prefixbooltrueno
<a name="input_access_iam_statements"></a> access_iam_statementsA map of IAM policy statements for custom permission usageany{}no
<a name="input_access_kms_key_arns"></a> access_kms_key_arnsA list of KMS key ARNs the access IAM role is permitted to decryptlist(string)[]no
<a name="input_access_secret_arns"></a> access_secret_arnsA list of SecretManager secret ARNs the access IAM role is permitted to accesslist(string)[]no
<a name="input_access_source_s3_bucket_arns"></a> access_source_s3_bucket_arnsA list of S3 bucket ARNs the access IAM role is permitted to accesslist(string)[]no
<a name="input_access_target_dynamodb_table_arns"></a> access_target_dynamodb_table_arnsA list of DynamoDB table ARNs the access IAM role is permitted to accesslist(string)[]no
<a name="input_access_target_elasticsearch_arns"></a> access_target_elasticsearch_arnsA list of Elasticsearch ARNs the access IAM role is permitted to accesslist(string)[]no
<a name="input_access_target_kinesis_arns"></a> access_target_kinesis_arnsA list of Kinesis ARNs the access IAM role is permitted to accesslist(string)[]no
<a name="input_access_target_s3_bucket_arns"></a> access_target_s3_bucket_arnsA list of S3 bucket ARNs the access IAM role is permitted to accesslist(string)[]no
<a name="input_certificates"></a> certificatesMap of objects that define the certificates to be createdmap(any){}no
<a name="input_create"></a> createDetermines whether resources will be createdbooltrueno
<a name="input_create_access_iam_role"></a> create_access_iam_roleDetermines whether the ECS task definition IAM role should be createdbooltrueno
<a name="input_create_access_policy"></a> create_access_policyDetermines whether the IAM policy should be createdbooltrueno
<a name="input_create_iam_roles"></a> create_iam_rolesDetermines whether the required DMS IAM resources will be createdbooltrueno
<a name="input_create_repl_instance"></a> create_repl_instanceIndicates whether a replication instace should be createdbooltrueno
<a name="input_create_repl_subnet_group"></a> create_repl_subnet_groupDetermines whether the replication subnet group will be createdbooltrueno
<a name="input_enable_redshift_target_permissions"></a> enable_redshift_target_permissionsDetermines whether redshift.amazonaws.com is permitted access to assume the dms-access-for-endpoint roleboolfalseno
<a name="input_endpoints"></a> endpointsMap of objects that define the endpoints to be createdany{}no
<a name="input_event_subscription_timeouts"></a> event_subscription_timeoutsA map of timeouts for event subscription create/update/delete operationsmap(string){}no
<a name="input_event_subscriptions"></a> event_subscriptionsMap of objects that define the event subscriptions to be createdany{}no
<a name="input_iam_role_permissions_boundary"></a> iam_role_permissions_boundaryARN of the policy that is used to set the permissions boundary for the rolestringnullno
<a name="input_iam_role_tags"></a> iam_role_tagsA map of additional tags to apply to the DMS IAM rolesmap(string){}no
<a name="input_repl_instance_allocated_storage"></a> repl_instance_allocated_storageThe amount of storage (in gigabytes) to be initially allocated for the replication instance. Min: 5, Max: 6144, Default: 50numbernullno
<a name="input_repl_instance_allow_major_version_upgrade"></a> repl_instance_allow_major_version_upgradeIndicates that major version upgrades are allowedbooltrueno
<a name="input_repl_instance_apply_immediately"></a> repl_instance_apply_immediatelyIndicates whether the changes should be applied immediately or during the next maintenance windowboolnullno
<a name="input_repl_instance_auto_minor_version_upgrade"></a> repl_instance_auto_minor_version_upgradeIndicates that minor engine upgrades will be applied automatically to the replication instance during the maintenance windowbooltrueno
<a name="input_repl_instance_availability_zone"></a> repl_instance_availability_zoneThe EC2 Availability Zone that the replication instance will be created instringnullno
<a name="input_repl_instance_class"></a> repl_instance_classThe compute and memory capacity of the replication instance as specified by the replication instance classstringnullno
<a name="input_repl_instance_engine_version"></a> repl_instance_engine_versionThe engine version number of the replication instancestringnullno
<a name="input_repl_instance_id"></a> repl_instance_idThe replication instance identifier. This parameter is stored as a lowercase stringstringnullno
<a name="input_repl_instance_kms_key_arn"></a> repl_instance_kms_key_arnThe Amazon Resource Name (ARN) for the KMS key that will be used to encrypt the connection parametersstringnullno
<a name="input_repl_instance_multi_az"></a> repl_instance_multi_azSpecifies if the replication instance is a multi-az deployment. You cannot set the availability_zone parameter if the multi_az parameter is set to trueboolnullno
<a name="input_repl_instance_network_type"></a> repl_instance_network_typeThe type of IP address protocol used by a replication instance. Valid values: IPV4, DUALstringnullno
<a name="input_repl_instance_preferred_maintenance_window"></a> repl_instance_preferred_maintenance_windowThe weekly time range during which system maintenance can occur, in Universal Coordinated Time (UTC)stringnullno
<a name="input_repl_instance_publicly_accessible"></a> repl_instance_publicly_accessibleSpecifies the accessibility options for the replication instanceboolnullno
<a name="input_repl_instance_subnet_group_id"></a> repl_instance_subnet_group_idAn existing subnet group to associate with the replication instancestringnullno
<a name="input_repl_instance_tags"></a> repl_instance_tagsA map of additional tags to apply to the replication instancemap(string){}no
<a name="input_repl_instance_timeouts"></a> repl_instance_timeoutsA map of timeouts for replication instance create/update/delete operationsmap(string){}no
<a name="input_repl_instance_vpc_security_group_ids"></a> repl_instance_vpc_security_group_idsA list of VPC security group IDs to be used with the replication instancelist(string)nullno
<a name="input_repl_subnet_group_description"></a> repl_subnet_group_descriptionThe description for the subnet groupstringnullno
<a name="input_repl_subnet_group_name"></a> repl_subnet_group_nameThe name for the replication subnet group. Stored as a lowercase string, must contain no more than 255 alphanumeric characters, periods, spaces, underscores, or hyphensstringnullno
<a name="input_repl_subnet_group_subnet_ids"></a> repl_subnet_group_subnet_idsA list of the EC2 subnet IDs for the subnet grouplist(string)[]no
<a name="input_repl_subnet_group_tags"></a> repl_subnet_group_tagsA map of additional tags to apply to the replication subnet groupmap(string){}no
<a name="input_replication_tasks"></a> replication_tasksMap of objects that define the replication tasks to be createdany{}no
<a name="input_s3_endpoints"></a> s3_endpointsMap of objects that define the S3 endpoints to be createdany{}no
<a name="input_tags"></a> tagsA map of tags to use on all resourcesmap(string){}no

Outputs

NameDescription
<a name="output_access_iam_role_arn"></a> access_iam_role_arnAccess IAM role ARN
<a name="output_access_iam_role_name"></a> access_iam_role_nameAccess IAM role name
<a name="output_access_iam_role_unique_id"></a> access_iam_role_unique_idStable and unique string identifying the access IAM role
<a name="output_certificates"></a> certificatesA map of maps containing the certificates created and their full output of attributes and values
<a name="output_dms_access_for_endpoint_iam_role_arn"></a> dms_access_for_endpoint_iam_role_arnAmazon Resource Name (ARN) specifying the role
<a name="output_dms_access_for_endpoint_iam_role_id"></a> dms_access_for_endpoint_iam_role_idName of the IAM role
<a name="output_dms_access_for_endpoint_iam_role_unique_id"></a> dms_access_for_endpoint_iam_role_unique_idStable and unique string identifying the role
<a name="output_dms_cloudwatch_logs_iam_role_arn"></a> dms_cloudwatch_logs_iam_role_arnAmazon Resource Name (ARN) specifying the role
<a name="output_dms_cloudwatch_logs_iam_role_id"></a> dms_cloudwatch_logs_iam_role_idName of the IAM role
<a name="output_dms_cloudwatch_logs_iam_role_unique_id"></a> dms_cloudwatch_logs_iam_role_unique_idStable and unique string identifying the role
<a name="output_dms_vpc_iam_role_arn"></a> dms_vpc_iam_role_arnAmazon Resource Name (ARN) specifying the role
<a name="output_dms_vpc_iam_role_id"></a> dms_vpc_iam_role_idName of the IAM role
<a name="output_dms_vpc_iam_role_unique_id"></a> dms_vpc_iam_role_unique_idStable and unique string identifying the role
<a name="output_endpoints"></a> endpointsA map of maps containing the endpoints created and their full output of attributes and values
<a name="output_event_subscriptions"></a> event_subscriptionsA map of maps containing the event subscriptions created and their full output of attributes and values
<a name="output_replication_instance_arn"></a> replication_instance_arnThe Amazon Resource Name (ARN) of the replication instance
<a name="output_replication_instance_private_ips"></a> replication_instance_private_ipsA list of the private IP addresses of the replication instance
<a name="output_replication_instance_public_ips"></a> replication_instance_public_ipsA list of the public IP addresses of the replication instance
<a name="output_replication_instance_tags_all"></a> replication_instance_tags_allA map of tags assigned to the resource, including those inherited from the provider default_tags configuration block
<a name="output_replication_subnet_group_id"></a> replication_subnet_group_idThe ID of the subnet group
<a name="output_replication_tasks"></a> replication_tasksA map of maps containing the replication tasks created and their full output of attributes and values
<a name="output_s3_endpoints"></a> s3_endpointsA map of maps containing the S3 endpoints created and their full output of attributes and values
<a name="output_serverless_replication_tasks"></a> serverless_replication_tasksA map of maps containing the serverless replication tasks (replication_config) created and their full output of attributes and values
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

License

Apache-2.0 Licensed. See LICENSE.