cdk-dms-replication 0.0.0

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.
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.DmsReplicationInstance = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const cdk = require("aws-cdk-lib");
7
+ const dms = require("aws-cdk-lib/aws-dms");
8
+ const ec2 = require("aws-cdk-lib/aws-ec2");
9
+ const kms = require("aws-cdk-lib/aws-kms");
10
+ const constructs_1 = require("constructs");
11
+ const enums_1 = require("./enums");
12
+ /**
13
+ * An L2-style construct that provisions a DMS replication instance with:
14
+ * - Private subnet placement via a dedicated subnet group
15
+ * - KMS encryption at rest (key created if not provided)
16
+ * - A dedicated security group (created if not provided)
17
+ */
18
+ class DmsReplicationInstance extends constructs_1.Construct {
19
+ constructor(scope, id, props) {
20
+ super(scope, id);
21
+ // -----------------------------------------------------------------------
22
+ // KMS key
23
+ // -----------------------------------------------------------------------
24
+ this.encryptionKey =
25
+ props.kmsKey ??
26
+ new kms.Key(this, 'EncryptionKey', {
27
+ description: `DMS replication instance encryption key for ${id}`,
28
+ enableKeyRotation: true,
29
+ removalPolicy: props.removalPolicy ?? cdk.RemovalPolicy.DESTROY,
30
+ });
31
+ // -----------------------------------------------------------------------
32
+ // Security group
33
+ // -----------------------------------------------------------------------
34
+ const provided = props.securityGroups ?? [];
35
+ if (provided.length === 0) {
36
+ const sg = new ec2.SecurityGroup(this, 'SecurityGroup', {
37
+ vpc: props.vpc,
38
+ description: `DMS replication instance security group for ${id}`,
39
+ allowAllOutbound: true,
40
+ });
41
+ this.securityGroup = sg;
42
+ }
43
+ else {
44
+ this.securityGroup = provided[0];
45
+ }
46
+ const securityGroupIds = provided.length > 0
47
+ ? provided.map((sg) => sg.securityGroupId)
48
+ : [this.securityGroup.securityGroupId];
49
+ // -----------------------------------------------------------------------
50
+ // Subnet group
51
+ // -----------------------------------------------------------------------
52
+ const subnetSelection = props.vpcSubnets ?? {
53
+ subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
54
+ };
55
+ const subnets = props.vpc.selectSubnets(subnetSelection);
56
+ this.subnetGroup = new dms.CfnReplicationSubnetGroup(this, 'SubnetGroup', {
57
+ replicationSubnetGroupDescription: `DMS subnet group for ${id}`,
58
+ subnetIds: subnets.subnetIds,
59
+ });
60
+ // -----------------------------------------------------------------------
61
+ // Replication instance
62
+ // -----------------------------------------------------------------------
63
+ const instanceIdentifier = props.replicationInstanceIdentifier ?? cdk.Names.uniqueResourceName(this, { maxLength: 63 }).toLowerCase();
64
+ this.cfnReplicationInstance = new dms.CfnReplicationInstance(this, 'Resource', {
65
+ replicationInstanceClass: props.replicationInstanceClass ?? enums_1.ReplicationInstanceClass.R6I_LARGE,
66
+ replicationInstanceIdentifier: instanceIdentifier,
67
+ allocatedStorage: props.allocatedStorage ?? 100,
68
+ engineVersion: props.engineVersion,
69
+ kmsKeyId: this.encryptionKey.keyArn,
70
+ multiAz: props.multiAz ?? false,
71
+ publiclyAccessible: props.publiclyAccessible ?? false,
72
+ autoMinorVersionUpgrade: props.autoMinorVersionUpgrade ?? true,
73
+ replicationSubnetGroupIdentifier: this.subnetGroup.ref,
74
+ vpcSecurityGroupIds: securityGroupIds,
75
+ preferredMaintenanceWindow: props.preferredMaintenanceWindow,
76
+ });
77
+ this.cfnReplicationInstance.applyRemovalPolicy(props.removalPolicy ?? cdk.RemovalPolicy.DESTROY);
78
+ this.replicationInstanceArn = this.cfnReplicationInstance.ref;
79
+ }
80
+ /**
81
+ * Allow inbound access to the replication instance on a given port from a peer.
82
+ * Useful when the source or target database security group needs to trust the instance.
83
+ */
84
+ allowInboundFrom(peer, port, description) {
85
+ if (this.securityGroup instanceof ec2.SecurityGroup) {
86
+ this.securityGroup.addIngressRule(peer, port, description ?? 'Allow DMS replication instance');
87
+ }
88
+ }
89
+ }
90
+ exports.DmsReplicationInstance = DmsReplicationInstance;
91
+ _a = JSII_RTTI_SYMBOL_1;
92
+ DmsReplicationInstance[_a] = { fqn: "cdk-dms-replication.DmsReplicationInstance", version: "0.0.0" };
93
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwbGljYXRpb24taW5zdGFuY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcmVwbGljYXRpb24taW5zdGFuY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxtQ0FBbUM7QUFDbkMsMkNBQTJDO0FBQzNDLDJDQUEyQztBQUMzQywyQ0FBMkM7QUFDM0MsMkNBQXVDO0FBQ3ZDLG1DQUFtRDtBQW9GbkQ7Ozs7O0dBS0c7QUFDSCxNQUFhLHNCQUF1QixTQUFRLHNCQUFTO0lBZ0JuRCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQWtDO1FBQzFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsMEVBQTBFO1FBQzFFLFVBQVU7UUFDViwwRUFBMEU7UUFDMUUsSUFBSSxDQUFDLGFBQWE7WUFDaEIsS0FBSyxDQUFDLE1BQU07Z0JBQ1osSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxlQUFlLEVBQUU7b0JBQ2pDLFdBQVcsRUFBRSwrQ0FBK0MsRUFBRSxFQUFFO29CQUNoRSxpQkFBaUIsRUFBRSxJQUFJO29CQUN2QixhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWEsSUFBSSxHQUFHLENBQUMsYUFBYSxDQUFDLE9BQU87aUJBQ2hFLENBQUMsQ0FBQztRQUVMLDBFQUEwRTtRQUMxRSxpQkFBaUI7UUFDakIsMEVBQTBFO1FBQzFFLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxjQUFjLElBQUksRUFBRSxDQUFDO1FBQzVDLElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMxQixNQUFNLEVBQUUsR0FBRyxJQUFJLEdBQUcsQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRTtnQkFDdEQsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHO2dCQUNkLFdBQVcsRUFBRSwrQ0FBK0MsRUFBRSxFQUFFO2dCQUNoRSxnQkFBZ0IsRUFBRSxJQUFJO2FBQ3ZCLENB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LWNkay1saWInO1xuaW1wb3J0ICogYXMgZG1zIGZyb20gJ2F3cy1jZGstbGliL2F3cy1kbXMnO1xuaW1wb3J0ICogYXMgZWMyIGZyb20gJ2F3cy1jZGstbGliL2F3cy1lYzInO1xuaW1wb3J0ICogYXMga21zIGZyb20gJ2F3cy1jZGstbGliL2F3cy1rbXMnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBSZXBsaWNhdGlvbkluc3RhbmNlQ2xhc3MgfSBmcm9tICcuL2VudW1zJztcblxuLyoqIFByb3BzIGZvciB7QGxpbmsgRG1zUmVwbGljYXRpb25JbnN0YW5jZX0uICovXG5leHBvcnQgaW50ZXJmYWNlIERtc1JlcGxpY2F0aW9uSW5zdGFuY2VQcm9wcyB7XG4gIC8qKlxuICAgKiBJbnN0YW5jZSBjbGFzcyBmb3IgdGhlIHJlcGxpY2F0aW9uIGluc3RhbmNlLlxuICAgKiBAZGVmYXVsdCBSZXBsaWNhdGlvbkluc3RhbmNlQ2xhc3MuUjZJX0xBUkdFXG4gICAqL1xuICByZWFkb25seSByZXBsaWNhdGlvbkluc3RhbmNlQ2xhc3M/OiBSZXBsaWNhdGlvbkluc3RhbmNlQ2xhc3M7XG5cbiAgLyoqXG4gICAqIFZQQyBpbiB3aGljaCB0byBwbGFjZSB0aGUgcmVwbGljYXRpb24gaW5zdGFuY2UuXG4gICAqIFRoZSBjb25zdHJ1Y3QgY3JlYXRlcyBhIGRlZGljYXRlZCBzdWJuZXQgZ3JvdXAgZnJvbSB0aGUgcHJpdmF0ZSBzdWJuZXRzLlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjOiBlYzIuSVZwYztcblxuICAvKipcbiAgICogU3BlY2lmaWMgc3VibmV0cyB0byB1c2UgZm9yIHRoZSByZXBsaWNhdGlvbiBzdWJuZXQgZ3JvdXAuXG4gICAqIERlZmF1bHRzIHRvIGFsbCBwcml2YXRlIHN1Ym5ldHMgaW4gdGhlIFZQQy5cbiAgICovXG4gIHJlYWRvbmx5IHZwY1N1Ym5ldHM/OiBlYzIuU3VibmV0U2VsZWN0aW9uO1xuXG4gIC8qKlxuICAgKiBTZWN1cml0eSBncm91cHMgdG8gYXR0YWNoIHRvIHRoZSByZXBsaWNhdGlvbiBpbnN0YW5jZS5cbiAgICogQSBuZXcgc2VjdXJpdHkgZ3JvdXAgaXMgY3JlYXRlZCBpZiBub25lIGFyZSBwcm92aWRlZC5cbiAgICovXG4gIHJlYWRvbmx5IHNlY3VyaXR5R3JvdXBzPzogZWMyLklTZWN1cml0eUdyb3VwW107XG5cbiAgLyoqXG4gICAqIEtNUyBrZXkgdXNlZCB0byBlbmNyeXB0IHRoZSByZXBsaWNhdGlvbiBpbnN0YW5jZSBzdG9yYWdlIGF0IHJlc3QuXG4gICAqIEEgbmV3IGtleSBpcyBjcmVhdGVkIGlmIG5vdCBwcm92aWRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGttc0tleT86IGttcy5JS2V5O1xuXG4gIC8qKlxuICAgKiBBbGxvY2F0ZWQgc3RvcmFnZSBpbiBHQi5cbiAgICogQGRlZmF1bHQgMTAwXG4gICAqL1xuICByZWFkb25seSBhbGxvY2F0ZWRTdG9yYWdlPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSByZXBsaWNhdGlvbiBpbnN0YW5jZSBpcyBNdWx0aS1BWi5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IG11bHRpQXo/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSByZXBsaWNhdGlvbiBpbnN0YW5jZSBpcyBwdWJsaWNseSBhY2Nlc3NpYmxlLlxuICAgKiBTZXR0aW5nIHRoaXMgdG8gdHJ1ZSBpcyBzdHJvbmdseSBkaXNjb3VyYWdlZCBmb3IgcHJvZHVjdGlvbiB3b3JrbG9hZHMuXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBwdWJsaWNseUFjY2Vzc2libGU/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGFsbG93IG1pbm9yIHZlcnNpb24gdXBncmFkZXMgdG8gYmUgYXBwbGllZCBhdXRvbWF0aWNhbGx5IGR1cmluZyBtYWludGVuYW5jZS5cbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgYXV0b01pbm9yVmVyc2lvblVwZ3JhZGU/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBQcmVmZXJyZWQgbWFpbnRlbmFuY2Ugd2luZG93LCBlLmcuIFwic3VuOjA0OjAwLXN1bjowNDozMFwiLlxuICAgKi9cbiAgcmVhZG9ubHkgcHJlZmVycmVkTWFpbnRlbmFuY2VXaW5kb3c/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFJlcGxpY2F0aW9uIGVuZ2luZSB2ZXJzaW9uLlxuICAgKiBAZGVmYXVsdCBsYXRlc3QgdmVyc2lvbiBhdmFpbGFibGUgaW4gdGhlIHJlZ2lvbiAoY2hvc2VuIGJ5IERNUylcbiAgICovXG4gIHJlYWRvbmx5IGVuZ2luZVZlcnNpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIExvZ2ljYWwgbmFtZSBvZiB0aGUgcmVwbGljYXRpb24gaW5zdGFuY2UuXG4gICAqIFVzZWQgaW4gdGhlIHJlcGxpY2F0aW9uIGluc3RhbmNlIGlkZW50aWZpZXIgYW5kIHJlc291cmNlIG5hbWluZy5cbiAgICogQGRlZmF1bHQgaWQgb2YgdGhlIGNvbnN0cnVjdFxuICAgKi9cbiAgcmVhZG9ubHkgcmVwbGljYXRpb25JbnN0YW5jZUlkZW50aWZpZXI/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFJlbW92YWwgcG9saWN5IGFwcGxpZWQgdG8gdGhlIHJlcGxpY2F0aW9uIGluc3RhbmNlLlxuICAgKiBAZGVmYXVsdCBjZGsuUmVtb3ZhbFBvbGljeS5ERVNUUk9ZXG4gICAqL1xuICByZWFkb25seSByZW1vdmFsUG9saWN5PzogY2RrLlJlbW92YWxQb2xpY3k7XG59XG5cbi8qKlxuICogQW4gTDItc3R5bGUgY29uc3RydWN0IHRoYXQgcHJvdmlzaW9ucyBhIERNUyByZXBsaWNhdGlvbiBpbnN0YW5jZSB3aXRoOlxuICogLSBQcml2YXRlIHN1Ym5ldCBwbGFjZW1lbnQgdmlhIGEgZGVkaWNhdGVkIHN1Ym5ldCBncm91cFxuICogLSBLTVMgZW5jcnlwdGlvbiBhdCByZXN0IChrZXkgY3JlYXRlZCBpZiBub3QgcHJvdmlkZWQpXG4gKiAtIEEgZGVkaWNhdGVkIHNlY3VyaXR5IGdyb3VwIChjcmVhdGVkIGlmIG5vdCBwcm92aWRlZClcbiAqL1xuZXhwb3J0IGNsYXNzIERtc1JlcGxpY2F0aW9uSW5zdGFuY2UgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKiogVGhlIHVuZGVybHlpbmcgQ2xvdWRGb3JtYXRpb24gcmVwbGljYXRpb24gaW5zdGFuY2UgcmVzb3VyY2UuICovXG4gIHJlYWRvbmx5IGNmblJlcGxpY2F0aW9uSW5zdGFuY2U6IGRtcy5DZm5SZXBsaWNhdGlvbkluc3RhbmNlO1xuXG4gIC8qKiBUaGUgcmVwbGljYXRpb24gc3VibmV0IGdyb3VwIGNyZWF0ZWQgZm9yIHRoaXMgaW5zdGFuY2UuICovXG4gIHJlYWRvbmx5IHN1Ym5ldEdyb3VwOiBkbXMuQ2ZuUmVwbGljYXRpb25TdWJuZXRHcm91cDtcblxuICAvKiogVGhlIEtNUyBrZXkgdXNlZCBmb3Igc3RvcmFnZSBlbmNyeXB0aW9uLiAqL1xuICByZWFkb25seSBlbmNyeXB0aW9uS2V5OiBrbXMuSUtleTtcblxuICAvKiogVGhlIHNlY3VyaXR5IGdyb3VwIGF0dGFjaGVkIHRvIHRoaXMgaW5zdGFuY2UuICovXG4gIHJlYWRvbmx5IHNlY3VyaXR5R3JvdXA6IGVjMi5JU2VjdXJpdHlHcm91cDtcblxuICAvKiogVGhlIHJlcGxpY2F0aW9uIGluc3RhbmNlIEFSTi4gKi9cbiAgcmVhZG9ubHkgcmVwbGljYXRpb25JbnN0YW5jZUFybjogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBEbXNSZXBsaWNhdGlvbkluc3RhbmNlUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBLTVMga2V5XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICB0aGlzLmVuY3J5cHRpb25LZXkgPVxuICAgICAgcHJvcHMua21zS2V5ID8/XG4gICAgICBuZXcga21zLktleSh0aGlzLCAnRW5jcnlwdGlvbktleScsIHtcbiAgICAgICAgZGVzY3JpcHRpb246IGBETVMgcmVwbGljYXRpb24gaW5zdGFuY2UgZW5jcnlwdGlvbiBrZXkgZm9yICR7aWR9YCxcbiAgICAgICAgZW5hYmxlS2V5Um90YXRpb246IHRydWUsXG4gICAgICAgIHJlbW92YWxQb2xpY3k6IHByb3BzLnJlbW92YWxQb2xpY3kgPz8gY2RrLlJlbW92YWxQb2xpY3kuREVTVFJPWSxcbiAgICAgIH0pO1xuXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBTZWN1cml0eSBncm91cFxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgY29uc3QgcHJvdmlkZWQgPSBwcm9wcy5zZWN1cml0eUdyb3VwcyA/PyBbXTtcbiAgICBpZiAocHJvdmlkZWQubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb25zdCBzZyA9IG5ldyBlYzIuU2VjdXJpdHlHcm91cCh0aGlzLCAnU2VjdXJpdHlHcm91cCcsIHtcbiAgICAgICAgdnBjOiBwcm9wcy52cGMsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBgRE1TIHJlcGxpY2F0aW9uIGluc3RhbmNlIHNlY3VyaXR5IGdyb3VwIGZvciAke2lkfWAsXG4gICAgICAgIGFsbG93QWxsT3V0Ym91bmQ6IHRydWUsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2VjdXJpdHlHcm91cCA9IHNnO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNlY3VyaXR5R3JvdXAgPSBwcm92aWRlZFswXTtcbiAgICB9XG5cbiAgICBjb25zdCBzZWN1cml0eUdyb3VwSWRzID0gcHJvdmlkZWQubGVuZ3RoID4gMFxuICAgICAgPyBwcm92aWRlZC5tYXAoKHNnKSA9PiBzZy5zZWN1cml0eUdyb3VwSWQpXG4gICAgICA6IFt0aGlzLnNlY3VyaXR5R3JvdXAuc2VjdXJpdHlHcm91cElkXTtcblxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gU3VibmV0IGdyb3VwXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBjb25zdCBzdWJuZXRTZWxlY3Rpb24gPSBwcm9wcy52cGNTdWJuZXRzID8/IHtcbiAgICAgIHN1Ym5ldFR5cGU6IGVjMi5TdWJuZXRUeXBlLlBSSVZBVEVfV0lUSF9FR1JFU1MsXG4gICAgfTtcbiAgICBjb25zdCBzdWJuZXRzID0gcHJvcHMudnBjLnNlbGVjdFN1Ym5ldHMoc3VibmV0U2VsZWN0aW9uKTtcblxuICAgIHRoaXMuc3VibmV0R3JvdXAgPSBuZXcgZG1zLkNmblJlcGxpY2F0aW9uU3VibmV0R3JvdXAodGhpcywgJ1N1Ym5ldEdyb3VwJywge1xuICAgICAgcmVwbGljYXRpb25TdWJuZXRHcm91cERlc2NyaXB0aW9uOiBgRE1TIHN1Ym5ldCBncm91cCBmb3IgJHtpZH1gLFxuICAgICAgc3VibmV0SWRzOiBzdWJuZXRzLnN1Ym5ldElkcyxcbiAgICB9KTtcblxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gUmVwbGljYXRpb24gaW5zdGFuY2VcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGNvbnN0IGluc3RhbmNlSWRlbnRpZmllciA9XG4gICAgICBwcm9wcy5yZXBsaWNhdGlvbkluc3RhbmNlSWRlbnRpZmllciA/PyBjZGsuTmFtZXMudW5pcXVlUmVzb3VyY2VOYW1lKHRoaXMsIHsgbWF4TGVuZ3RoOiA2MyB9KS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgdGhpcy5jZm5SZXBsaWNhdGlvbkluc3RhbmNlID0gbmV3IGRtcy5DZm5SZXBsaWNhdGlvbkluc3RhbmNlKHRoaXMsICdSZXNvdXJjZScsIHtcbiAgICAgIHJlcGxpY2F0aW9uSW5zdGFuY2VDbGFzczogcHJvcHMucmVwbGljYXRpb25JbnN0YW5jZUNsYXNzID8/IFJlcGxpY2F0aW9uSW5zdGFuY2VDbGFzcy5SNklfTEFSR0UsXG4gICAgICByZXBsaWNhdGlvbkluc3RhbmNlSWRlbnRpZmllcjogaW5zdGFuY2VJZGVudGlmaWVyLFxuICAgICAgYWxsb2NhdGVkU3RvcmFnZTogcHJvcHMuYWxsb2NhdGVkU3RvcmFnZSA/PyAxMDAsXG4gICAgICBlbmdpbmVWZXJzaW9uOiBwcm9wcy5lbmdpbmVWZXJzaW9uLFxuICAgICAga21zS2V5SWQ6IHRoaXMuZW5jcnlwdGlvbktleS5rZXlBcm4sXG4gICAgICBtdWx0aUF6OiBwcm9wcy5tdWx0aUF6ID8/IGZhbHNlLFxuICAgICAgcHVibGljbHlBY2Nlc3NpYmxlOiBwcm9wcy5wdWJsaWNseUFjY2Vzc2libGUgPz8gZmFsc2UsXG4gICAgICBhdXRvTWlub3JWZXJzaW9uVXBncmFkZTogcHJvcHMuYXV0b01pbm9yVmVyc2lvblVwZ3JhZGUgPz8gdHJ1ZSxcbiAgICAgIHJlcGxpY2F0aW9uU3VibmV0R3JvdXBJZGVudGlmaWVyOiB0aGlzLnN1Ym5ldEdyb3VwLnJlZixcbiAgICAgIHZwY1NlY3VyaXR5R3JvdXBJZHM6IHNlY3VyaXR5R3JvdXBJZHMsXG4gICAgICBwcmVmZXJyZWRNYWludGVuYW5jZVdpbmRvdzogcHJvcHMucHJlZmVycmVkTWFpbnRlbmFuY2VXaW5kb3csXG4gICAgfSk7XG4gICAgdGhpcy5jZm5SZXBsaWNhdGlvbkluc3RhbmNlLmFwcGx5UmVtb3ZhbFBvbGljeShcbiAgICAgIHByb3BzLnJlbW92YWxQb2xpY3kgPz8gY2RrLlJlbW92YWxQb2xpY3kuREVTVFJPWSxcbiAgICApO1xuXG4gICAgdGhpcy5yZXBsaWNhdGlvbkluc3RhbmNlQXJuID0gdGhpcy5jZm5SZXBsaWNhdGlvbkluc3RhbmNlLnJlZjtcbiAgfVxuXG4gIC8qKlxuICAgKiBBbGxvdyBpbmJvdW5kIGFjY2VzcyB0byB0aGUgcmVwbGljYXRpb24gaW5zdGFuY2Ugb24gYSBnaXZlbiBwb3J0IGZyb20gYSBwZWVyLlxuICAgKiBVc2VmdWwgd2hlbiB0aGUgc291cmNlIG9yIHRhcmdldCBkYXRhYmFzZSBzZWN1cml0eSBncm91cCBuZWVkcyB0byB0cnVzdCB0aGUgaW5zdGFuY2UuXG4gICAqL1xuICBhbGxvd0luYm91bmRGcm9tKHBlZXI6IGVjMi5JUGVlciwgcG9ydDogZWMyLlBvcnQsIGRlc2NyaXB0aW9uPzogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2VjdXJpdHlHcm91cCBpbnN0YW5jZW9mIGVjMi5TZWN1cml0eUdyb3VwKSB7XG4gICAgICB0aGlzLnNlY3VyaXR5R3JvdXAuYWRkSW5ncmVzc1J1bGUocGVlciwgcG9ydCwgZGVzY3JpcHRpb24gPz8gJ0FsbG93IERNUyByZXBsaWNhdGlvbiBpbnN0YW5jZScpO1xuICAgIH1cbiAgfVxufVxuIl19
@@ -0,0 +1,72 @@
1
+ import * as cdk from 'aws-cdk-lib';
2
+ import * as dms from 'aws-cdk-lib/aws-dms';
3
+ import { Construct } from 'constructs';
4
+ import { IDmsEndpoint } from './endpoint';
5
+ import { MigrationType } from './enums';
6
+ /** Props for {@link DmsReplicationTask}. */
7
+ export interface DmsReplicationTaskProps {
8
+ /** ARN of the replication instance to use. */
9
+ readonly replicationInstanceArn: string;
10
+ /** Source endpoint. */
11
+ readonly sourceEndpoint: IDmsEndpoint;
12
+ /** Target endpoint. */
13
+ readonly targetEndpoint: IDmsEndpoint;
14
+ /** The migration type. */
15
+ readonly migrationType: MigrationType;
16
+ /**
17
+ * Table mappings JSON string.
18
+ * Use {@link TableMappings} to build this, or provide a raw JSON string.
19
+ *
20
+ * @example
21
+ * tableMappings: new TableMappings().includeSchema('public').toJson()
22
+ */
23
+ readonly tableMappings: string;
24
+ /**
25
+ * Task settings JSON string.
26
+ * Use {@link TaskSettings} to build this, or provide a raw JSON string.
27
+ * A sensible default is applied if not provided.
28
+ */
29
+ readonly taskSettings?: string;
30
+ /**
31
+ * Logical name for the replication task.
32
+ * Auto-generated from the construct ID if not provided.
33
+ */
34
+ readonly replicationTaskIdentifier?: string;
35
+ /**
36
+ * CDC start time as an ISO-8601 string or Unix epoch number.
37
+ * Only valid when migrationType is CDC or FULL_LOAD_AND_CDC.
38
+ * Mutually exclusive with cdcStartPosition.
39
+ */
40
+ readonly cdcStartTime?: string;
41
+ /**
42
+ * CDC start position (log sequence number or similar).
43
+ * Only valid when migrationType is CDC or FULL_LOAD_AND_CDC.
44
+ * Mutually exclusive with cdcStartTime.
45
+ */
46
+ readonly cdcStartPosition?: string;
47
+ /**
48
+ * CDC stop position. The task stops once this position is reached.
49
+ * Only valid when migrationType is CDC or FULL_LOAD_AND_CDC.
50
+ */
51
+ readonly cdcStopPosition?: string;
52
+ /**
53
+ * Removal policy for this resource.
54
+ * @default cdk.RemovalPolicy.DESTROY
55
+ */
56
+ readonly removalPolicy?: cdk.RemovalPolicy;
57
+ /**
58
+ * Tags to apply to the task resource.
59
+ */
60
+ readonly tags?: cdk.CfnTag[];
61
+ }
62
+ /**
63
+ * A DMS replication task that ties a replication instance to a source and
64
+ * target endpoint and defines what data to migrate and how.
65
+ */
66
+ export declare class DmsReplicationTask extends Construct {
67
+ /** The underlying CloudFormation replication task resource. */
68
+ readonly cfnReplicationTask: dms.CfnReplicationTask;
69
+ /** ARN of the replication task. */
70
+ readonly replicationTaskArn: string;
71
+ constructor(scope: Construct, id: string, props: DmsReplicationTaskProps);
72
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.DmsReplicationTask = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const cdk = require("aws-cdk-lib");
7
+ const dms = require("aws-cdk-lib/aws-dms");
8
+ const constructs_1 = require("constructs");
9
+ const task_settings_1 = require("./task-settings");
10
+ /**
11
+ * A DMS replication task that ties a replication instance to a source and
12
+ * target endpoint and defines what data to migrate and how.
13
+ */
14
+ class DmsReplicationTask extends constructs_1.Construct {
15
+ constructor(scope, id, props) {
16
+ super(scope, id);
17
+ const taskIdentifier = props.replicationTaskIdentifier ??
18
+ cdk.Names.uniqueResourceName(this, { maxLength: 63 }).toLowerCase();
19
+ const taskSettings = props.taskSettings ?? new task_settings_1.TaskSettings().toJson();
20
+ // DMS expects cdcStartTime as a Unix epoch number (seconds since epoch)
21
+ let cdcStartTime;
22
+ if (props.cdcStartTime !== undefined) {
23
+ const parsed = Date.parse(props.cdcStartTime);
24
+ cdcStartTime = isNaN(parsed) ? Number(props.cdcStartTime) : Math.floor(parsed / 1000);
25
+ }
26
+ this.cfnReplicationTask = new dms.CfnReplicationTask(this, 'Resource', {
27
+ replicationInstanceArn: props.replicationInstanceArn,
28
+ sourceEndpointArn: props.sourceEndpoint.endpointArn,
29
+ targetEndpointArn: props.targetEndpoint.endpointArn,
30
+ migrationType: props.migrationType,
31
+ tableMappings: props.tableMappings,
32
+ replicationTaskSettings: taskSettings,
33
+ replicationTaskIdentifier: taskIdentifier,
34
+ cdcStartTime,
35
+ cdcStartPosition: props.cdcStartPosition,
36
+ cdcStopPosition: props.cdcStopPosition,
37
+ tags: props.tags,
38
+ });
39
+ this.cfnReplicationTask.applyRemovalPolicy(props.removalPolicy ?? cdk.RemovalPolicy.DESTROY);
40
+ this.replicationTaskArn = this.cfnReplicationTask.ref;
41
+ }
42
+ }
43
+ exports.DmsReplicationTask = DmsReplicationTask;
44
+ _a = JSII_RTTI_SYMBOL_1;
45
+ DmsReplicationTask[_a] = { fqn: "cdk-dms-replication.DmsReplicationTask", version: "0.0.0" };
46
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwbGljYXRpb24tdGFzay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXBsaWNhdGlvbi10YXNrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQywyQ0FBdUM7QUFJdkMsbURBQStDO0FBc0UvQzs7O0dBR0c7QUFDSCxNQUFhLGtCQUFtQixTQUFRLHNCQUFTO0lBTy9DLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBOEI7UUFDdEUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLGNBQWMsR0FDbEIsS0FBSyxDQUFDLHlCQUF5QjtZQUMvQixHQUFHLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBRXRFLE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxZQUFZLElBQUksSUFBSSw0QkFBWSxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7UUFFdkUsd0VBQXdFO1FBQ3hFLElBQUksWUFBZ0MsQ0FBQztRQUNyQyxJQUFJLEtBQUssQ0FBQyxZQUFZLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDckMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDOUMsWUFBWSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLENBQUM7UUFDeEYsQ0FBQztRQUVELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFO1lBQ3JFLHNCQUFzQixFQUFFLEtBQUssQ0FBQyxzQkFBc0I7WUFDcEQsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLGNBQWMsQ0FBQyxXQUFXO1lBQ25ELGlCQUFpQixFQUFFLEtBQUssQ0FBQyxjQUFjLENBQUMsV0FBVztZQUNuRCxhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWE7WUFDbEMsYUFBYSxFQUFFLEtBQUssQ0FBQyxhQUFhO1lBQ2xDLHVCQUF1QixFQUFFLFlBQVk7WUFDckMseUJBQXlCLEVBQUUsY0FBYztZQUN6QyxZQUFZO1lBQ1osZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGdCQUFnQjtZQUN4QyxlQUFlLEVBQUUsS0FBSyxDQUFDLGVBQWU7WUFDdEMsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO1NBQ2pCLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxrQkFBa0IsQ0FDeEMsS0FBSyxDQUFDLGFBQWEsSUFBSSxHQUFHLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FDakQsQ0FBQztRQUVGLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDO0lBQ3hELENBQUM7O0FBMUNILGdEQTJDQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNkayBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBkbXMgZnJvbSAnYXdzLWNkay1saWIvYXdzLWRtcyc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IElEbXNFbmRwb2ludCB9IGZyb20gJy4vZW5kcG9pbnQnO1xuaW1wb3J0IHsgTWlncmF0aW9uVHlwZSB9IGZyb20gJy4vZW51bXMnO1xuaW1wb3J0IHsgVGFibGVNYXBwaW5ncyB9IGZyb20gJy4vdGFibGUtbWFwcGluZ3MnO1xuaW1wb3J0IHsgVGFza1NldHRpbmdzIH0gZnJvbSAnLi90YXNrLXNldHRpbmdzJztcblxuLyoqIFByb3BzIGZvciB7QGxpbmsgRG1zUmVwbGljYXRpb25UYXNrfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRG1zUmVwbGljYXRpb25UYXNrUHJvcHMge1xuICAvKiogQVJOIG9mIHRoZSByZXBsaWNhdGlvbiBpbnN0YW5jZSB0byB1c2UuICovXG4gIHJlYWRvbmx5IHJlcGxpY2F0aW9uSW5zdGFuY2VBcm46IHN0cmluZztcblxuICAvKiogU291cmNlIGVuZHBvaW50LiAqL1xuICByZWFkb25seSBzb3VyY2VFbmRwb2ludDogSURtc0VuZHBvaW50O1xuXG4gIC8qKiBUYXJnZXQgZW5kcG9pbnQuICovXG4gIHJlYWRvbmx5IHRhcmdldEVuZHBvaW50OiBJRG1zRW5kcG9pbnQ7XG5cbiAgLyoqIFRoZSBtaWdyYXRpb24gdHlwZS4gKi9cbiAgcmVhZG9ubHkgbWlncmF0aW9uVHlwZTogTWlncmF0aW9uVHlwZTtcblxuICAvKipcbiAgICogVGFibGUgbWFwcGluZ3MgSlNPTiBzdHJpbmcuXG4gICAqIFVzZSB7QGxpbmsgVGFibGVNYXBwaW5nc30gdG8gYnVpbGQgdGhpcywgb3IgcHJvdmlkZSBhIHJhdyBKU09OIHN0cmluZy5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogdGFibGVNYXBwaW5nczogbmV3IFRhYmxlTWFwcGluZ3MoKS5pbmNsdWRlU2NoZW1hKCdwdWJsaWMnKS50b0pzb24oKVxuICAgKi9cbiAgcmVhZG9ubHkgdGFibGVNYXBwaW5nczogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUYXNrIHNldHRpbmdzIEpTT04gc3RyaW5nLlxuICAgKiBVc2Uge0BsaW5rIFRhc2tTZXR0aW5nc30gdG8gYnVpbGQgdGhpcywgb3IgcHJvdmlkZSBhIHJhdyBKU09OIHN0cmluZy5cbiAgICogQSBzZW5zaWJsZSBkZWZhdWx0IGlzIGFwcGxpZWQgaWYgbm90IHByb3ZpZGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgdGFza1NldHRpbmdzPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBMb2dpY2FsIG5hbWUgZm9yIHRoZSByZXBsaWNhdGlvbiB0YXNrLlxuICAgKiBBdXRvLWdlbmVyYXRlZCBmcm9tIHRoZSBjb25zdHJ1Y3QgSUQgaWYgbm90IHByb3ZpZGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVwbGljYXRpb25UYXNrSWRlbnRpZmllcj86IHN0cmluZztcblxuICAvKipcbiAgICogQ0RDIHN0YXJ0IHRpbWUgYXMgYW4gSVNPLTg2MDEgc3RyaW5nIG9yIFVuaXggZXBvY2ggbnVtYmVyLlxuICAgKiBPbmx5IHZhbGlkIHdoZW4gbWlncmF0aW9uVHlwZSBpcyBDREMgb3IgRlVMTF9MT0FEX0FORF9DREMuXG4gICAqIE11dHVhbGx5IGV4Y2x1c2l2ZSB3aXRoIGNkY1N0YXJ0UG9zaXRpb24uXG4gICAqL1xuICByZWFkb25seSBjZGNTdGFydFRpbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIENEQyBzdGFydCBwb3NpdGlvbiAobG9nIHNlcXVlbmNlIG51bWJlciBvciBzaW1pbGFyKS5cbiAgICogT25seSB2YWxpZCB3aGVuIG1pZ3JhdGlvblR5cGUgaXMgQ0RDIG9yIEZVTExfTE9BRF9BTkRfQ0RDLlxuICAgKiBNdXR1YWxseSBleGNsdXNpdmUgd2l0aCBjZGNTdGFydFRpbWUuXG4gICAqL1xuICByZWFkb25seSBjZGNTdGFydFBvc2l0aW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBDREMgc3RvcCBwb3NpdGlvbi4gIFRoZSB0YXNrIHN0b3BzIG9uY2UgdGhpcyBwb3NpdGlvbiBpcyByZWFjaGVkLlxuICAgKiBPbmx5IHZhbGlkIHdoZW4gbWlncmF0aW9uVHlwZSBpcyBDREMgb3IgRlVMTF9MT0FEX0FORF9DREMuXG4gICAqL1xuICByZWFkb25seSBjZGNTdG9wUG9zaXRpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFJlbW92YWwgcG9saWN5IGZvciB0aGlzIHJlc291cmNlLlxuICAgKiBAZGVmYXVsdCBjZGsuUmVtb3ZhbFBvbGljeS5ERVNUUk9ZXG4gICAqL1xuICByZWFkb25seSByZW1vdmFsUG9saWN5PzogY2RrLlJlbW92YWxQb2xpY3k7XG5cbiAgLyoqXG4gICAqIFRhZ3MgdG8gYXBwbHkgdG8gdGhlIHRhc2sgcmVzb3VyY2UuXG4gICAqL1xuICByZWFkb25seSB0YWdzPzogY2RrLkNmblRhZ1tdO1xufVxuXG4vKipcbiAqIEEgRE1TIHJlcGxpY2F0aW9uIHRhc2sgdGhhdCB0aWVzIGEgcmVwbGljYXRpb24gaW5zdGFuY2UgdG8gYSBzb3VyY2UgYW5kXG4gKiB0YXJnZXQgZW5kcG9pbnQgYW5kIGRlZmluZXMgd2hhdCBkYXRhIHRvIG1pZ3JhdGUgYW5kIGhvdy5cbiAqL1xuZXhwb3J0IGNsYXNzIERtc1JlcGxpY2F0aW9uVGFzayBleHRlbmRzIENvbnN0cnVjdCB7XG4gIC8qKiBUaGUgdW5kZXJseWluZyBDbG91ZEZvcm1hdGlvbiByZXBsaWNhdGlvbiB0YXNrIHJlc291cmNlLiAqL1xuICByZWFkb25seSBjZm5SZXBsaWNhdGlvblRhc2s6IGRtcy5DZm5SZXBsaWNhdGlvblRhc2s7XG5cbiAgLyoqIEFSTiBvZiB0aGUgcmVwbGljYXRpb24gdGFzay4gKi9cbiAgcmVhZG9ubHkgcmVwbGljYXRpb25UYXNrQXJuOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IERtc1JlcGxpY2F0aW9uVGFza1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGNvbnN0IHRhc2tJZGVudGlmaWVyID1cbiAgICAgIHByb3BzLnJlcGxpY2F0aW9uVGFza0lkZW50aWZpZXIgPz9cbiAgICAgIGNkay5OYW1lcy51bmlxdWVSZXNvdXJjZU5hbWUodGhpcywgeyBtYXhMZW5ndGg6IDYzIH0pLnRvTG93ZXJDYXNlKCk7XG5cbiAgICBjb25zdCB0YXNrU2V0dGluZ3MgPSBwcm9wcy50YXNrU2V0dGluZ3MgPz8gbmV3IFRhc2tTZXR0aW5ncygpLnRvSnNvbigpO1xuXG4gICAgLy8gRE1TIGV4cGVjdHMgY2RjU3RhcnRUaW1lIGFzIGEgVW5peCBlcG9jaCBudW1iZXIgKHNlY29uZHMgc2luY2UgZXBvY2gpXG4gICAgbGV0IGNkY1N0YXJ0VGltZTogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgIGlmIChwcm9wcy5jZGNTdGFydFRpbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgcGFyc2VkID0gRGF0ZS5wYXJzZShwcm9wcy5jZGNTdGFydFRpbWUpO1xuICAgICAgY2RjU3RhcnRUaW1lID0gaXNOYU4ocGFyc2VkKSA/IE51bWJlcihwcm9wcy5jZGNTdGFydFRpbWUpIDogTWF0aC5mbG9vcihwYXJzZWQgLyAxMDAwKTtcbiAgICB9XG5cbiAgICB0aGlzLmNmblJlcGxpY2F0aW9uVGFzayA9IG5ldyBkbXMuQ2ZuUmVwbGljYXRpb25UYXNrKHRoaXMsICdSZXNvdXJjZScsIHtcbiAgICAgIHJlcGxpY2F0aW9uSW5zdGFuY2VBcm46IHByb3BzLnJlcGxpY2F0aW9uSW5zdGFuY2VBcm4sXG4gICAgICBzb3VyY2VFbmRwb2ludEFybjogcHJvcHMuc291cmNlRW5kcG9pbnQuZW5kcG9pbnRBcm4sXG4gICAgICB0YXJnZXRFbmRwb2ludEFybjogcHJvcHMudGFyZ2V0RW5kcG9pbnQuZW5kcG9pbnRBcm4sXG4gICAgICBtaWdyYXRpb25UeXBlOiBwcm9wcy5taWdyYXRpb25UeXBlLFxuICAgICAgdGFibGVNYXBwaW5nczogcHJvcHMudGFibGVNYXBwaW5ncyxcbiAgICAgIHJlcGxpY2F0aW9uVGFza1NldHRpbmdzOiB0YXNrU2V0dGluZ3MsXG4gICAgICByZXBsaWNhdGlvblRhc2tJZGVudGlmaWVyOiB0YXNrSWRlbnRpZmllcixcbiAgICAgIGNkY1N0YXJ0VGltZSxcbiAgICAgIGNkY1N0YXJ0UG9zaXRpb246IHByb3BzLmNkY1N0YXJ0UG9zaXRpb24sXG4gICAgICBjZGNTdG9wUG9zaXRpb246IHByb3BzLmNkY1N0b3BQb3NpdGlvbixcbiAgICAgIHRhZ3M6IHByb3BzLnRhZ3MsXG4gICAgfSk7XG5cbiAgICB0aGlzLmNmblJlcGxpY2F0aW9uVGFzay5hcHBseVJlbW92YWxQb2xpY3koXG4gICAgICBwcm9wcy5yZW1vdmFsUG9saWN5ID8/IGNkay5SZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAgKTtcblxuICAgIHRoaXMucmVwbGljYXRpb25UYXNrQXJuID0gdGhpcy5jZm5SZXBsaWNhdGlvblRhc2sucmVmO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,196 @@
1
+ import * as cdk from 'aws-cdk-lib';
2
+ import * as dms from 'aws-cdk-lib/aws-dms';
3
+ import * as ec2 from 'aws-cdk-lib/aws-ec2';
4
+ import * as iam from 'aws-cdk-lib/aws-iam';
5
+ import * as kms from 'aws-cdk-lib/aws-kms';
6
+ import * as logs from 'aws-cdk-lib/aws-logs';
7
+ import { Construct } from 'constructs';
8
+ import { IDmsEndpoint } from './endpoint';
9
+ import { MigrationType } from './enums';
10
+ import { SourceEndpointOptions, TargetEndpointOptions } from './migration-pipeline';
11
+ /** Props for {@link DmsServerlessPipeline}. */
12
+ export interface DmsServerlessPipelineProps {
13
+ /**
14
+ * VPC in which to place the serverless replication config.
15
+ * The config is placed in private subnets.
16
+ */
17
+ readonly vpc: ec2.IVpc;
18
+ /**
19
+ * Subnet selection for the replication subnet group.
20
+ * @default private subnets with egress
21
+ */
22
+ readonly vpcSubnets?: ec2.SubnetSelection;
23
+ /**
24
+ * Security groups to attach to the serverless replication config.
25
+ * A new security group is created if none are provided.
26
+ */
27
+ readonly securityGroups?: ec2.ISecurityGroup[];
28
+ /**
29
+ * Maximum number of DMS Capacity Units (DCUs) the serverless replication may
30
+ * scale up to.
31
+ *
32
+ * Valid values: 1, 2, 4, 8, 16, 32, 64, 128, 192, 256, 384.
33
+ */
34
+ readonly maxCapacityUnits: number;
35
+ /**
36
+ * Minimum number of DCUs DMS will provision at start-up.
37
+ * @default DMS auto-determines based on workload
38
+ */
39
+ readonly minCapacityUnits?: number;
40
+ /**
41
+ * Whether the serverless replication is Multi-AZ.
42
+ * @default false
43
+ */
44
+ readonly multiAz?: boolean;
45
+ /**
46
+ * Preferred maintenance window, e.g. "sun:04:00-sun:04:30".
47
+ */
48
+ readonly preferredMaintenanceWindow?: string;
49
+ /**
50
+ * KMS key used to encrypt replication storage at rest.
51
+ * A new key is created if not provided.
52
+ */
53
+ readonly kmsKey?: kms.IKey;
54
+ /**
55
+ * Source endpoint configuration.
56
+ * Provide this OR `existingSourceEndpoint` — not both.
57
+ */
58
+ readonly sourceEndpoint?: SourceEndpointOptions;
59
+ /**
60
+ * An existing {@link IDmsEndpoint} to use as the source.
61
+ * Provide this OR `sourceEndpoint` — not both.
62
+ */
63
+ readonly existingSourceEndpoint?: IDmsEndpoint;
64
+ /**
65
+ * Target endpoint configuration.
66
+ * Provide this OR `existingTargetEndpoint` — not both.
67
+ */
68
+ readonly targetEndpoint?: TargetEndpointOptions;
69
+ /**
70
+ * An existing {@link IDmsEndpoint} to use as the target.
71
+ * Provide this OR `targetEndpoint` — not both.
72
+ */
73
+ readonly existingTargetEndpoint?: IDmsEndpoint;
74
+ /** The type of migration to perform. */
75
+ readonly migrationType: MigrationType;
76
+ /**
77
+ * Table mappings JSON string.
78
+ * Use {@link TableMappings} to build this.
79
+ * Defaults to "include all tables in all schemas" if not provided.
80
+ */
81
+ readonly tableMappings?: string;
82
+ /**
83
+ * Replication settings JSON string (equivalent to task settings for classic DMS).
84
+ * Use {@link TaskSettings} to build this.
85
+ * Sensible defaults are applied by DMS if not provided.
86
+ *
87
+ * @remarks DMS Serverless does not support setting CDC start/stop positions
88
+ * via CloudFormation. To start replication from a specific LSN or timestamp
89
+ * after the replication config has been created, call the
90
+ * `StartReplication` API with `StartReplicationTaskType` set to
91
+ * `start-replication` and supply `CdcStartPosition` or `CdcStartTime`.
92
+ */
93
+ readonly taskSettings?: string;
94
+ /**
95
+ * Whether to create a CloudWatch log group for the replication config.
96
+ * @default true
97
+ */
98
+ readonly enableCloudWatchLogs?: boolean;
99
+ /**
100
+ * Retention period for the CloudWatch log group.
101
+ * @default logs.RetentionDays.ONE_MONTH
102
+ */
103
+ readonly logRetention?: logs.RetentionDays;
104
+ /**
105
+ * Whether to create the two account-level DMS service roles (`dms-vpc-role`
106
+ * and `dms-cloudwatch-logs-role`) required by DMS.
107
+ *
108
+ * Set to `false` if the roles already exist — for example, because a
109
+ * `DmsMigrationPipeline` or a prior manual deployment already created them.
110
+ * Attempting to create roles with the same name twice causes a CloudFormation
111
+ * `EntityAlreadyExists` error.
112
+ *
113
+ * @default true
114
+ */
115
+ readonly createDmsServiceRoles?: boolean;
116
+ /**
117
+ * Logical identifier for the replication config resource.
118
+ * @default unique name derived from the construct id
119
+ */
120
+ readonly replicationConfigIdentifier?: string;
121
+ /**
122
+ * Removal policy applied to all resources in the pipeline.
123
+ * @default cdk.RemovalPolicy.DESTROY
124
+ */
125
+ readonly removalPolicy?: cdk.RemovalPolicy;
126
+ }
127
+ /**
128
+ * An L3 CDK pattern construct that provisions a DMS Serverless replication
129
+ * pipeline:
130
+ *
131
+ * - **Replication config** — backed by `CfnReplicationConfig`; DMS auto-scales
132
+ * capacity between `minCapacityUnits` and `maxCapacityUnits`.
133
+ * - **Source endpoint** — supports every engine DMS supports.
134
+ * - **Target endpoint** — supports every engine DMS supports.
135
+ * - **Subnet group** — private subnet placement.
136
+ * - **KMS key** — storage encryption at rest (created if not provided).
137
+ * - **Security group** — dedicated group (created if not provided).
138
+ * - **IAM roles** — `dms-vpc-role` and `dms-cloudwatch-logs-role`.
139
+ * - **CloudWatch log group** — (optional) retains replication logs.
140
+ *
141
+ * > **CDC start/stop position limitation**: `CfnReplicationConfig` does not
142
+ * > expose `cdcStartTime` / `cdcStartPosition` / `cdcStopPosition`. To start
143
+ * > from a specific position, call the `StartReplication` API directly after
144
+ * > the config is created (e.g. from a Lambda custom resource or CLI).
145
+ *
146
+ * @example
147
+ * const pipeline = new DmsServerlessPipeline(this, 'ServerlessPipeline', {
148
+ * vpc,
149
+ * maxCapacityUnits: 8,
150
+ * migrationType: MigrationType.FULL_LOAD_AND_CDC,
151
+ * sourceEndpoint: {
152
+ * engine: EndpointEngine.MYSQL,
153
+ * serverName: 'mysql.example.com',
154
+ * port: 3306,
155
+ * username: 'dms_user',
156
+ * password: cdk.SecretValue.secretsManager('mysql-dms-secret'),
157
+ * },
158
+ * targetEndpoint: {
159
+ * engine: EndpointEngine.AURORA_POSTGRESQL,
160
+ * serverName: cluster.clusterEndpoint.hostname,
161
+ * port: 5432,
162
+ * username: 'dms_user',
163
+ * password: cdk.SecretValue.secretsManager('aurora-dms-secret'),
164
+ * },
165
+ * });
166
+ */
167
+ export declare class DmsServerlessPipeline extends Construct {
168
+ /** The underlying `CfnReplicationConfig` resource. */
169
+ readonly cfnReplicationConfig: dms.CfnReplicationConfig;
170
+ /** The ARN of the replication config. */
171
+ readonly replicationConfigArn: string;
172
+ /** The source endpoint used by this pipeline. */
173
+ readonly source: IDmsEndpoint;
174
+ /** The target endpoint used by this pipeline. */
175
+ readonly target: IDmsEndpoint;
176
+ /** The replication subnet group created for this pipeline. */
177
+ readonly subnetGroup: dms.CfnReplicationSubnetGroup;
178
+ /** The KMS key used for storage encryption. */
179
+ readonly encryptionKey: kms.IKey;
180
+ /** The security group attached to this pipeline. */
181
+ readonly securityGroup: ec2.ISecurityGroup;
182
+ /** CloudWatch log group for the replication config (if enableCloudWatchLogs is true). */
183
+ readonly logGroup?: logs.LogGroup;
184
+ /**
185
+ * IAM role that allows DMS to write to CloudWatch Logs.
186
+ * `undefined` when `createDmsServiceRoles` is `false`.
187
+ */
188
+ readonly dmsCloudWatchRole?: iam.Role;
189
+ /**
190
+ * IAM role that allows DMS to manage VPC resources (dms-vpc-role).
191
+ * `undefined` when `createDmsServiceRoles` is `false`.
192
+ */
193
+ readonly dmsVpcRole?: iam.Role;
194
+ constructor(scope: Construct, id: string, props: DmsServerlessPipelineProps);
195
+ private validateProps;
196
+ }