cdk-dms-replication 0.0.16 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.jsii CHANGED
@@ -3580,7 +3580,7 @@
3580
3580
  },
3581
3581
  "name": "cdk-dms-replication",
3582
3582
  "readme": {
3583
- "markdown": "# cdk-dms-replication\n\n[![npm version](https://badge.fury.io/js/cdk-dms-replication.svg)](https://badge.fury.io/js/cdk-dms-replication)\n[![PyPI version](https://badge.fury.io/py/cdk-dms-replication.svg)](https://badge.fury.io/py/cdk-dms-replication)\n[![build](https://github.com/kckempf/cdk-dms-replication/actions/workflows/build.yml/badge.svg)](https://github.com/kckempf/cdk-dms-replication/actions/workflows/build.yml)\n\nL3 CDK constructs for [Amazon Database Migration Service (DMS)](https://aws.amazon.com/dms/). Provision a complete migration pipeline — replication instance, endpoints, and task — in a few lines of code, with secure defaults and full support for all DMS-supported engines and migration patterns.\n\n## Features\n\n- **All migration patterns** — full load, CDC, and full-load-and-CDC\n- **Classic and Serverless** — `DmsMigrationPipeline` (fixed instance) or `DmsServerlessPipeline` (auto-scales DCUs)\n- **All DMS engines** — MySQL, PostgreSQL, Oracle, SQL Server, SAP ASE, IBM Db2, MongoDB, DocumentDB, S3, DynamoDB, Redshift, Kinesis, Kafka, OpenSearch, Neptune, Redis\n- **Secure defaults** — replication instance placed in private subnets, KMS encryption at rest, security group auto-created\n- **Fluent builders** — `TableMappings` and `TaskSettings` builders produce the JSON DMS expects without hand-crafting strings\n- **Multi-language** — TypeScript, Python, Java, .NET, Go (via JSII)\n- **Escape hatches** — pass existing endpoints or a pre-existing replication instance\n\n## Installation\n\n### TypeScript / JavaScript\n\n```bash\nnpm install cdk-dms-replication\n```\n\n### Python\n\n```bash\npip install cdk-dms-replication\n```\n\n### Java\n\n```xml\n<dependency>\n <groupId>io.github.kckempf</groupId>\n <artifactId>cdk-dms-replication</artifactId>\n <version>VERSION</version>\n</dependency>\n```\n\n### .NET\n\n```bash\ndotnet add package KcKempf.CdkDmsReplication\n```\n\n### Go\n\n```bash\ngo get github.com/kckempf/cdk-dms-replication-go\n```\n\n---\n\n## Quick start\n\n### Classic pipeline (fixed replication instance)\n\n`DmsMigrationPipeline` provisions a replication instance, both endpoints, and a replication task in one construct.\n\n```typescript\nimport * as cdk from 'aws-cdk-lib';\nimport * as ec2 from 'aws-cdk-lib/aws-ec2';\nimport {\n DmsMigrationPipeline,\n EndpointEngine,\n MigrationType,\n TableMappings,\n} from 'cdk-dms-replication';\n\nconst app = new cdk.App();\nconst stack = new cdk.Stack(app, 'MigrationStack');\n\nconst vpc = ec2.Vpc.fromLookup(stack, 'Vpc', { isDefault: false });\n\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n\n sourceEndpoint: {\n engine: EndpointEngine.MYSQL,\n serverName: 'mysql.internal.example.com',\n port: 3306,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('mysql-dms-password'),\n databaseName: 'orders',\n },\n\n targetEndpoint: {\n engine: EndpointEngine.AURORA_POSTGRESQL,\n serverName: cluster.clusterEndpoint.hostname,\n port: 5432,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('aurora-dms-password'),\n databaseName: 'orders',\n },\n\n tableMappings: new TableMappings()\n .includeSchema('public')\n .excludeTable('public', 'audit_log')\n .toJson(),\n});\n```\n\n> **Note:** The `tableMappings` default (when omitted) is to include all tables in all schemas.\n\n### Serverless pipeline (auto-scaling)\n\n`DmsServerlessPipeline` uses DMS Serverless, which automatically scales capacity (measured in DMS Capacity Units — DCUs) between a configurable minimum and maximum. There is no replication instance to size or manage.\n\n```typescript\nimport {\n DmsServerlessPipeline,\n EndpointEngine,\n MigrationType,\n} from 'cdk-dms-replication';\n\nnew DmsServerlessPipeline(stack, 'Pipeline', {\n vpc,\n maxCapacityUnits: 16, // required; valid values: 1,2,4,8,16,32,64,128,192,256,384\n minCapacityUnits: 2, // optional; DMS auto-determines if omitted\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n\n sourceEndpoint: {\n engine: EndpointEngine.MYSQL,\n serverName: 'mysql.internal.example.com',\n port: 3306,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('mysql-dms-password'),\n databaseName: 'orders',\n },\n\n targetEndpoint: {\n engine: EndpointEngine.AURORA_POSTGRESQL,\n serverName: cluster.clusterEndpoint.hostname,\n port: 5432,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('aurora-dms-password'),\n databaseName: 'orders',\n },\n});\n```\n\n> **CDC start/stop position limitation:** `DmsServerlessPipeline` does not support `cdcStartPosition` or `cdcStartTime` at the CloudFormation level. To start replication from a specific LSN or timestamp, call the [`StartReplication` API](https://docs.aws.amazon.com/dms/latest/APIReference/API_StartReplication.html) after the config is created.\n\n---\n\n## Migration patterns\n\n### Full load\n\nMigrates all existing data once, then stops.\n\n```typescript\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.FULL_LOAD,\n sourceEndpoint: { ... },\n targetEndpoint: { ... },\n});\n```\n\n### CDC only\n\nReplicates ongoing changes starting from a specific position or time. The target must already be seeded with data.\n\n```typescript\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.CDC,\n cdcStartPosition: 'mysql-bin-changelog.000024:373', // binlog position\n // — or —\n cdcStartTime: '2024-01-01T00:00:00Z', // ISO-8601 timestamp\n sourceEndpoint: { ... },\n targetEndpoint: { ... },\n});\n```\n\n### Full load then CDC\n\nMigrates existing data, then automatically switches to continuous replication.\n\n```typescript\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n sourceEndpoint: { ... },\n targetEndpoint: { ... },\n});\n```\n\n---\n\n## Endpoint examples\n\n### MySQL / MariaDB / Aurora MySQL\n\n```typescript\nsourceEndpoint: {\n engine: EndpointEngine.MYSQL, // or MARIADB, AURORA_MYSQL\n serverName: 'mysql.example.com',\n port: 3306,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('db-secret'),\n databaseName: 'mydb',\n mySqlSettings: {\n parallelLoadThreads: 4,\n serverTimezone: 'UTC',\n },\n},\n```\n\n### PostgreSQL / Aurora PostgreSQL\n\n```typescript\nsourceEndpoint: {\n engine: EndpointEngine.POSTGRES, // or AURORA_POSTGRESQL\n serverName: 'pg.example.com',\n port: 5432,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('db-secret'),\n databaseName: 'appdb',\n postgreSqlSettings: {\n captureDdls: true,\n slotName: 'dms_replication_slot',\n pluginName: PostgresCdcPlugin.PG_LOGICAL,\n heartbeatEnable: true,\n },\n},\n```\n\n### Oracle\n\n```typescript\nsourceEndpoint: {\n engine: EndpointEngine.ORACLE,\n serverName: 'oracle.example.com',\n port: 1521,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('oracle-secret'),\n databaseName: 'ORCL',\n oracleSettings: {\n addSupplementalLogging: true,\n useLogminerReader: true, // true = LogMiner, false = BinaryReader\n },\n},\n```\n\n### SQL Server\n\n```typescript\nsourceEndpoint: {\n engine: EndpointEngine.SQLSERVER,\n serverName: 'sqlserver.example.com',\n port: 1433,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('sqlserver-secret'),\n databaseName: 'AdventureWorks',\n sqlServerSettings: {\n readBackupOnly: false,\n safeguardPolicy: SqlServerSafeguardPolicy.RELY_ON_SQL_SERVER_REPLICATION_AGENT,\n },\n},\n```\n\n### MongoDB / DocumentDB\n\n```typescript\nsourceEndpoint: {\n engine: EndpointEngine.MONGODB, // or DOCDB\n serverName: 'mongo.example.com',\n port: 27017,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('mongo-secret'),\n mongoDbSettings: {\n authType: MongoAuthType.PASSWORD,\n authMechanism: MongoAuthMechanism.SCRAM_SHA_1,\n nestingLevel: MongoNestingLevel.ONE,\n },\n},\n```\n\n### Amazon S3 (source or target)\n\n```typescript\n// As a target\ntargetEndpoint: {\n engine: EndpointEngine.S3,\n s3Settings: {\n bucketName: 'my-migration-data',\n bucketFolder: 'dms-output',\n serviceAccessRoleArn: s3Role.roleArn,\n dataFormat: S3DataFormat.PARQUET,\n parquetVersion: ParquetVersion.PARQUET_2_0,\n datePartitionEnabled: true,\n datePartitionSequence: DatePartitionSequence.YYYYMMDD,\n encryptionMode: EncryptionMode.SSE_KMS,\n serverSideEncryptionKmsKeyId: myKey.keyArn,\n },\n},\n```\n\n### Amazon Redshift\n\n```typescript\ntargetEndpoint: {\n engine: EndpointEngine.REDSHIFT,\n serverName: 'my-cluster.abc123.us-east-1.redshift.amazonaws.com',\n port: 5439,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('redshift-secret'),\n databaseName: 'dev',\n redshiftSettings: {\n bucketName: 'my-redshift-staging',\n serviceAccessRoleArn: redshiftRole.roleArn,\n encryptionMode: EncryptionMode.SSE_KMS,\n serverSideEncryptionKmsKeyId: myKey.keyArn,\n truncateColumns: true,\n emptyAsNull: true,\n },\n},\n```\n\n### Amazon Kinesis Data Streams\n\n```typescript\ntargetEndpoint: {\n engine: EndpointEngine.KINESIS,\n kinesisSettings: {\n streamArn: stream.streamArn,\n serviceAccessRoleArn: kinesisRole.roleArn,\n messageFormat: MessageFormat.JSON,\n includeTransactionDetails: true,\n includeTableAlterOperations: true,\n },\n},\n```\n\n### Apache Kafka / Amazon MSK\n\n```typescript\ntargetEndpoint: {\n engine: EndpointEngine.KAFKA,\n kafkaSettings: {\n broker: 'b-1.my-cluster.abc123.kafka.us-east-1.amazonaws.com:9092',\n topic: 'dms-changes',\n messageFormat: MessageFormat.JSON,\n securityProtocol: KafkaSecurityProtocol.SASL_SSL,\n saslUsername: 'dms_user',\n saslPassword: cdk.SecretValue.secretsManager('kafka-sasl-password'),\n },\n},\n```\n\n### Amazon OpenSearch Service\n\n```typescript\ntargetEndpoint: {\n engine: EndpointEngine.OPENSEARCH,\n openSearchSettings: {\n endpointUri: 'https://search-my-domain.us-east-1.es.amazonaws.com',\n serviceAccessRoleArn: openSearchRole.roleArn,\n fullLoadErrorPercentage: 10,\n errorRetryDuration: 300,\n },\n},\n```\n\n### Amazon Neptune\n\n```typescript\ntargetEndpoint: {\n engine: EndpointEngine.NEPTUNE,\n neptuneSettings: {\n s3BucketName: 'my-neptune-staging',\n s3BucketFolder: 'dms',\n serviceAccessRoleArn: neptuneRole.roleArn,\n iamAuthEnabled: true,\n },\n},\n```\n\n### Amazon DynamoDB\n\n```typescript\ntargetEndpoint: {\n engine: EndpointEngine.DYNAMODB,\n dynamoDbSettings: {\n serviceAccessRoleArn: dynamoRole.roleArn,\n },\n},\n```\n\n---\n\n## Table mappings\n\nUse the `TableMappings` fluent builder to control which tables are migrated and how they are named on the target.\n\n### Selection rules\n\n```typescript\nnew TableMappings()\n .includeSchema('public') // include all tables in 'public'\n .includeSchema('%') // include all schemas (wildcard)\n .excludeTable('public', 'audit_log') // exclude a specific table\n .excludeSchema('internal') // exclude an entire schema\n .explicitTable('public', 'orders') // migrate only this one table\n .toJson()\n```\n\n### Transformation rules\n\n```typescript\nnew TableMappings()\n .includeSchema('%')\n .renameSchema('legacy', 'v2') // rename schema on target\n .toLowerCaseTable('public', '%') // lowercase all table names\n .toUpperCaseSchema('%') // uppercase all schema names\n .addPrefixToTable('public', '%', 'migrated_')\n .renameTable('public', 'usr', 'users') // rename a specific table\n .renameColumn('public', 'orders', 'cust_id', 'customer_id')\n .removeColumn('public', 'orders', 'internal_notes')\n .toJson()\n```\n\n### Adding columns\n\n```typescript\nnew TableMappings()\n .includeSchema('public')\n .addColumn('public', 'orders', {\n columnName: 'migrated_at',\n columnType: ColumnDataType.DATETIME,\n expression: '$timestamp', // DMS built-in expression\n })\n .addColumn('public', 'orders', {\n columnName: 'migration_version',\n columnType: ColumnDataType.STRING,\n columnLength: 10,\n columnValue: 'v2.0', // constant value\n })\n .toJson()\n```\n\n---\n\n## Task settings\n\nUse `TaskSettings` to tune LOB handling, error behaviour, full-load parallelism, and CDC batching.\n\n```typescript\nimport { TaskSettings, LobMode, ErrorAction, LoggingLevel } from 'cdk-dms-replication';\n\nconst settings = new TaskSettings()\n // LOB handling\n .withLobMode(LobMode.LIMITED_LOB, 64) // truncate LOBs at 64 KB\n\n // Full load tuning\n .withFullLoadSubTasks(16) // 16 parallel table loads\n .withTargetTablePrepMode('DROP_AND_CREATE')\n .withCommitRate(50000) // commit every 50k rows\n\n // CDC batch apply\n .withBatchApply(true, 5, 60) // batch changes, 5–60 second window\n\n // Error handling\n .withDataErrorPolicy(ErrorAction.IGNORE_RECORD, 1000)\n .withRecovery(-1, 5) // unlimited retries, 5s interval\n\n // Logging\n .withLogging('SOURCE_UNLOAD', LoggingLevel.LOGGER_SEVERITY_DEBUG)\n .withLogging('TARGET_LOAD', LoggingLevel.LOGGER_SEVERITY_DEFAULT)\n .toJson();\n\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n taskSettings: settings,\n sourceEndpoint: { ... },\n targetEndpoint: { ... },\n});\n```\n\n---\n\n## Replication instance options\n\n```typescript\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n\n // Instance sizing (default: R6I_LARGE)\n replicationInstanceClass: ReplicationInstanceClass.R6I_4XLARGE,\n allocatedStorage: 500, // GB\n\n // High availability\n multiAz: true,\n\n // Encryption — bring your own KMS key\n encryptionKey: myKmsKey,\n\n // Subnet placement\n vpcSubnets: {\n subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,\n },\n\n sourceEndpoint: { ... },\n targetEndpoint: { ... },\n});\n```\n\n---\n\n## Using lower-level constructs directly\n\nIf you need more control, use the individual constructs and wire them together yourself.\n\n```typescript\nimport {\n DmsReplicationInstance,\n DmsEndpoint,\n DmsReplicationTask,\n EndpointType,\n EndpointEngine,\n MigrationType,\n TableMappings,\n} from 'cdk-dms-replication';\n\n// 1. Replication instance\nconst instance = new DmsReplicationInstance(stack, 'Instance', {\n vpc,\n replicationInstanceClass: ReplicationInstanceClass.R6I_LARGE,\n multiAz: true,\n});\n\n// Allow the source DB security group to accept connections from DMS\ninstance.allowInboundFrom(\n ec2.Peer.securityGroupId(myDbSg.securityGroupId),\n ec2.Port.tcp(3306),\n);\n\n// 2. Endpoints\nconst source = new DmsEndpoint(stack, 'Source', {\n endpointType: EndpointType.SOURCE,\n engine: EndpointEngine.MYSQL,\n serverName: 'mysql.example.com',\n port: 3306,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('db-secret'),\n databaseName: 'mydb',\n});\n\nconst target = new DmsEndpoint(stack, 'Target', {\n endpointType: EndpointType.TARGET,\n engine: EndpointEngine.S3,\n s3Settings: {\n bucketName: 'my-bucket',\n serviceAccessRoleArn: s3Role.roleArn,\n },\n});\n\n// 3. Replication task\nnew DmsReplicationTask(stack, 'Task', {\n replicationInstanceArn: instance.replicationInstanceArn,\n sourceEndpoint: source,\n targetEndpoint: target,\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n tableMappings: new TableMappings().includeSchema('public').toJson(),\n});\n```\n\n---\n\n## Using existing endpoints\n\nBring your own endpoints if they already exist (e.g., created outside CDK or in a different stack):\n\n```typescript\nimport { IDmsEndpoint } from 'cdk-dms-replication';\n\n// Reference an existing endpoint by ARN\nconst existingSource: IDmsEndpoint = {\n endpointArn: 'arn:aws:dms:us-east-1:123456789012:endpoint:ABCDEF',\n};\n\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.CDC,\n existingSourceEndpoint: existingSource,\n targetEndpoint: {\n engine: EndpointEngine.S3,\n s3Settings: { ... },\n },\n});\n```\n\n---\n\n## Secrets Manager integration\n\nFor production workloads, store credentials in AWS Secrets Manager and let DMS retrieve them directly (no plaintext in CloudFormation):\n\n```typescript\nsourceEndpoint: {\n engine: EndpointEngine.MYSQL,\n serverName: 'mysql.example.com',\n port: 3306,\n mySqlSettings: {\n secretsManagerSecretId: 'arn:aws:secretsmanager:us-east-1:123456789012:secret:dms/mysql-abc123',\n secretsManagerAccessRoleArn: dmsSecretsRole.roleArn,\n },\n},\n```\n\nThe secret must contain `username` and `password` keys. See [Using AWS Secrets Manager to access database credentials](https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Security.html#security-iam-secretsmanager) for the required secret format and IAM permissions.\n\n---\n\n## Cross-account migrations\n\nDMS supports migrating data between AWS accounts. The replication instance always lives in one account (the **DMS account**) and connects to source and target databases over the network, regardless of which account owns them.\n\n### Prerequisites\n\nTwo things must be true before the construct can help:\n\n1. **Network connectivity** — The replication instance's VPC must be able to reach both endpoints. Establish this with [VPC peering](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html), [AWS Transit Gateway](https://docs.aws.amazon.com/vpc/latest/tgw/what-is-transit-gateway.html), or [AWS PrivateLink](https://docs.aws.amazon.com/vpc/latest/privatelink/what-is-privatelink.html) before deploying. The construct has no visibility into routing — it will synthesise correctly regardless, but the task will fail at runtime if the endpoints are unreachable.\n\n2. **IAM cross-account trust** — For AWS-managed targets (S3, Kinesis, Redshift, DynamoDB, etc.) owned by a different account, DMS needs an IAM role in the **target account** that trusts the DMS service principal in the **DMS account**.\n\n### CDK stack setup\n\nCDK cannot pass constructs like `ec2.IVpc` across account boundaries. Use `Vpc.fromLookup` in the DMS account stack to reference the VPC by ID:\n\n```typescript\n// DMS account stack (e.g. account 111111111111)\nconst vpc = ec2.Vpc.fromLookup(stack, 'Vpc', {\n vpcId: 'vpc-0abc1234def567890',\n});\n```\n\n### Database endpoints (any engine)\n\nFor source or target databases running in another account, provide the hostname that is reachable from the replication instance's VPC (private IP, private DNS name, or VPC peering DNS). No special construct configuration is needed beyond what you would use for a same-account migration.\n\n```typescript\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n\n // Source DB in account 222222222222, reachable via Transit Gateway\n sourceEndpoint: {\n engine: EndpointEngine.ORACLE,\n serverName: '10.1.2.3', // private IP from peered VPC\n port: 1521,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('oracle-dms-secret'),\n databaseName: 'ORCL',\n },\n\n // Target in the same DMS account — normal config\n targetEndpoint: {\n engine: EndpointEngine.AURORA_POSTGRESQL,\n serverName: cluster.clusterEndpoint.hostname,\n port: 5432,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('aurora-dms-secret'),\n databaseName: 'mydb',\n },\n});\n```\n\n### AWS-managed targets in another account (S3, Kinesis, Redshift, etc.)\n\nWhen the target service lives in a different account, create an IAM role in the **target account** that DMS (running in the DMS account) can assume. Pass its ARN via `serviceAccessRoleArn`.\n\n**Step 1 — Create the cross-account role in the target account (222222222222):**\n\n```typescript\n// In a stack deployed to the TARGET account (222222222222)\nconst crossAccountDmsRole = new iam.Role(targetStack, 'DmsCrossAccountRole', {\n assumedBy: new iam.CompositePrincipal(\n // Allow DMS in the DMS account to assume this role\n new iam.ArnPrincipal(`arn:aws:iam::111111111111:role/dms-vpc-role`),\n new iam.ServicePrincipal('dms.amazonaws.com'),\n ),\n inlinePolicies: {\n S3Access: new iam.PolicyDocument({\n statements: [\n new iam.PolicyStatement({\n actions: ['s3:PutObject', 's3:DeleteObject', 's3:ListBucket'],\n resources: [\n targetBucket.bucketArn,\n `${targetBucket.bucketArn}/*`,\n ],\n }),\n ],\n }),\n },\n});\n```\n\n**Step 2 — Reference the role ARN in the DMS account stack:**\n\n```typescript\n// In the DMS account stack (111111111111)\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.FULL_LOAD,\n sourceEndpoint: {\n engine: EndpointEngine.MYSQL,\n serverName: 'mysql.internal.example.com',\n port: 3306,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('mysql-dms-secret'),\n databaseName: 'orders',\n },\n targetEndpoint: {\n engine: EndpointEngine.S3,\n s3Settings: {\n bucketName: 'target-account-bucket', // bucket in account 222222222222\n serviceAccessRoleArn: 'arn:aws:iam::222222222222:role/DmsCrossAccountRole',\n },\n },\n});\n```\n\nThe same pattern applies to Kinesis, Redshift, DynamoDB, and other AWS-managed targets — create the role in the target account, grant it the permissions that service needs, and pass its ARN to the relevant `serviceAccessRoleArn` field.\n\n### Cross-account Secrets Manager\n\nIf the database credentials are stored in Secrets Manager in the source account (222222222222) but DMS runs in a different account (111111111111):\n\n1. Add a [resource-based policy](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_resource-based-policies.html) to the secret in account 222222222222 that allows the DMS account's role to call `secretsmanager:GetSecretValue`.\n2. Pass the full secret ARN and the cross-account access role ARN to the endpoint settings:\n\n```typescript\nsourceEndpoint: {\n engine: EndpointEngine.MYSQL,\n serverName: 'mysql.internal.example.com',\n port: 3306,\n mySqlSettings: {\n secretsManagerSecretId:\n 'arn:aws:secretsmanager:us-east-1:222222222222:secret:dms/mysql-abc123',\n secretsManagerAccessRoleArn:\n 'arn:aws:iam::111111111111:role/DmsSecretsManagerRole',\n },\n},\n```\n\n### Cross-account KMS encryption\n\nThe construct creates a KMS key in the DMS account for replication instance storage. If you need the replication instance to write to a KMS-encrypted target in another account, bring your own key and add a cross-account statement to its key policy:\n\n```typescript\n// Key in the DMS account (111111111111), with cross-account decrypt permission\nconst encryptionKey = new kms.Key(stack, 'ReplicationKey', {\n enableKeyRotation: true,\n policy: new iam.PolicyDocument({\n statements: [\n // Standard key admin/use permissions ...\n new iam.PolicyStatement({\n principals: [new iam.AccountPrincipal('222222222222')],\n actions: ['kms:Decrypt', 'kms:GenerateDataKey'],\n resources: ['*'],\n }),\n ],\n }),\n});\n\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n encryptionKey,\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n sourceEndpoint: { ... },\n targetEndpoint: { ... },\n});\n```\n\n### Summary of cross-account responsibilities\n\n| Concern | Who sets it up | How to configure |\n|---------|---------------|-----------------|\n| Network connectivity | You (VPC peering / TGW / PrivateLink) | Prerequisite — no construct prop |\n| Database endpoint hostname | You | `serverName` — use private IP or private DNS |\n| Cross-account service role (S3, Kinesis, etc.) | You (role in target account) | `serviceAccessRoleArn` |\n| Cross-account Secrets Manager | You (resource policy on secret) | `secretsManagerSecretId` + `secretsManagerAccessRoleArn` |\n| Cross-account KMS | You (key policy) | `encryptionKey` (bring your own) |\n| Replication instance, subnet group, task | This construct | Fully managed |\n\n---\n\n## Observability\n\nA CloudWatch Logs log group is created by default. Customise the retention period or disable it:\n\n```typescript\nimport * as logs from 'aws-cdk-lib/aws-logs';\n\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n enableCloudWatchLogs: true,\n logRetention: logs.RetentionDays.THREE_MONTHS,\n sourceEndpoint: { ... },\n targetEndpoint: { ... },\n});\n```\n\n---\n\n## API reference\n\nFull API documentation is available in [API.md](https://github.com/kckempf/cdk-dms-replication/blob/main/API.md) and on [Construct Hub](https://constructs.dev/packages/cdk-dms-replication).\n\n---\n\n## Supported source engines\n\n| Engine | `EndpointEngine` value |\n|--------|----------------------|\n| MySQL | `MYSQL` |\n| Amazon Aurora (MySQL) | `AURORA_MYSQL` |\n| PostgreSQL | `POSTGRES` |\n| Amazon Aurora (PostgreSQL) | `AURORA_POSTGRESQL` |\n| Oracle | `ORACLE` |\n| Microsoft SQL Server | `SQLSERVER` |\n| MariaDB | `MARIADB` |\n| SAP ASE (Sybase) | `SAP_ASE` |\n| IBM Db2 LUW | `IBM_DB2` |\n| IBM Db2 for z/OS | `IBM_DB2_ZOS` |\n| MongoDB | `MONGODB` |\n| Amazon DocumentDB | `DOCDB` |\n| Amazon S3 | `S3` |\n\n## Supported target engines\n\nAll source engines above, plus:\n\n| Engine | `EndpointEngine` value |\n|--------|----------------------|\n| Amazon S3 | `S3` |\n| Amazon DynamoDB | `DYNAMODB` |\n| Amazon Redshift | `REDSHIFT` |\n| Amazon Kinesis Data Streams | `KINESIS` |\n| Apache Kafka / Amazon MSK | `KAFKA` |\n| Amazon OpenSearch Service | `OPENSEARCH` |\n| Amazon Neptune | `NEPTUNE` |\n| Amazon ElastiCache for Redis | `REDIS` |\n\n---\n\n## Security considerations\n\n- The replication instance is placed in **private subnets** by default. Set `publiclyAccessible: true` only if required.\n- Storage is encrypted at rest using a **KMS customer-managed key** (auto-created if you don't provide one).\n- **Do not use the `password` prop in production.** The resolved value is written as plaintext into the CloudFormation template and state file. Use Secrets Manager instead: set `secretsManagerSecretId` and `secretsManagerAccessRoleArn` in the engine-specific settings and omit `password` entirely.\n- Grant DMS only the minimum IAM permissions required for each target engine.\n- For CDC with PostgreSQL, the replication user needs the `rds_replication` role (RDS) or `REPLICATION` privilege (self-managed).\n- For CDC with Oracle, supplemental logging must be enabled on the source database.\n- **`dms-vpc-role` and `dms-cloudwatch-logs-role`** are account-level IAM roles created automatically by this construct the first time a pipeline is deployed. Subsequent pipelines in the same account reuse the existing roles. If you manage these roles outside of CDK, import them via your stack before deploying.\n\n---\n\n## Contributing\n\nBug reports and pull requests are welcome. Please open an issue at [github.com/kckempf/cdk-dms-replication/issues](https://github.com/kckempf/cdk-dms-replication/issues) before starting significant work.\n\n---\n\n## Author\n\n[Kevin Kempf](https://github.com/kckempf)\n\n---\n\n## License\n\nApache-2.0 — see [LICENSE](https://github.com/kckempf/cdk-dms-replication/blob/main/LICENSE)\n"
3583
+ "markdown": "# cdk-dms-replication\n\n[![npm version](https://badge.fury.io/js/cdk-dms-replication.svg)](https://badge.fury.io/js/cdk-dms-replication)\n[![PyPI version](https://badge.fury.io/py/cdk-dms-replication.svg)](https://badge.fury.io/py/cdk-dms-replication)\n[![build](https://github.com/kckempf/cdk-dms-replication/actions/workflows/build.yml/badge.svg)](https://github.com/kckempf/cdk-dms-replication/actions/workflows/build.yml)\n\nL3 CDK constructs for [Amazon Database Migration Service (DMS)](https://aws.amazon.com/dms/). Provision a complete migration pipeline — replication instance, endpoints, and task — in a few lines of code, with secure defaults and full support for all DMS-supported engines and migration patterns.\n\n## Features\n\n- **All migration patterns** — full load, CDC, and full-load-and-CDC\n- **Classic and Serverless** — `DmsMigrationPipeline` (fixed instance) or `DmsServerlessPipeline` (auto-scales DCUs)\n- **All DMS engines** — MySQL, PostgreSQL, Oracle, SQL Server, SAP ASE, IBM Db2, MongoDB, DocumentDB, S3, DynamoDB, Redshift, Kinesis, Kafka, OpenSearch, Neptune, Redis\n- **Secure defaults** — replication instance placed in private subnets, KMS encryption at rest, security group auto-created\n- **Fluent builders** — `TableMappings` and `TaskSettings` builders produce the JSON DMS expects without hand-crafting strings\n- **Multi-language** — TypeScript, Python, Java, .NET, Go (via JSII)\n- **Escape hatches** — pass existing endpoints or a pre-existing replication instance\n\n## Installation\n\n### TypeScript / JavaScript\n\n```bash\nnpm install cdk-dms-replication\n```\n\n### Python\n\n```bash\npip install cdk-dms-replication\n```\n\n### Java\n\n```xml\n<dependency>\n <groupId>io.github.kckempf</groupId>\n <artifactId>cdk-dms-replication</artifactId>\n <version>VERSION</version>\n</dependency>\n```\n\n### .NET\n\n```bash\ndotnet add package KcKempf.CdkDmsReplication\n```\n\n### Go\n\n```bash\ngo get github.com/kckempf/cdk-dms-replication-go\n```\n\n---\n\n## Quick start\n\n### Classic pipeline (fixed replication instance)\n\n`DmsMigrationPipeline` provisions a replication instance, both endpoints, and a replication task in one construct.\n\n```typescript\nimport * as cdk from 'aws-cdk-lib';\nimport * as ec2 from 'aws-cdk-lib/aws-ec2';\nimport {\n DmsMigrationPipeline,\n EndpointEngine,\n MigrationType,\n TableMappings,\n} from 'cdk-dms-replication';\n\nconst app = new cdk.App();\nconst stack = new cdk.Stack(app, 'MigrationStack');\n\nconst vpc = ec2.Vpc.fromLookup(stack, 'Vpc', { isDefault: false });\n\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n\n sourceEndpoint: {\n engine: EndpointEngine.MYSQL,\n serverName: 'mysql.internal.example.com',\n port: 3306,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('mysql-dms-password'),\n databaseName: 'orders',\n },\n\n targetEndpoint: {\n engine: EndpointEngine.AURORA_POSTGRESQL,\n serverName: cluster.clusterEndpoint.hostname,\n port: 5432,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('aurora-dms-password'),\n databaseName: 'orders',\n },\n\n tableMappings: new TableMappings()\n .includeSchema('public')\n .excludeTable('public', 'audit_log')\n .toJson(),\n});\n```\n\n> **Note:** The `tableMappings` default (when omitted) is to include all tables in all schemas.\n\n### Serverless pipeline (auto-scaling)\n\n`DmsServerlessPipeline` uses DMS Serverless, which automatically scales capacity (measured in DMS Capacity Units — DCUs) between a configurable minimum and maximum. There is no replication instance to size or manage.\n\n```typescript\nimport {\n DmsServerlessPipeline,\n EndpointEngine,\n MigrationType,\n} from 'cdk-dms-replication';\n\nnew DmsServerlessPipeline(stack, 'Pipeline', {\n vpc,\n maxCapacityUnits: 16, // required; valid values: 1,2,4,8,16,32,64,128,192,256,384\n minCapacityUnits: 2, // optional; DMS auto-determines if omitted\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n\n sourceEndpoint: {\n engine: EndpointEngine.MYSQL,\n serverName: 'mysql.internal.example.com',\n port: 3306,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('mysql-dms-password'),\n databaseName: 'orders',\n },\n\n targetEndpoint: {\n engine: EndpointEngine.AURORA_POSTGRESQL,\n serverName: cluster.clusterEndpoint.hostname,\n port: 5432,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('aurora-dms-password'),\n databaseName: 'orders',\n },\n});\n```\n\n> **CDC start/stop position limitation:** `DmsServerlessPipeline` does not support `cdcStartPosition` or `cdcStartTime` at the CloudFormation level. To start replication from a specific LSN or timestamp, call the [`StartReplication` API](https://docs.aws.amazon.com/dms/latest/APIReference/API_StartReplication.html) after the config is created.\n\n---\n\n## Migration patterns\n\n### Full load\n\nMigrates all existing data once, then stops.\n\n```typescript\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.FULL_LOAD,\n sourceEndpoint: { ... },\n targetEndpoint: { ... },\n});\n```\n\n### CDC only\n\nReplicates ongoing changes starting from a specific position or time. The target must already be seeded with data.\n\n```typescript\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.CDC,\n cdcStartPosition: 'mysql-bin-changelog.000024:373', // binlog position\n // — or —\n cdcStartTime: '2024-01-01T00:00:00Z', // ISO-8601 timestamp\n sourceEndpoint: { ... },\n targetEndpoint: { ... },\n});\n```\n\n### Full load then CDC\n\nMigrates existing data, then automatically switches to continuous replication.\n\n```typescript\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n sourceEndpoint: { ... },\n targetEndpoint: { ... },\n});\n```\n\n---\n\n## Endpoint examples\n\n### MySQL / MariaDB / Aurora MySQL\n\n```typescript\nsourceEndpoint: {\n engine: EndpointEngine.MYSQL, // or MARIADB, AURORA_MYSQL\n serverName: 'mysql.example.com',\n port: 3306,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('db-secret'),\n databaseName: 'mydb',\n mySqlSettings: {\n parallelLoadThreads: 4,\n serverTimezone: 'UTC',\n },\n},\n```\n\n### PostgreSQL / Aurora PostgreSQL\n\n```typescript\nsourceEndpoint: {\n engine: EndpointEngine.POSTGRES, // or AURORA_POSTGRESQL\n serverName: 'pg.example.com',\n port: 5432,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('db-secret'),\n databaseName: 'appdb',\n postgreSqlSettings: {\n captureDdls: true,\n slotName: 'dms_replication_slot',\n pluginName: PostgresCdcPlugin.PG_LOGICAL,\n heartbeatEnable: true,\n },\n},\n```\n\n### Oracle\n\n```typescript\nsourceEndpoint: {\n engine: EndpointEngine.ORACLE,\n serverName: 'oracle.example.com',\n port: 1521,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('oracle-secret'),\n databaseName: 'ORCL',\n oracleSettings: {\n addSupplementalLogging: true,\n useLogminerReader: true, // true = LogMiner, false = BinaryReader\n },\n},\n```\n\n### SQL Server\n\n```typescript\nsourceEndpoint: {\n engine: EndpointEngine.SQLSERVER,\n serverName: 'sqlserver.example.com',\n port: 1433,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('sqlserver-secret'),\n databaseName: 'AdventureWorks',\n sqlServerSettings: {\n readBackupOnly: false,\n safeguardPolicy: SqlServerSafeguardPolicy.RELY_ON_SQL_SERVER_REPLICATION_AGENT,\n },\n},\n```\n\n### MongoDB / DocumentDB\n\n```typescript\nsourceEndpoint: {\n engine: EndpointEngine.MONGODB, // or DOCDB\n serverName: 'mongo.example.com',\n port: 27017,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('mongo-secret'),\n mongoDbSettings: {\n authType: MongoAuthType.PASSWORD,\n authMechanism: MongoAuthMechanism.SCRAM_SHA_1,\n nestingLevel: MongoNestingLevel.ONE,\n },\n},\n```\n\n### Amazon S3 (source or target)\n\n```typescript\n// As a target\ntargetEndpoint: {\n engine: EndpointEngine.S3,\n s3Settings: {\n bucketName: 'my-migration-data',\n bucketFolder: 'dms-output',\n serviceAccessRoleArn: s3Role.roleArn,\n dataFormat: S3DataFormat.PARQUET,\n parquetVersion: ParquetVersion.PARQUET_2_0,\n datePartitionEnabled: true,\n datePartitionSequence: DatePartitionSequence.YYYYMMDD,\n encryptionMode: EncryptionMode.SSE_KMS,\n serverSideEncryptionKmsKeyId: myKey.keyArn,\n },\n},\n```\n\n### Amazon Redshift\n\n```typescript\ntargetEndpoint: {\n engine: EndpointEngine.REDSHIFT,\n serverName: 'my-cluster.abc123.us-east-1.redshift.amazonaws.com',\n port: 5439,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('redshift-secret'),\n databaseName: 'dev',\n redshiftSettings: {\n bucketName: 'my-redshift-staging',\n serviceAccessRoleArn: redshiftRole.roleArn,\n encryptionMode: EncryptionMode.SSE_KMS,\n serverSideEncryptionKmsKeyId: myKey.keyArn,\n truncateColumns: true,\n emptyAsNull: true,\n },\n},\n```\n\n### Amazon Kinesis Data Streams\n\n```typescript\ntargetEndpoint: {\n engine: EndpointEngine.KINESIS,\n kinesisSettings: {\n streamArn: stream.streamArn,\n serviceAccessRoleArn: kinesisRole.roleArn,\n messageFormat: MessageFormat.JSON,\n includeTransactionDetails: true,\n includeTableAlterOperations: true,\n },\n},\n```\n\n### Apache Kafka / Amazon MSK\n\n```typescript\ntargetEndpoint: {\n engine: EndpointEngine.KAFKA,\n kafkaSettings: {\n broker: 'b-1.my-cluster.abc123.kafka.us-east-1.amazonaws.com:9092',\n topic: 'dms-changes',\n messageFormat: MessageFormat.JSON,\n securityProtocol: KafkaSecurityProtocol.SASL_SSL,\n saslUsername: 'dms_user',\n saslPassword: cdk.SecretValue.secretsManager('kafka-sasl-password'),\n },\n},\n```\n\n### Amazon OpenSearch Service\n\n```typescript\ntargetEndpoint: {\n engine: EndpointEngine.OPENSEARCH,\n openSearchSettings: {\n endpointUri: 'https://search-my-domain.us-east-1.es.amazonaws.com',\n serviceAccessRoleArn: openSearchRole.roleArn,\n fullLoadErrorPercentage: 10,\n errorRetryDuration: 300,\n },\n},\n```\n\n### Amazon Neptune\n\n```typescript\ntargetEndpoint: {\n engine: EndpointEngine.NEPTUNE,\n neptuneSettings: {\n s3BucketName: 'my-neptune-staging',\n s3BucketFolder: 'dms',\n serviceAccessRoleArn: neptuneRole.roleArn,\n iamAuthEnabled: true,\n },\n},\n```\n\n### Amazon DynamoDB\n\n```typescript\ntargetEndpoint: {\n engine: EndpointEngine.DYNAMODB,\n dynamoDbSettings: {\n serviceAccessRoleArn: dynamoRole.roleArn,\n },\n},\n```\n\n---\n\n## Table mappings\n\nUse the `TableMappings` fluent builder to control which tables are migrated and how they are named on the target.\n\n### Selection rules\n\n```typescript\nnew TableMappings()\n .includeSchema('public') // include all tables in 'public'\n .includeSchema('%') // include all schemas (wildcard)\n .excludeTable('public', 'audit_log') // exclude a specific table\n .excludeSchema('internal') // exclude an entire schema\n .explicitTable('public', 'orders') // migrate only this one table\n .toJson()\n```\n\n### Transformation rules\n\n```typescript\nnew TableMappings()\n .includeSchema('%')\n .renameSchema('legacy', 'v2') // rename schema on target\n .toLowerCaseTable('public', '%') // lowercase all table names\n .toUpperCaseSchema('%') // uppercase all schema names\n .addPrefixToTable('public', '%', 'migrated_')\n .renameTable('public', 'usr', 'users') // rename a specific table\n .renameColumn('public', 'orders', 'cust_id', 'customer_id')\n .removeColumn('public', 'orders', 'internal_notes')\n .toJson()\n```\n\n### Adding columns\n\n```typescript\nnew TableMappings()\n .includeSchema('public')\n .addColumn('public', 'orders', {\n columnName: 'migrated_at',\n columnType: ColumnDataType.DATETIME,\n expression: '$timestamp', // DMS built-in expression\n })\n .addColumn('public', 'orders', {\n columnName: 'migration_version',\n columnType: ColumnDataType.STRING,\n columnLength: 10,\n columnValue: 'v2.0', // constant value\n })\n .toJson()\n```\n\n---\n\n## Task settings\n\nUse `TaskSettings` to tune LOB handling, error behaviour, full-load parallelism, and CDC batching.\n\n```typescript\nimport { TaskSettings, LobMode, ErrorAction, LoggingLevel } from 'cdk-dms-replication';\n\nconst settings = new TaskSettings()\n // LOB handling\n .withLobMode(LobMode.LIMITED_LOB, 64) // truncate LOBs at 64 KB\n\n // Full load tuning\n .withFullLoadSubTasks(16) // 16 parallel table loads\n .withTargetTablePrepMode('DROP_AND_CREATE')\n .withCommitRate(50000) // commit every 50k rows\n\n // CDC batch apply\n .withBatchApply(true, 5, 60) // batch changes, 5–60 second window\n\n // Error handling\n .withDataErrorPolicy(ErrorAction.IGNORE_RECORD, 1000)\n .withRecovery(-1, 5) // unlimited retries, 5s interval\n\n // Logging\n .withLogging('SOURCE_UNLOAD', LoggingLevel.LOGGER_SEVERITY_DEBUG)\n .withLogging('TARGET_LOAD', LoggingLevel.LOGGER_SEVERITY_DEFAULT)\n .toJson();\n\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n taskSettings: settings,\n sourceEndpoint: { ... },\n targetEndpoint: { ... },\n});\n```\n\n---\n\n## Replication instance options\n\n```typescript\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n\n // Instance sizing (default: R6I_LARGE)\n replicationInstanceClass: ReplicationInstanceClass.R6I_4XLARGE,\n allocatedStorage: 500, // GB\n\n // High availability\n multiAz: true,\n\n // Encryption — bring your own KMS key\n encryptionKey: myKmsKey,\n\n // Subnet placement\n vpcSubnets: {\n subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,\n },\n\n sourceEndpoint: { ... },\n targetEndpoint: { ... },\n});\n```\n\n---\n\n## Using lower-level constructs directly\n\nIf you need more control, use the individual constructs and wire them together yourself.\n\n```typescript\nimport {\n DmsReplicationInstance,\n DmsEndpoint,\n DmsReplicationTask,\n EndpointType,\n EndpointEngine,\n MigrationType,\n TableMappings,\n} from 'cdk-dms-replication';\n\n// 1. Replication instance\nconst instance = new DmsReplicationInstance(stack, 'Instance', {\n vpc,\n replicationInstanceClass: ReplicationInstanceClass.R6I_LARGE,\n multiAz: true,\n});\n\n// Allow the source DB security group to accept connections from DMS\ninstance.allowInboundFrom(\n ec2.Peer.securityGroupId(myDbSg.securityGroupId),\n ec2.Port.tcp(3306),\n);\n\n// 2. Endpoints\nconst source = new DmsEndpoint(stack, 'Source', {\n endpointType: EndpointType.SOURCE,\n engine: EndpointEngine.MYSQL,\n serverName: 'mysql.example.com',\n port: 3306,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('db-secret'),\n databaseName: 'mydb',\n});\n\nconst target = new DmsEndpoint(stack, 'Target', {\n endpointType: EndpointType.TARGET,\n engine: EndpointEngine.S3,\n s3Settings: {\n bucketName: 'my-bucket',\n serviceAccessRoleArn: s3Role.roleArn,\n },\n});\n\n// 3. Replication task\nnew DmsReplicationTask(stack, 'Task', {\n replicationInstanceArn: instance.replicationInstanceArn,\n sourceEndpoint: source,\n targetEndpoint: target,\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n tableMappings: new TableMappings().includeSchema('public').toJson(),\n});\n```\n\n---\n\n## Using existing endpoints\n\nBring your own endpoints if they already exist (e.g., created outside CDK or in a different stack):\n\n```typescript\nimport { IDmsEndpoint } from 'cdk-dms-replication';\n\n// Reference an existing endpoint by ARN\nconst existingSource: IDmsEndpoint = {\n endpointArn: 'arn:aws:dms:us-east-1:123456789012:endpoint:ABCDEF',\n};\n\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.CDC,\n existingSourceEndpoint: existingSource,\n targetEndpoint: {\n engine: EndpointEngine.S3,\n s3Settings: { ... },\n },\n});\n```\n\n---\n\n## Secrets Manager integration\n\nFor production workloads, store credentials in AWS Secrets Manager and let DMS retrieve them directly (no plaintext in CloudFormation):\n\n```typescript\nsourceEndpoint: {\n engine: EndpointEngine.MYSQL,\n serverName: 'mysql.example.com',\n port: 3306,\n mySqlSettings: {\n secretsManagerSecretId: 'arn:aws:secretsmanager:us-east-1:123456789012:secret:dms/mysql-abc123',\n secretsManagerAccessRoleArn: dmsSecretsRole.roleArn,\n },\n},\n```\n\nThe secret must contain `username` and `password` keys. See [Using AWS Secrets Manager to access database credentials](https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Security.html#security-iam-secretsmanager) for the required secret format and IAM permissions.\n\n---\n\n## Cross-account migrations\n\nDMS supports migrating data between AWS accounts. The replication instance always lives in one account (the **DMS account**) and connects to source and target databases over the network, regardless of which account owns them.\n\n### Prerequisites\n\nTwo things must be true before the construct can help:\n\n1. **Network connectivity** — The replication instance's VPC must be able to reach both endpoints. Establish this with [VPC peering](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html), [AWS Transit Gateway](https://docs.aws.amazon.com/vpc/latest/tgw/what-is-transit-gateway.html), or [AWS PrivateLink](https://docs.aws.amazon.com/vpc/latest/privatelink/what-is-privatelink.html) before deploying. The construct has no visibility into routing — it will synthesise correctly regardless, but the task will fail at runtime if the endpoints are unreachable.\n\n2. **IAM cross-account trust** — For AWS-managed targets (S3, Kinesis, Redshift, DynamoDB, etc.) owned by a different account, DMS needs an IAM role in the **target account** that trusts the DMS service principal in the **DMS account**.\n\n### CDK stack setup\n\nCDK cannot pass constructs like `ec2.IVpc` across account boundaries. Use `Vpc.fromLookup` in the DMS account stack to reference the VPC by ID:\n\n```typescript\n// DMS account stack (e.g. account 111111111111)\nconst vpc = ec2.Vpc.fromLookup(stack, 'Vpc', {\n vpcId: 'vpc-0abc1234def567890',\n});\n```\n\n### Database endpoints (any engine)\n\nFor source or target databases running in another account, provide the hostname that is reachable from the replication instance's VPC (private IP, private DNS name, or VPC peering DNS). No special construct configuration is needed beyond what you would use for a same-account migration.\n\n```typescript\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n\n // Source DB in account 222222222222, reachable via Transit Gateway\n sourceEndpoint: {\n engine: EndpointEngine.ORACLE,\n serverName: '10.1.2.3', // private IP from peered VPC\n port: 1521,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('oracle-dms-secret'),\n databaseName: 'ORCL',\n },\n\n // Target in the same DMS account — normal config\n targetEndpoint: {\n engine: EndpointEngine.AURORA_POSTGRESQL,\n serverName: cluster.clusterEndpoint.hostname,\n port: 5432,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('aurora-dms-secret'),\n databaseName: 'mydb',\n },\n});\n```\n\n### AWS-managed targets in another account (S3, Kinesis, Redshift, etc.)\n\nWhen the target service lives in a different account, create an IAM role in the **target account** that DMS (running in the DMS account) can assume. Pass its ARN via `serviceAccessRoleArn`.\n\n**Step 1 — Create the cross-account role in the target account (222222222222):**\n\n```typescript\n// In a stack deployed to the TARGET account (222222222222)\nconst crossAccountDmsRole = new iam.Role(targetStack, 'DmsCrossAccountRole', {\n assumedBy: new iam.CompositePrincipal(\n // Allow DMS in the DMS account to assume this role\n new iam.ArnPrincipal(`arn:aws:iam::111111111111:role/dms-vpc-role`),\n new iam.ServicePrincipal('dms.amazonaws.com'),\n ),\n inlinePolicies: {\n S3Access: new iam.PolicyDocument({\n statements: [\n new iam.PolicyStatement({\n actions: ['s3:PutObject', 's3:DeleteObject', 's3:ListBucket'],\n resources: [\n targetBucket.bucketArn,\n `${targetBucket.bucketArn}/*`,\n ],\n }),\n ],\n }),\n },\n});\n```\n\n**Step 2 — Reference the role ARN in the DMS account stack:**\n\n```typescript\n// In the DMS account stack (111111111111)\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.FULL_LOAD,\n sourceEndpoint: {\n engine: EndpointEngine.MYSQL,\n serverName: 'mysql.internal.example.com',\n port: 3306,\n username: 'dms_user',\n password: cdk.SecretValue.secretsManager('mysql-dms-secret'),\n databaseName: 'orders',\n },\n targetEndpoint: {\n engine: EndpointEngine.S3,\n s3Settings: {\n bucketName: 'target-account-bucket', // bucket in account 222222222222\n serviceAccessRoleArn: 'arn:aws:iam::222222222222:role/DmsCrossAccountRole',\n },\n },\n});\n```\n\nThe same pattern applies to Kinesis, Redshift, DynamoDB, and other AWS-managed targets — create the role in the target account, grant it the permissions that service needs, and pass its ARN to the relevant `serviceAccessRoleArn` field.\n\n### Cross-account Secrets Manager\n\nIf the database credentials are stored in Secrets Manager in the source account (222222222222) but DMS runs in a different account (111111111111):\n\n1. Add a [resource-based policy](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_resource-based-policies.html) to the secret in account 222222222222 that allows the DMS account's role to call `secretsmanager:GetSecretValue`.\n2. Pass the full secret ARN and the cross-account access role ARN to the endpoint settings:\n\n```typescript\nsourceEndpoint: {\n engine: EndpointEngine.MYSQL,\n serverName: 'mysql.internal.example.com',\n port: 3306,\n mySqlSettings: {\n secretsManagerSecretId:\n 'arn:aws:secretsmanager:us-east-1:222222222222:secret:dms/mysql-abc123',\n secretsManagerAccessRoleArn:\n 'arn:aws:iam::111111111111:role/DmsSecretsManagerRole',\n },\n},\n```\n\n### Cross-account KMS encryption\n\nThe construct creates a KMS key in the DMS account for replication instance storage. If you need the replication instance to write to a KMS-encrypted target in another account, bring your own key and add a cross-account statement to its key policy:\n\n```typescript\n// Key in the DMS account (111111111111), with cross-account decrypt permission\nconst encryptionKey = new kms.Key(stack, 'ReplicationKey', {\n enableKeyRotation: true,\n policy: new iam.PolicyDocument({\n statements: [\n // Standard key admin/use permissions ...\n new iam.PolicyStatement({\n principals: [new iam.AccountPrincipal('222222222222')],\n actions: ['kms:Decrypt', 'kms:GenerateDataKey'],\n resources: ['*'],\n }),\n ],\n }),\n});\n\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n encryptionKey,\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n sourceEndpoint: { ... },\n targetEndpoint: { ... },\n});\n```\n\n### Summary of cross-account responsibilities\n\n| Concern | Who sets it up | How to configure |\n|---------|---------------|-----------------|\n| Network connectivity | You (VPC peering / TGW / PrivateLink) | Prerequisite — no construct prop |\n| Database endpoint hostname | You | `serverName` — use private IP or private DNS |\n| Cross-account service role (S3, Kinesis, etc.) | You (role in target account) | `serviceAccessRoleArn` |\n| Cross-account Secrets Manager | You (resource policy on secret) | `secretsManagerSecretId` + `secretsManagerAccessRoleArn` |\n| Cross-account KMS | You (key policy) | `encryptionKey` (bring your own) |\n| Replication instance, subnet group, task | This construct | Fully managed |\n\n---\n\n## Observability\n\nA CloudWatch Logs log group is created by default. Customise the retention period or disable it:\n\n```typescript\nimport * as logs from 'aws-cdk-lib/aws-logs';\n\nnew DmsMigrationPipeline(stack, 'Pipeline', {\n vpc,\n migrationType: MigrationType.FULL_LOAD_AND_CDC,\n enableCloudWatchLogs: true,\n logRetention: logs.RetentionDays.THREE_MONTHS,\n sourceEndpoint: { ... },\n targetEndpoint: { ... },\n});\n```\n\n---\n\n## API reference\n\nFull API documentation is available in [API.md](https://github.com/kckempf/cdk-dms-replication/blob/main/API.md) and on [Construct Hub](https://constructs.dev/packages/cdk-dms-replication).\n\n---\n\n## Supported source engines\n\n| Engine | `EndpointEngine` value |\n|--------|----------------------|\n| MySQL | `MYSQL` |\n| Amazon Aurora (MySQL) | `AURORA_MYSQL` |\n| PostgreSQL | `POSTGRES` |\n| Amazon Aurora (PostgreSQL) | `AURORA_POSTGRESQL` |\n| Oracle | `ORACLE` |\n| Microsoft SQL Server | `SQLSERVER` |\n| MariaDB | `MARIADB` |\n| SAP ASE (Sybase) | `SAP_ASE` |\n| IBM Db2 LUW | `IBM_DB2` |\n| IBM Db2 for z/OS | `IBM_DB2_ZOS` |\n| MongoDB | `MONGODB` |\n| Amazon DocumentDB | `DOCDB` |\n| Amazon S3 | `S3` |\n\n## Supported target engines\n\nAll source engines above, plus:\n\n| Engine | `EndpointEngine` value |\n|--------|----------------------|\n| Amazon S3 | `S3` |\n| Amazon DynamoDB | `DYNAMODB` |\n| Amazon Redshift | `REDSHIFT` |\n| Amazon Kinesis Data Streams | `KINESIS` |\n| Apache Kafka / Amazon MSK | `KAFKA` |\n| Amazon OpenSearch Service | `OPENSEARCH` |\n| Amazon Neptune | `NEPTUNE` |\n| Amazon ElastiCache for Redis | `REDIS` |\n\n---\n\n## Security considerations\n\n- The replication instance is placed in **private subnets** by default. Set `publiclyAccessible: true` only if required.\n- Storage is encrypted at rest using a **KMS customer-managed key** (auto-created if you don't provide one).\n- **Do not use the `password` prop in production.** The resolved value is written as plaintext into the CloudFormation template and state file. Use Secrets Manager instead: set `secretsManagerSecretId` and `secretsManagerAccessRoleArn` in the engine-specific settings and omit `password` entirely.\n- Grant DMS only the minimum IAM permissions required for each target engine.\n- For CDC with PostgreSQL, the replication user needs the `rds_replication` role (RDS) or `REPLICATION` privilege (self-managed).\n- For CDC with Oracle, supplemental logging must be enabled on the source database.\n- **`dms-vpc-role` and `dms-cloudwatch-logs-role`** are account-level IAM roles required by DMS. When `createDmsServiceRoles` is `true` (the default), they are created idempotently via a custom resource — if they already exist in the account (created by another stack or manually), the existing roles are silently reused and their trust policies corrected if necessary. The roles are created with `RemovalPolicy.RETAIN` and are **not** lifecycle-managed by the deploying stack; they will not be deleted when the stack is destroyed. If you require the roles to be lifecycle-managed, create them in a dedicated stack and set `createDmsServiceRoles: false`.\n\n---\n\n## Contributing\n\nBug reports and pull requests are welcome. Please open an issue at [github.com/kckempf/cdk-dms-replication/issues](https://github.com/kckempf/cdk-dms-replication/issues) before starting significant work.\n\n---\n\n## Author\n\n[Kevin Kempf](https://github.com/kckempf)\n\n---\n\n## License\n\nApache-2.0 — see [LICENSE](https://github.com/kckempf/cdk-dms-replication/blob/main/LICENSE)\n"
3584
3584
  },
3585
3585
  "repository": {
3586
3586
  "type": "git",
@@ -4719,7 +4719,7 @@
4719
4719
  },
4720
4720
  "locationInModule": {
4721
4721
  "filename": "src/migration-pipeline.ts",
4722
- "line": 321
4722
+ "line": 324
4723
4723
  },
4724
4724
  "parameters": [
4725
4725
  {
@@ -4745,7 +4745,7 @@
4745
4745
  "kind": "class",
4746
4746
  "locationInModule": {
4747
4747
  "filename": "src/migration-pipeline.ts",
4748
- "line": 289
4748
+ "line": 292
4749
4749
  },
4750
4750
  "name": "DmsMigrationPipeline",
4751
4751
  "properties": [
@@ -4757,7 +4757,7 @@
4757
4757
  "immutable": true,
4758
4758
  "locationInModule": {
4759
4759
  "filename": "src/migration-pipeline.ts",
4760
- "line": 295
4760
+ "line": 298
4761
4761
  },
4762
4762
  "name": "replicationInstance",
4763
4763
  "type": {
@@ -4772,7 +4772,7 @@
4772
4772
  "immutable": true,
4773
4773
  "locationInModule": {
4774
4774
  "filename": "src/migration-pipeline.ts",
4775
- "line": 304
4775
+ "line": 307
4776
4776
  },
4777
4777
  "name": "replicationTask",
4778
4778
  "type": {
@@ -4787,7 +4787,7 @@
4787
4787
  "immutable": true,
4788
4788
  "locationInModule": {
4789
4789
  "filename": "src/migration-pipeline.ts",
4790
- "line": 298
4790
+ "line": 301
4791
4791
  },
4792
4792
  "name": "source",
4793
4793
  "type": {
@@ -4802,7 +4802,7 @@
4802
4802
  "immutable": true,
4803
4803
  "locationInModule": {
4804
4804
  "filename": "src/migration-pipeline.ts",
4805
- "line": 301
4805
+ "line": 304
4806
4806
  },
4807
4807
  "name": "target",
4808
4808
  "type": {
@@ -4813,34 +4813,34 @@
4813
4813
  "docs": {
4814
4814
  "remarks": "`undefined` when `createDmsServiceRoles` is `false`.",
4815
4815
  "stability": "stable",
4816
- "summary": "IAM role that allows DMS to write to CloudWatch Logs."
4816
+ "summary": "Construct wrapping the custom resources that created the `dms-cloudwatch-logs-role`."
4817
4817
  },
4818
4818
  "immutable": true,
4819
4819
  "locationInModule": {
4820
4820
  "filename": "src/migration-pipeline.ts",
4821
- "line": 313
4821
+ "line": 316
4822
4822
  },
4823
4823
  "name": "dmsCloudWatchRole",
4824
4824
  "optional": true,
4825
4825
  "type": {
4826
- "fqn": "aws-cdk-lib.aws_iam.Role"
4826
+ "fqn": "constructs.Construct"
4827
4827
  }
4828
4828
  },
4829
4829
  {
4830
4830
  "docs": {
4831
4831
  "remarks": "`undefined` when `createDmsServiceRoles` is `false`.",
4832
4832
  "stability": "stable",
4833
- "summary": "IAM role that allows DMS to manage VPC resources (dms-vpc-role)."
4833
+ "summary": "Construct wrapping the custom resources that created the `dms-vpc-role`."
4834
4834
  },
4835
4835
  "immutable": true,
4836
4836
  "locationInModule": {
4837
4837
  "filename": "src/migration-pipeline.ts",
4838
- "line": 319
4838
+ "line": 322
4839
4839
  },
4840
4840
  "name": "dmsVpcRole",
4841
4841
  "optional": true,
4842
4842
  "type": {
4843
- "fqn": "aws-cdk-lib.aws_iam.Role"
4843
+ "fqn": "constructs.Construct"
4844
4844
  }
4845
4845
  },
4846
4846
  {
@@ -4851,7 +4851,7 @@
4851
4851
  "immutable": true,
4852
4852
  "locationInModule": {
4853
4853
  "filename": "src/migration-pipeline.ts",
4854
- "line": 307
4854
+ "line": 310
4855
4855
  },
4856
4856
  "name": "logGroup",
4857
4857
  "optional": true,
@@ -4873,7 +4873,7 @@
4873
4873
  "kind": "interface",
4874
4874
  "locationInModule": {
4875
4875
  "filename": "src/migration-pipeline.ts",
4876
- "line": 87
4876
+ "line": 86
4877
4877
  },
4878
4878
  "name": "DmsMigrationPipelineProps",
4879
4879
  "properties": [
@@ -4886,7 +4886,7 @@
4886
4886
  "immutable": true,
4887
4887
  "locationInModule": {
4888
4888
  "filename": "src/migration-pipeline.ts",
4889
- "line": 167
4889
+ "line": 166
4890
4890
  },
4891
4891
  "name": "migrationType",
4892
4892
  "type": {
@@ -4903,7 +4903,7 @@
4903
4903
  "immutable": true,
4904
4904
  "locationInModule": {
4905
4905
  "filename": "src/migration-pipeline.ts",
4906
- "line": 96
4906
+ "line": 95
4907
4907
  },
4908
4908
  "name": "vpc",
4909
4909
  "type": {
@@ -4920,7 +4920,7 @@
4920
4920
  "immutable": true,
4921
4921
  "locationInModule": {
4922
4922
  "filename": "src/migration-pipeline.ts",
4923
- "line": 114
4923
+ "line": 113
4924
4924
  },
4925
4925
  "name": "allocatedStorage",
4926
4926
  "optional": true,
@@ -4938,7 +4938,7 @@
4938
4938
  "immutable": true,
4939
4939
  "locationInModule": {
4940
4940
  "filename": "src/migration-pipeline.ts",
4941
- "line": 193
4941
+ "line": 192
4942
4942
  },
4943
4943
  "name": "cdcStartPosition",
4944
4944
  "optional": true,
@@ -4956,7 +4956,7 @@
4956
4956
  "immutable": true,
4957
4957
  "locationInModule": {
4958
4958
  "filename": "src/migration-pipeline.ts",
4959
- "line": 187
4959
+ "line": 186
4960
4960
  },
4961
4961
  "name": "cdcStartTime",
4962
4962
  "optional": true,
@@ -4974,7 +4974,7 @@
4974
4974
  "immutable": true,
4975
4975
  "locationInModule": {
4976
4976
  "filename": "src/migration-pipeline.ts",
4977
- "line": 199
4977
+ "line": 198
4978
4978
  },
4979
4979
  "name": "cdcStopPosition",
4980
4980
  "optional": true,
@@ -4986,14 +4986,14 @@
4986
4986
  "abstract": true,
4987
4987
  "docs": {
4988
4988
  "default": "true",
4989
- "remarks": "Set this to `false` if the roles already exist in the AWS account for\nexample, because another CDK stack (or a manual deployment) already\ncreated them. Attempting to create roles with the same name twice in the\nsame account causes a CloudFormation `EntityAlreadyExists` error.\n\nWhen `false`, the construct expects the roles to already be present and\nskips creating them. The `dmsVpcRole` and `dmsCloudWatchRole` properties\nwill be `undefined`.",
4989
+ "remarks": "When `true`, the roles are created idempotently via a custom resource: if\neither role already exists in the account (created by another stack or\nmanually), the existing role is silently reused and its trust policy is\ncorrected if necessary. The roles are created with `RemovalPolicy.RETAIN`\nand are **not** lifecycle-managed by this stack — they will not be deleted\nwhen the stack is destroyed. If you require the roles to be\nlifecycle-managed, create them in a dedicated stack and set this to\n`false`, then pass cross-stack references as needed.\n\nWhen `false`, the construct expects the roles to already be present and\nskips creating them. The `dmsVpcRole` and `dmsCloudWatchRole` properties\nwill be `undefined`.",
4990
4990
  "stability": "stable",
4991
4991
  "summary": "Whether to create the two account-level DMS service roles (`dms-vpc-role` and `dms-cloudwatch-logs-role`) required by DMS."
4992
4992
  },
4993
4993
  "immutable": true,
4994
4994
  "locationInModule": {
4995
4995
  "filename": "src/migration-pipeline.ts",
4996
- "line": 236
4996
+ "line": 239
4997
4997
  },
4998
4998
  "name": "createDmsServiceRoles",
4999
4999
  "optional": true,
@@ -5011,7 +5011,7 @@
5011
5011
  "immutable": true,
5012
5012
  "locationInModule": {
5013
5013
  "filename": "src/migration-pipeline.ts",
5014
- "line": 209
5014
+ "line": 208
5015
5015
  },
5016
5016
  "name": "enableCloudWatchLogs",
5017
5017
  "optional": true,
@@ -5029,7 +5029,7 @@
5029
5029
  "immutable": true,
5030
5030
  "locationInModule": {
5031
5031
  "filename": "src/migration-pipeline.ts",
5032
- "line": 132
5032
+ "line": 131
5033
5033
  },
5034
5034
  "name": "encryptionKey",
5035
5035
  "optional": true,
@@ -5047,7 +5047,7 @@
5047
5047
  "immutable": true,
5048
5048
  "locationInModule": {
5049
5049
  "filename": "src/migration-pipeline.ts",
5050
- "line": 126
5050
+ "line": 125
5051
5051
  },
5052
5052
  "name": "engineVersion",
5053
5053
  "optional": true,
@@ -5065,7 +5065,7 @@
5065
5065
  "immutable": true,
5066
5066
  "locationInModule": {
5067
5067
  "filename": "src/migration-pipeline.ts",
5068
- "line": 148
5068
+ "line": 147
5069
5069
  },
5070
5070
  "name": "existingSourceEndpoint",
5071
5071
  "optional": true,
@@ -5083,7 +5083,7 @@
5083
5083
  "immutable": true,
5084
5084
  "locationInModule": {
5085
5085
  "filename": "src/migration-pipeline.ts",
5086
- "line": 160
5086
+ "line": 159
5087
5087
  },
5088
5088
  "name": "existingTargetEndpoint",
5089
5089
  "optional": true,
@@ -5101,7 +5101,7 @@
5101
5101
  "immutable": true,
5102
5102
  "locationInModule": {
5103
5103
  "filename": "src/migration-pipeline.ts",
5104
- "line": 215
5104
+ "line": 214
5105
5105
  },
5106
5106
  "name": "logRetention",
5107
5107
  "optional": true,
@@ -5119,7 +5119,7 @@
5119
5119
  "immutable": true,
5120
5120
  "locationInModule": {
5121
5121
  "filename": "src/migration-pipeline.ts",
5122
- "line": 120
5122
+ "line": 119
5123
5123
  },
5124
5124
  "name": "multiAz",
5125
5125
  "optional": true,
@@ -5137,7 +5137,7 @@
5137
5137
  "immutable": true,
5138
5138
  "locationInModule": {
5139
5139
  "filename": "src/migration-pipeline.ts",
5140
- "line": 246
5140
+ "line": 249
5141
5141
  },
5142
5142
  "name": "removalPolicy",
5143
5143
  "optional": true,
@@ -5155,7 +5155,7 @@
5155
5155
  "immutable": true,
5156
5156
  "locationInModule": {
5157
5157
  "filename": "src/migration-pipeline.ts",
5158
- "line": 108
5158
+ "line": 107
5159
5159
  },
5160
5160
  "name": "replicationInstanceClass",
5161
5161
  "optional": true,
@@ -5173,7 +5173,7 @@
5173
5173
  "immutable": true,
5174
5174
  "locationInModule": {
5175
5175
  "filename": "src/migration-pipeline.ts",
5176
- "line": 142
5176
+ "line": 141
5177
5177
  },
5178
5178
  "name": "sourceEndpoint",
5179
5179
  "optional": true,
@@ -5191,7 +5191,7 @@
5191
5191
  "immutable": true,
5192
5192
  "locationInModule": {
5193
5193
  "filename": "src/migration-pipeline.ts",
5194
- "line": 174
5194
+ "line": 173
5195
5195
  },
5196
5196
  "name": "tableMappings",
5197
5197
  "optional": true,
@@ -5209,7 +5209,7 @@
5209
5209
  "immutable": true,
5210
5210
  "locationInModule": {
5211
5211
  "filename": "src/migration-pipeline.ts",
5212
- "line": 154
5212
+ "line": 153
5213
5213
  },
5214
5214
  "name": "targetEndpoint",
5215
5215
  "optional": true,
@@ -5227,7 +5227,7 @@
5227
5227
  "immutable": true,
5228
5228
  "locationInModule": {
5229
5229
  "filename": "src/migration-pipeline.ts",
5230
- "line": 181
5230
+ "line": 180
5231
5231
  },
5232
5232
  "name": "taskSettings",
5233
5233
  "optional": true,
@@ -5245,7 +5245,7 @@
5245
5245
  "immutable": true,
5246
5246
  "locationInModule": {
5247
5247
  "filename": "src/migration-pipeline.ts",
5248
- "line": 102
5248
+ "line": 101
5249
5249
  },
5250
5250
  "name": "vpcSubnets",
5251
5251
  "optional": true,
@@ -5993,7 +5993,7 @@
5993
5993
  },
5994
5994
  "locationInModule": {
5995
5995
  "filename": "src/serverless-pipeline.ts",
5996
- "line": 272
5996
+ "line": 279
5997
5997
  },
5998
5998
  "parameters": [
5999
5999
  {
@@ -6019,7 +6019,7 @@
6019
6019
  "kind": "class",
6020
6020
  "locationInModule": {
6021
6021
  "filename": "src/serverless-pipeline.ts",
6022
- "line": 235
6022
+ "line": 242
6023
6023
  },
6024
6024
  "name": "DmsServerlessPipeline",
6025
6025
  "properties": [
@@ -6031,7 +6031,7 @@
6031
6031
  "immutable": true,
6032
6032
  "locationInModule": {
6033
6033
  "filename": "src/serverless-pipeline.ts",
6034
- "line": 237
6034
+ "line": 244
6035
6035
  },
6036
6036
  "name": "cfnReplicationConfig",
6037
6037
  "type": {
@@ -6046,7 +6046,7 @@
6046
6046
  "immutable": true,
6047
6047
  "locationInModule": {
6048
6048
  "filename": "src/serverless-pipeline.ts",
6049
- "line": 252
6049
+ "line": 259
6050
6050
  },
6051
6051
  "name": "encryptionKey",
6052
6052
  "type": {
@@ -6061,7 +6061,7 @@
6061
6061
  "immutable": true,
6062
6062
  "locationInModule": {
6063
6063
  "filename": "src/serverless-pipeline.ts",
6064
- "line": 240
6064
+ "line": 247
6065
6065
  },
6066
6066
  "name": "replicationConfigArn",
6067
6067
  "type": {
@@ -6076,7 +6076,7 @@
6076
6076
  "immutable": true,
6077
6077
  "locationInModule": {
6078
6078
  "filename": "src/serverless-pipeline.ts",
6079
- "line": 255
6079
+ "line": 262
6080
6080
  },
6081
6081
  "name": "securityGroup",
6082
6082
  "type": {
@@ -6091,7 +6091,7 @@
6091
6091
  "immutable": true,
6092
6092
  "locationInModule": {
6093
6093
  "filename": "src/serverless-pipeline.ts",
6094
- "line": 243
6094
+ "line": 250
6095
6095
  },
6096
6096
  "name": "source",
6097
6097
  "type": {
@@ -6106,7 +6106,7 @@
6106
6106
  "immutable": true,
6107
6107
  "locationInModule": {
6108
6108
  "filename": "src/serverless-pipeline.ts",
6109
- "line": 249
6109
+ "line": 256
6110
6110
  },
6111
6111
  "name": "subnetGroup",
6112
6112
  "type": {
@@ -6121,7 +6121,7 @@
6121
6121
  "immutable": true,
6122
6122
  "locationInModule": {
6123
6123
  "filename": "src/serverless-pipeline.ts",
6124
- "line": 246
6124
+ "line": 253
6125
6125
  },
6126
6126
  "name": "target",
6127
6127
  "type": {
@@ -6132,34 +6132,34 @@
6132
6132
  "docs": {
6133
6133
  "remarks": "`undefined` when `createDmsServiceRoles` is `false`.",
6134
6134
  "stability": "stable",
6135
- "summary": "IAM role that allows DMS to write to CloudWatch Logs."
6135
+ "summary": "Construct wrapping the custom resources that created the `dms-cloudwatch-logs-role`."
6136
6136
  },
6137
6137
  "immutable": true,
6138
6138
  "locationInModule": {
6139
6139
  "filename": "src/serverless-pipeline.ts",
6140
- "line": 264
6140
+ "line": 271
6141
6141
  },
6142
6142
  "name": "dmsCloudWatchRole",
6143
6143
  "optional": true,
6144
6144
  "type": {
6145
- "fqn": "aws-cdk-lib.aws_iam.Role"
6145
+ "fqn": "constructs.Construct"
6146
6146
  }
6147
6147
  },
6148
6148
  {
6149
6149
  "docs": {
6150
6150
  "remarks": "`undefined` when `createDmsServiceRoles` is `false`.",
6151
6151
  "stability": "stable",
6152
- "summary": "IAM role that allows DMS to manage VPC resources (dms-vpc-role)."
6152
+ "summary": "Construct wrapping the custom resources that created the `dms-vpc-role`."
6153
6153
  },
6154
6154
  "immutable": true,
6155
6155
  "locationInModule": {
6156
6156
  "filename": "src/serverless-pipeline.ts",
6157
- "line": 270
6157
+ "line": 277
6158
6158
  },
6159
6159
  "name": "dmsVpcRole",
6160
6160
  "optional": true,
6161
6161
  "type": {
6162
- "fqn": "aws-cdk-lib.aws_iam.Role"
6162
+ "fqn": "constructs.Construct"
6163
6163
  }
6164
6164
  },
6165
6165
  {
@@ -6170,7 +6170,7 @@
6170
6170
  "immutable": true,
6171
6171
  "locationInModule": {
6172
6172
  "filename": "src/serverless-pipeline.ts",
6173
- "line": 258
6173
+ "line": 265
6174
6174
  },
6175
6175
  "name": "logGroup",
6176
6176
  "optional": true,
@@ -6192,7 +6192,7 @@
6192
6192
  "kind": "interface",
6193
6193
  "locationInModule": {
6194
6194
  "filename": "src/serverless-pipeline.ts",
6195
- "line": 24
6195
+ "line": 23
6196
6196
  },
6197
6197
  "name": "DmsServerlessPipelineProps",
6198
6198
  "properties": [
@@ -6206,7 +6206,7 @@
6206
6206
  "immutable": true,
6207
6207
  "locationInModule": {
6208
6208
  "filename": "src/serverless-pipeline.ts",
6209
- "line": 57
6209
+ "line": 56
6210
6210
  },
6211
6211
  "name": "maxCapacityUnits",
6212
6212
  "type": {
@@ -6222,7 +6222,7 @@
6222
6222
  "immutable": true,
6223
6223
  "locationInModule": {
6224
6224
  "filename": "src/serverless-pipeline.ts",
6225
- "line": 119
6225
+ "line": 118
6226
6226
  },
6227
6227
  "name": "migrationType",
6228
6228
  "type": {
@@ -6239,7 +6239,7 @@
6239
6239
  "immutable": true,
6240
6240
  "locationInModule": {
6241
6241
  "filename": "src/serverless-pipeline.ts",
6242
- "line": 33
6242
+ "line": 32
6243
6243
  },
6244
6244
  "name": "vpc",
6245
6245
  "type": {
@@ -6250,14 +6250,14 @@
6250
6250
  "abstract": true,
6251
6251
  "docs": {
6252
6252
  "default": "true",
6253
- "remarks": "Set to `false` if the roles already existfor example, because a\n`DmsMigrationPipeline` or a prior manual deployment already created them.\nAttempting to create roles with the same name twice causes a CloudFormation\n`EntityAlreadyExists` error.",
6253
+ "remarks": "When `true`, the roles are created idempotently via a custom resource: if\neither role already exists in the account (created by another stack or\nmanually), the existing role is silently reused and its trust policy is\ncorrected if necessary. The roles are created with `RemovalPolicy.RETAIN`\nand are **not** lifecycle-managed by this stack they will not be deleted\nwhen the stack is destroyed. If you require the roles to be\nlifecycle-managed, create them in a dedicated stack and set this to\n`false`, then pass cross-stack references as needed.\n\nWhen `false`, the construct expects the roles to already be present and\nskips creating them. The `dmsVpcRole` and `dmsCloudWatchRole` properties\nwill be `undefined`.",
6254
6254
  "stability": "stable",
6255
6255
  "summary": "Whether to create the two account-level DMS service roles (`dms-vpc-role` and `dms-cloudwatch-logs-role`) required by DMS."
6256
6256
  },
6257
6257
  "immutable": true,
6258
6258
  "locationInModule": {
6259
6259
  "filename": "src/serverless-pipeline.ts",
6260
- "line": 172
6260
+ "line": 179
6261
6261
  },
6262
6262
  "name": "createDmsServiceRoles",
6263
6263
  "optional": true,
@@ -6275,7 +6275,7 @@
6275
6275
  "immutable": true,
6276
6276
  "locationInModule": {
6277
6277
  "filename": "src/serverless-pipeline.ts",
6278
- "line": 149
6278
+ "line": 148
6279
6279
  },
6280
6280
  "name": "enableCloudWatchLogs",
6281
6281
  "optional": true,
@@ -6293,7 +6293,7 @@
6293
6293
  "immutable": true,
6294
6294
  "locationInModule": {
6295
6295
  "filename": "src/serverless-pipeline.ts",
6296
- "line": 100
6296
+ "line": 99
6297
6297
  },
6298
6298
  "name": "existingSourceEndpoint",
6299
6299
  "optional": true,
@@ -6311,7 +6311,7 @@
6311
6311
  "immutable": true,
6312
6312
  "locationInModule": {
6313
6313
  "filename": "src/serverless-pipeline.ts",
6314
- "line": 112
6314
+ "line": 111
6315
6315
  },
6316
6316
  "name": "existingTargetEndpoint",
6317
6317
  "optional": true,
@@ -6329,7 +6329,7 @@
6329
6329
  "immutable": true,
6330
6330
  "locationInModule": {
6331
6331
  "filename": "src/serverless-pipeline.ts",
6332
- "line": 84
6332
+ "line": 83
6333
6333
  },
6334
6334
  "name": "kmsKey",
6335
6335
  "optional": true,
@@ -6347,7 +6347,7 @@
6347
6347
  "immutable": true,
6348
6348
  "locationInModule": {
6349
6349
  "filename": "src/serverless-pipeline.ts",
6350
- "line": 155
6350
+ "line": 154
6351
6351
  },
6352
6352
  "name": "logRetention",
6353
6353
  "optional": true,
@@ -6365,7 +6365,7 @@
6365
6365
  "immutable": true,
6366
6366
  "locationInModule": {
6367
6367
  "filename": "src/serverless-pipeline.ts",
6368
- "line": 63
6368
+ "line": 62
6369
6369
  },
6370
6370
  "name": "minCapacityUnits",
6371
6371
  "optional": true,
@@ -6383,7 +6383,7 @@
6383
6383
  "immutable": true,
6384
6384
  "locationInModule": {
6385
6385
  "filename": "src/serverless-pipeline.ts",
6386
- "line": 69
6386
+ "line": 68
6387
6387
  },
6388
6388
  "name": "multiAz",
6389
6389
  "optional": true,
@@ -6400,7 +6400,7 @@
6400
6400
  "immutable": true,
6401
6401
  "locationInModule": {
6402
6402
  "filename": "src/serverless-pipeline.ts",
6403
- "line": 74
6403
+ "line": 73
6404
6404
  },
6405
6405
  "name": "preferredMaintenanceWindow",
6406
6406
  "optional": true,
@@ -6418,7 +6418,7 @@
6418
6418
  "immutable": true,
6419
6419
  "locationInModule": {
6420
6420
  "filename": "src/serverless-pipeline.ts",
6421
- "line": 188
6421
+ "line": 195
6422
6422
  },
6423
6423
  "name": "removalPolicy",
6424
6424
  "optional": true,
@@ -6436,7 +6436,7 @@
6436
6436
  "immutable": true,
6437
6437
  "locationInModule": {
6438
6438
  "filename": "src/serverless-pipeline.ts",
6439
- "line": 182
6439
+ "line": 189
6440
6440
  },
6441
6441
  "name": "replicationConfigIdentifier",
6442
6442
  "optional": true,
@@ -6454,7 +6454,7 @@
6454
6454
  "immutable": true,
6455
6455
  "locationInModule": {
6456
6456
  "filename": "src/serverless-pipeline.ts",
6457
- "line": 45
6457
+ "line": 44
6458
6458
  },
6459
6459
  "name": "securityGroups",
6460
6460
  "optional": true,
@@ -6477,7 +6477,7 @@
6477
6477
  "immutable": true,
6478
6478
  "locationInModule": {
6479
6479
  "filename": "src/serverless-pipeline.ts",
6480
- "line": 94
6480
+ "line": 93
6481
6481
  },
6482
6482
  "name": "sourceEndpoint",
6483
6483
  "optional": true,
@@ -6495,7 +6495,7 @@
6495
6495
  "immutable": true,
6496
6496
  "locationInModule": {
6497
6497
  "filename": "src/serverless-pipeline.ts",
6498
- "line": 126
6498
+ "line": 125
6499
6499
  },
6500
6500
  "name": "tableMappings",
6501
6501
  "optional": true,
@@ -6513,7 +6513,7 @@
6513
6513
  "immutable": true,
6514
6514
  "locationInModule": {
6515
6515
  "filename": "src/serverless-pipeline.ts",
6516
- "line": 106
6516
+ "line": 105
6517
6517
  },
6518
6518
  "name": "targetEndpoint",
6519
6519
  "optional": true,
@@ -6534,7 +6534,7 @@
6534
6534
  "immutable": true,
6535
6535
  "locationInModule": {
6536
6536
  "filename": "src/serverless-pipeline.ts",
6537
- "line": 139
6537
+ "line": 138
6538
6538
  },
6539
6539
  "name": "taskSettings",
6540
6540
  "optional": true,
@@ -6552,7 +6552,7 @@
6552
6552
  "immutable": true,
6553
6553
  "locationInModule": {
6554
6554
  "filename": "src/serverless-pipeline.ts",
6555
- "line": 39
6555
+ "line": 38
6556
6556
  },
6557
6557
  "name": "vpcSubnets",
6558
6558
  "optional": true,
@@ -11296,7 +11296,7 @@
11296
11296
  "kind": "interface",
11297
11297
  "locationInModule": {
11298
11298
  "filename": "src/migration-pipeline.ts",
11299
- "line": 23
11299
+ "line": 22
11300
11300
  },
11301
11301
  "name": "SourceEndpointOptions",
11302
11302
  "properties": [
@@ -11308,7 +11308,7 @@
11308
11308
  "immutable": true,
11309
11309
  "locationInModule": {
11310
11310
  "filename": "src/migration-pipeline.ts",
11311
- "line": 24
11311
+ "line": 23
11312
11312
  },
11313
11313
  "name": "engine",
11314
11314
  "type": {
@@ -11323,7 +11323,7 @@
11323
11323
  "immutable": true,
11324
11324
  "locationInModule": {
11325
11325
  "filename": "src/migration-pipeline.ts",
11326
- "line": 37
11326
+ "line": 36
11327
11327
  },
11328
11328
  "name": "certificateArn",
11329
11329
  "optional": true,
@@ -11339,7 +11339,7 @@
11339
11339
  "immutable": true,
11340
11340
  "locationInModule": {
11341
11341
  "filename": "src/migration-pipeline.ts",
11342
- "line": 35
11342
+ "line": 34
11343
11343
  },
11344
11344
  "name": "databaseName",
11345
11345
  "optional": true,
@@ -11355,7 +11355,7 @@
11355
11355
  "immutable": true,
11356
11356
  "locationInModule": {
11357
11357
  "filename": "src/migration-pipeline.ts",
11358
- "line": 44
11358
+ "line": 43
11359
11359
  },
11360
11360
  "name": "db2Settings",
11361
11361
  "optional": true,
@@ -11371,7 +11371,7 @@
11371
11371
  "immutable": true,
11372
11372
  "locationInModule": {
11373
11373
  "filename": "src/migration-pipeline.ts",
11374
- "line": 25
11374
+ "line": 24
11375
11375
  },
11376
11376
  "name": "endpointIdentifier",
11377
11377
  "optional": true,
@@ -11387,7 +11387,7 @@
11387
11387
  "immutable": true,
11388
11388
  "locationInModule": {
11389
11389
  "filename": "src/migration-pipeline.ts",
11390
- "line": 36
11390
+ "line": 35
11391
11391
  },
11392
11392
  "name": "extraConnectionAttributes",
11393
11393
  "optional": true,
@@ -11403,7 +11403,7 @@
11403
11403
  "immutable": true,
11404
11404
  "locationInModule": {
11405
11405
  "filename": "src/migration-pipeline.ts",
11406
- "line": 45
11406
+ "line": 44
11407
11407
  },
11408
11408
  "name": "mongoDbSettings",
11409
11409
  "optional": true,
@@ -11419,7 +11419,7 @@
11419
11419
  "immutable": true,
11420
11420
  "locationInModule": {
11421
11421
  "filename": "src/migration-pipeline.ts",
11422
- "line": 39
11422
+ "line": 38
11423
11423
  },
11424
11424
  "name": "mySqlSettings",
11425
11425
  "optional": true,
@@ -11435,7 +11435,7 @@
11435
11435
  "immutable": true,
11436
11436
  "locationInModule": {
11437
11437
  "filename": "src/migration-pipeline.ts",
11438
- "line": 41
11438
+ "line": 40
11439
11439
  },
11440
11440
  "name": "oracleSettings",
11441
11441
  "optional": true,
@@ -11453,7 +11453,7 @@
11453
11453
  "immutable": true,
11454
11454
  "locationInModule": {
11455
11455
  "filename": "src/migration-pipeline.ts",
11456
- "line": 34
11456
+ "line": 33
11457
11457
  },
11458
11458
  "name": "password",
11459
11459
  "optional": true,
@@ -11469,7 +11469,7 @@
11469
11469
  "immutable": true,
11470
11470
  "locationInModule": {
11471
11471
  "filename": "src/migration-pipeline.ts",
11472
- "line": 27
11472
+ "line": 26
11473
11473
  },
11474
11474
  "name": "port",
11475
11475
  "optional": true,
@@ -11485,7 +11485,7 @@
11485
11485
  "immutable": true,
11486
11486
  "locationInModule": {
11487
11487
  "filename": "src/migration-pipeline.ts",
11488
- "line": 40
11488
+ "line": 39
11489
11489
  },
11490
11490
  "name": "postgreSqlSettings",
11491
11491
  "optional": true,
@@ -11501,7 +11501,7 @@
11501
11501
  "immutable": true,
11502
11502
  "locationInModule": {
11503
11503
  "filename": "src/migration-pipeline.ts",
11504
- "line": 46
11504
+ "line": 45
11505
11505
  },
11506
11506
  "name": "s3Settings",
11507
11507
  "optional": true,
@@ -11517,7 +11517,7 @@
11517
11517
  "immutable": true,
11518
11518
  "locationInModule": {
11519
11519
  "filename": "src/migration-pipeline.ts",
11520
- "line": 43
11520
+ "line": 42
11521
11521
  },
11522
11522
  "name": "sapAseSettings",
11523
11523
  "optional": true,
@@ -11533,7 +11533,7 @@
11533
11533
  "immutable": true,
11534
11534
  "locationInModule": {
11535
11535
  "filename": "src/migration-pipeline.ts",
11536
- "line": 26
11536
+ "line": 25
11537
11537
  },
11538
11538
  "name": "serverName",
11539
11539
  "optional": true,
@@ -11549,7 +11549,7 @@
11549
11549
  "immutable": true,
11550
11550
  "locationInModule": {
11551
11551
  "filename": "src/migration-pipeline.ts",
11552
- "line": 42
11552
+ "line": 41
11553
11553
  },
11554
11554
  "name": "sqlServerSettings",
11555
11555
  "optional": true,
@@ -11565,7 +11565,7 @@
11565
11565
  "immutable": true,
11566
11566
  "locationInModule": {
11567
11567
  "filename": "src/migration-pipeline.ts",
11568
- "line": 38
11568
+ "line": 37
11569
11569
  },
11570
11570
  "name": "sslMode",
11571
11571
  "optional": true,
@@ -11581,7 +11581,7 @@
11581
11581
  "immutable": true,
11582
11582
  "locationInModule": {
11583
11583
  "filename": "src/migration-pipeline.ts",
11584
- "line": 28
11584
+ "line": 27
11585
11585
  },
11586
11586
  "name": "username",
11587
11587
  "optional": true,
@@ -12644,7 +12644,7 @@
12644
12644
  "kind": "interface",
12645
12645
  "locationInModule": {
12646
12646
  "filename": "src/migration-pipeline.ts",
12647
- "line": 53
12647
+ "line": 52
12648
12648
  },
12649
12649
  "name": "TargetEndpointOptions",
12650
12650
  "properties": [
@@ -12656,7 +12656,7 @@
12656
12656
  "immutable": true,
12657
12657
  "locationInModule": {
12658
12658
  "filename": "src/migration-pipeline.ts",
12659
- "line": 54
12659
+ "line": 53
12660
12660
  },
12661
12661
  "name": "engine",
12662
12662
  "type": {
@@ -12671,7 +12671,7 @@
12671
12671
  "immutable": true,
12672
12672
  "locationInModule": {
12673
12673
  "filename": "src/migration-pipeline.ts",
12674
- "line": 67
12674
+ "line": 66
12675
12675
  },
12676
12676
  "name": "certificateArn",
12677
12677
  "optional": true,
@@ -12687,7 +12687,7 @@
12687
12687
  "immutable": true,
12688
12688
  "locationInModule": {
12689
12689
  "filename": "src/migration-pipeline.ts",
12690
- "line": 65
12690
+ "line": 64
12691
12691
  },
12692
12692
  "name": "databaseName",
12693
12693
  "optional": true,
@@ -12703,7 +12703,7 @@
12703
12703
  "immutable": true,
12704
12704
  "locationInModule": {
12705
12705
  "filename": "src/migration-pipeline.ts",
12706
- "line": 74
12706
+ "line": 73
12707
12707
  },
12708
12708
  "name": "db2Settings",
12709
12709
  "optional": true,
@@ -12719,7 +12719,7 @@
12719
12719
  "immutable": true,
12720
12720
  "locationInModule": {
12721
12721
  "filename": "src/migration-pipeline.ts",
12722
- "line": 77
12722
+ "line": 76
12723
12723
  },
12724
12724
  "name": "dynamoDbSettings",
12725
12725
  "optional": true,
@@ -12735,7 +12735,7 @@
12735
12735
  "immutable": true,
12736
12736
  "locationInModule": {
12737
12737
  "filename": "src/migration-pipeline.ts",
12738
- "line": 55
12738
+ "line": 54
12739
12739
  },
12740
12740
  "name": "endpointIdentifier",
12741
12741
  "optional": true,
@@ -12751,7 +12751,7 @@
12751
12751
  "immutable": true,
12752
12752
  "locationInModule": {
12753
12753
  "filename": "src/migration-pipeline.ts",
12754
- "line": 66
12754
+ "line": 65
12755
12755
  },
12756
12756
  "name": "extraConnectionAttributes",
12757
12757
  "optional": true,
@@ -12767,7 +12767,7 @@
12767
12767
  "immutable": true,
12768
12768
  "locationInModule": {
12769
12769
  "filename": "src/migration-pipeline.ts",
12770
- "line": 80
12770
+ "line": 79
12771
12771
  },
12772
12772
  "name": "kafkaSettings",
12773
12773
  "optional": true,
@@ -12783,7 +12783,7 @@
12783
12783
  "immutable": true,
12784
12784
  "locationInModule": {
12785
12785
  "filename": "src/migration-pipeline.ts",
12786
- "line": 79
12786
+ "line": 78
12787
12787
  },
12788
12788
  "name": "kinesisSettings",
12789
12789
  "optional": true,
@@ -12799,7 +12799,7 @@
12799
12799
  "immutable": true,
12800
12800
  "locationInModule": {
12801
12801
  "filename": "src/migration-pipeline.ts",
12802
- "line": 75
12802
+ "line": 74
12803
12803
  },
12804
12804
  "name": "mongoDbSettings",
12805
12805
  "optional": true,
@@ -12815,7 +12815,7 @@
12815
12815
  "immutable": true,
12816
12816
  "locationInModule": {
12817
12817
  "filename": "src/migration-pipeline.ts",
12818
- "line": 69
12818
+ "line": 68
12819
12819
  },
12820
12820
  "name": "mySqlSettings",
12821
12821
  "optional": true,
@@ -12831,7 +12831,7 @@
12831
12831
  "immutable": true,
12832
12832
  "locationInModule": {
12833
12833
  "filename": "src/migration-pipeline.ts",
12834
- "line": 82
12834
+ "line": 81
12835
12835
  },
12836
12836
  "name": "neptuneSettings",
12837
12837
  "optional": true,
@@ -12847,7 +12847,7 @@
12847
12847
  "immutable": true,
12848
12848
  "locationInModule": {
12849
12849
  "filename": "src/migration-pipeline.ts",
12850
- "line": 81
12850
+ "line": 80
12851
12851
  },
12852
12852
  "name": "openSearchSettings",
12853
12853
  "optional": true,
@@ -12863,7 +12863,7 @@
12863
12863
  "immutable": true,
12864
12864
  "locationInModule": {
12865
12865
  "filename": "src/migration-pipeline.ts",
12866
- "line": 71
12866
+ "line": 70
12867
12867
  },
12868
12868
  "name": "oracleSettings",
12869
12869
  "optional": true,
@@ -12881,7 +12881,7 @@
12881
12881
  "immutable": true,
12882
12882
  "locationInModule": {
12883
12883
  "filename": "src/migration-pipeline.ts",
12884
- "line": 64
12884
+ "line": 63
12885
12885
  },
12886
12886
  "name": "password",
12887
12887
  "optional": true,
@@ -12897,7 +12897,7 @@
12897
12897
  "immutable": true,
12898
12898
  "locationInModule": {
12899
12899
  "filename": "src/migration-pipeline.ts",
12900
- "line": 57
12900
+ "line": 56
12901
12901
  },
12902
12902
  "name": "port",
12903
12903
  "optional": true,
@@ -12913,7 +12913,7 @@
12913
12913
  "immutable": true,
12914
12914
  "locationInModule": {
12915
12915
  "filename": "src/migration-pipeline.ts",
12916
- "line": 70
12916
+ "line": 69
12917
12917
  },
12918
12918
  "name": "postgreSqlSettings",
12919
12919
  "optional": true,
@@ -12929,7 +12929,7 @@
12929
12929
  "immutable": true,
12930
12930
  "locationInModule": {
12931
12931
  "filename": "src/migration-pipeline.ts",
12932
- "line": 83
12932
+ "line": 82
12933
12933
  },
12934
12934
  "name": "redisSettings",
12935
12935
  "optional": true,
@@ -12945,7 +12945,7 @@
12945
12945
  "immutable": true,
12946
12946
  "locationInModule": {
12947
12947
  "filename": "src/migration-pipeline.ts",
12948
- "line": 78
12948
+ "line": 77
12949
12949
  },
12950
12950
  "name": "redshiftSettings",
12951
12951
  "optional": true,
@@ -12961,7 +12961,7 @@
12961
12961
  "immutable": true,
12962
12962
  "locationInModule": {
12963
12963
  "filename": "src/migration-pipeline.ts",
12964
- "line": 76
12964
+ "line": 75
12965
12965
  },
12966
12966
  "name": "s3Settings",
12967
12967
  "optional": true,
@@ -12977,7 +12977,7 @@
12977
12977
  "immutable": true,
12978
12978
  "locationInModule": {
12979
12979
  "filename": "src/migration-pipeline.ts",
12980
- "line": 73
12980
+ "line": 72
12981
12981
  },
12982
12982
  "name": "sapAseSettings",
12983
12983
  "optional": true,
@@ -12993,7 +12993,7 @@
12993
12993
  "immutable": true,
12994
12994
  "locationInModule": {
12995
12995
  "filename": "src/migration-pipeline.ts",
12996
- "line": 56
12996
+ "line": 55
12997
12997
  },
12998
12998
  "name": "serverName",
12999
12999
  "optional": true,
@@ -13009,7 +13009,7 @@
13009
13009
  "immutable": true,
13010
13010
  "locationInModule": {
13011
13011
  "filename": "src/migration-pipeline.ts",
13012
- "line": 72
13012
+ "line": 71
13013
13013
  },
13014
13014
  "name": "sqlServerSettings",
13015
13015
  "optional": true,
@@ -13025,7 +13025,7 @@
13025
13025
  "immutable": true,
13026
13026
  "locationInModule": {
13027
13027
  "filename": "src/migration-pipeline.ts",
13028
- "line": 68
13028
+ "line": 67
13029
13029
  },
13030
13030
  "name": "sslMode",
13031
13031
  "optional": true,
@@ -13041,7 +13041,7 @@
13041
13041
  "immutable": true,
13042
13042
  "locationInModule": {
13043
13043
  "filename": "src/migration-pipeline.ts",
13044
- "line": 58
13044
+ "line": 57
13045
13045
  },
13046
13046
  "name": "username",
13047
13047
  "optional": true,
@@ -13480,6 +13480,6 @@
13480
13480
  "symbolId": "src/table-mappings:TransformationAction"
13481
13481
  }
13482
13482
  },
13483
- "version": "0.0.16",
13484
- "fingerprint": "Gshn4bKO1FkK30PscmwCnsRuxSsYSVq1pQ7pwiZFmO8="
13483
+ "version": "0.1.1",
13484
+ "fingerprint": "OZkzjYKUjTnfAqrI/5Izuussehn0mdV6yZffGyhWQKs="
13485
13485
  }