@ctxpipe/aws-cdk 1.0.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/README.md +108 -0
- package/lib/ctxpipe.d.ts +19 -0
- package/lib/ctxpipe.d.ts.map +1 -0
- package/lib/ctxpipe.js +232 -0
- package/lib/ctxpipe.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +6 -0
- package/lib/index.js.map +1 -0
- package/lib/internal/contracts.d.ts +119 -0
- package/lib/internal/contracts.d.ts.map +1 -0
- package/lib/internal/contracts.js +3 -0
- package/lib/internal/contracts.js.map +1 -0
- package/lib/internal/data-plane-construct.d.ts +7 -0
- package/lib/internal/data-plane-construct.d.ts.map +1 -0
- package/lib/internal/data-plane-construct.js +114 -0
- package/lib/internal/data-plane-construct.js.map +1 -0
- package/lib/internal/ingress-construct.d.ts +7 -0
- package/lib/internal/ingress-construct.d.ts.map +1 -0
- package/lib/internal/ingress-construct.js +94 -0
- package/lib/internal/ingress-construct.js.map +1 -0
- package/lib/internal/migrate-on-deploy-construct.d.ts +7 -0
- package/lib/internal/migrate-on-deploy-construct.d.ts.map +1 -0
- package/lib/internal/migrate-on-deploy-construct.js +208 -0
- package/lib/internal/migrate-on-deploy-construct.js.map +1 -0
- package/lib/internal/networking-construct.d.ts +7 -0
- package/lib/internal/networking-construct.d.ts.map +1 -0
- package/lib/internal/networking-construct.js +112 -0
- package/lib/internal/networking-construct.js.map +1 -0
- package/lib/internal/outputs-construct.d.ts +6 -0
- package/lib/internal/outputs-construct.d.ts.map +1 -0
- package/lib/internal/outputs-construct.js +65 -0
- package/lib/internal/outputs-construct.js.map +1 -0
- package/lib/internal/secrets-construct.d.ts +7 -0
- package/lib/internal/secrets-construct.d.ts.map +1 -0
- package/lib/internal/secrets-construct.js +211 -0
- package/lib/internal/secrets-construct.js.map +1 -0
- package/lib/internal/services-construct.d.ts +7 -0
- package/lib/internal/services-construct.d.ts.map +1 -0
- package/lib/internal/services-construct.js +123 -0
- package/lib/internal/services-construct.js.map +1 -0
- package/lib/internal/task-definitions-construct.d.ts +8 -0
- package/lib/internal/task-definitions-construct.d.ts.map +1 -0
- package/lib/internal/task-definitions-construct.js +204 -0
- package/lib/internal/task-definitions-construct.js.map +1 -0
- package/lib/pinned-service-image-tag.d.ts +7 -0
- package/lib/pinned-service-image-tag.d.ts.map +1 -0
- package/lib/pinned-service-image-tag.js +11 -0
- package/lib/pinned-service-image-tag.js.map +1 -0
- package/lib/types.d.ts +51 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +3 -0
- package/lib/types.js.map +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# @ctxpipe/aws-cdk
|
|
2
|
+
|
|
3
|
+
TypeScript AWS CDK library for deploying ctxpipe self-host infrastructure with one high-level construct: `CtxPipe`.
|
|
4
|
+
|
|
5
|
+
## Quickstart
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import * as cdk from "aws-cdk-lib";
|
|
9
|
+
import { CtxPipe } from "@ctxpipe/aws-cdk";
|
|
10
|
+
|
|
11
|
+
const app = new cdk.App();
|
|
12
|
+
const stack = new cdk.Stack(app, "CtxPipeStack");
|
|
13
|
+
|
|
14
|
+
new CtxPipe(stack, "CtxPipe", {
|
|
15
|
+
orgSlug: "acme",
|
|
16
|
+
customDomain: {
|
|
17
|
+
domainName: "app.example.com",
|
|
18
|
+
hostedZoneId: "Z0123456789ABCDEF",
|
|
19
|
+
},
|
|
20
|
+
modelProvider: {
|
|
21
|
+
baseUrl: "https://api.openai.com/v1",
|
|
22
|
+
apiKey: cdk.SecretValue.unsafePlainText("replace-model-api-key"),
|
|
23
|
+
defaultModel: "gpt-4.1-mini",
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Deploy with your CDK app as usual (`cdk synth`, then `cdk deploy`).
|
|
29
|
+
|
|
30
|
+
## Required props
|
|
31
|
+
|
|
32
|
+
- `modelProvider`: OpenAI-compatible model endpoint, key, and model ID.
|
|
33
|
+
- `orgSlug`: organization slug used by the deployed instance. Neptune is single-graph per cluster, so this construct configures one org per stack.
|
|
34
|
+
- `customDomain`: provide `domainName` and `hostedZoneId` to set the public URL to `https://<domainName>` and add:
|
|
35
|
+
- ACM certificate for the domain (DNS validated in the provided hosted zone),
|
|
36
|
+
- Route53 DNS validation records required by ACM,
|
|
37
|
+
- Route53 ALB alias records,
|
|
38
|
+
- HTTPS listener on ALB,
|
|
39
|
+
- HTTP -> HTTPS redirect.
|
|
40
|
+
The same hosted zone ID is also used for SES domain identity and DKIM records.
|
|
41
|
+
|
|
42
|
+
## Optional props
|
|
43
|
+
|
|
44
|
+
- `connectorSecrets`: deployment-wide connector secrets (GitHub/Atlassian). Omit for first boot if connectors are not configured yet.
|
|
45
|
+
- `serviceImageTag`: optional — one GHCR tag for every service image (backend, worker, UI, codesearch, migrate). When omitted, defaults to the commit SHA embedded at package build time (aligned with GHCR `:sha` tags for that commit), or `latest` if Git was unavailable when the package was built.
|
|
46
|
+
- `infraDefaults`: minor defaults such as AZ count, NAT gateways, DB name, backup retention days.
|
|
47
|
+
|
|
48
|
+
## What `CtxPipe` provisions
|
|
49
|
+
|
|
50
|
+
- VPC with public + private subnets and NAT egress.
|
|
51
|
+
- ECS cluster and Fargate services for backend, worker, ui, and codesearch.
|
|
52
|
+
- Service deployments use ECS deployment circuit breaker with automatic rollback.
|
|
53
|
+
- Deploy-time database migration as a one-off ECS Fargate task triggered by a CloudFormation custom resource before service deployment.
|
|
54
|
+
- Aurora PostgreSQL (private), Neptune cluster + instance (private), EFS (codesearch `/data`).
|
|
55
|
+
- Secrets Manager secrets for database URL, model provider, and optional connectors.
|
|
56
|
+
- SES domain identity + DKIM records + SMTP credentials in Secrets Manager for backend email delivery.
|
|
57
|
+
- Public ALB routing to backend only (UI/codesearch remain internal-only).
|
|
58
|
+
- Outputs for app URL and key secret ARNs.
|
|
59
|
+
- Backup defaults enabled for Aurora, Neptune, and EFS.
|
|
60
|
+
|
|
61
|
+
Runtime defaults injected by the construct include:
|
|
62
|
+
|
|
63
|
+
- `GRAPH_DB_PROVIDER=neptune`
|
|
64
|
+
- `GRAPH_DB_URI` from Neptune endpoint
|
|
65
|
+
- `GRAPH_DB_URI_<orgSlug>` from the same Neptune endpoint
|
|
66
|
+
- `UI_PROXY_URL=http://ui.ctxpipe.local:3002`
|
|
67
|
+
- `CODESEARCH_URL=http://codesearch.ctxpipe.local:3001`
|
|
68
|
+
- `AUTH_SECRET` generated in Secrets Manager and injected into backend/worker/codesearch/migrate tasks
|
|
69
|
+
- `DATABASE_URL` secret injected into backend/worker/codesearch tasks
|
|
70
|
+
- `SMTP_CONNECTION_URL` and `EMAIL_FROM_ADDRESS` injected into backend from SES SMTP credentials
|
|
71
|
+
- `EMAIL_FROM_ADDRESS` is always `ctxpipe-noreply@<hosted-zone-apex>`
|
|
72
|
+
|
|
73
|
+
## Deploy-time migrations
|
|
74
|
+
|
|
75
|
+
`CtxPipe` runs Postgres migrations automatically during `cdk deploy` by executing an internal one-off ECS task before the long-running ECS services are deployed or updated.
|
|
76
|
+
|
|
77
|
+
- This migration step is part of the construct internals; consumers do not need to run `ecs run-task` manually.
|
|
78
|
+
- A failed migration fails the CloudFormation deployment, preventing partially-updated services.
|
|
79
|
+
- The migration custom-resource flow is bounded by Lambda/CloudFormation timing limits (up to 15 minutes per deployment operation). If your migrations can exceed that window, run heavy schema/data backfills outside this deploy-time hook (for example with a separate migration workflow).
|
|
80
|
+
|
|
81
|
+
## Image-tag coupling note
|
|
82
|
+
|
|
83
|
+
Each `@ctxpipe/aws-cdk` npm release is built from a monorepo commit. GHCR publishes `ghcr.io/ctxpipe-ai/*` images tagged with that commit SHA on `main`. Published packages embed that SHA as the default image tag when `serviceImageTag` is omitted, so ECS task definitions stay aligned with the construct version you installed. Override `serviceImageTag` when you need a different registry tag (for example PR preview images).
|
|
84
|
+
|
|
85
|
+
## Environment checklist
|
|
86
|
+
|
|
87
|
+
### Customer-supplied (required)
|
|
88
|
+
|
|
89
|
+
- `AUTH_BASE_URL` (derived from `customDomain.domainName`)
|
|
90
|
+
- `MODEL_PROVIDER_URL`, `MODEL_PROVIDER_API_KEY`, and `MODEL_FAST_NAME` (provided through `modelProvider`)
|
|
91
|
+
|
|
92
|
+
### CDK-generated defaults
|
|
93
|
+
|
|
94
|
+
- `AUTH_SECRET` (Secrets Manager generated value)
|
|
95
|
+
- `DATABASE_URL` (Secrets Manager + Aurora endpoint)
|
|
96
|
+
- `GRAPH_DB_PROVIDER=neptune`
|
|
97
|
+
- `GRAPH_DB_URI` (Neptune endpoint)
|
|
98
|
+
- `GRAPH_DB_URI_<orgSlug>` (Neptune endpoint for the configured org slug)
|
|
99
|
+
- `UI_PROXY_URL` and `CODESEARCH_URL` (internal service DNS)
|
|
100
|
+
- `SMTP_CONNECTION_URL` and `EMAIL_FROM_ADDRESS` (SES SMTP + Secrets Manager)
|
|
101
|
+
|
|
102
|
+
Because Neptune is single-graph per cluster, this construct does not support multi-tenant self-hosting in one stack. Deploy separate stacks for separate org slugs.
|
|
103
|
+
|
|
104
|
+
### Optional second deploy (connector onboarding)
|
|
105
|
+
|
|
106
|
+
- `GITHUB_APP_ID`, `GITHUB_PRIVATE_KEY`, `GITHUB_WEBHOOK_SECRET`
|
|
107
|
+
- `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET`
|
|
108
|
+
- `ATLASSIAN_CLIENT_ID`, `ATLASSIAN_CLIENT_SECRET`
|
package/lib/ctxpipe.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type * as secretsmanager from "aws-cdk-lib/aws-secretsmanager";
|
|
2
|
+
import { Construct } from "constructs";
|
|
3
|
+
import type { CtxPipeProps } from "./types";
|
|
4
|
+
export declare class CtxPipe extends Construct {
|
|
5
|
+
readonly appUrl: string;
|
|
6
|
+
readonly databaseUrlSecret: secretsmanager.ISecret;
|
|
7
|
+
readonly modelProviderSecret: secretsmanager.ISecret;
|
|
8
|
+
readonly smtpSecret: secretsmanager.ISecret;
|
|
9
|
+
readonly connectorSecret?: secretsmanager.ISecret;
|
|
10
|
+
constructor(scope: Construct, id: string, props: CtxPipeProps);
|
|
11
|
+
private validateModelProvider;
|
|
12
|
+
private validateOrgSlug;
|
|
13
|
+
private resolveDefaults;
|
|
14
|
+
private resolveCustomDomain;
|
|
15
|
+
private resolveHostedZoneName;
|
|
16
|
+
private normalizeHostedZoneId;
|
|
17
|
+
private toHostedZoneApiId;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=ctxpipe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ctxpipe.d.ts","sourceRoot":"","sources":["../src/ctxpipe.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,cAAc,MAAM,gCAAgC,CAAC;AAEtE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAcvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAK5C,qBAAa,OAAQ,SAAQ,SAAS;IACpC,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,iBAAiB,EAAE,cAAc,CAAC,OAAO,CAAC;IAC1D,SAAgB,mBAAmB,EAAE,cAAc,CAAC,OAAO,CAAC;IAC5D,SAAgB,UAAU,EAAE,cAAc,CAAC,OAAO,CAAC;IACnD,SAAgB,eAAe,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC;gBAEtC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY;IA0EpE,OAAO,CAAC,qBAAqB;IAS7B,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,mBAAmB;IAsB3B,OAAO,CAAC,qBAAqB;IAiE7B,OAAO,CAAC,qBAAqB;IAM7B,OAAO,CAAC,iBAAiB;CAK1B"}
|
package/lib/ctxpipe.js
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.CtxPipe = void 0;
|
|
37
|
+
const cdk = __importStar(require("aws-cdk-lib"));
|
|
38
|
+
const acm = __importStar(require("aws-cdk-lib/aws-certificatemanager"));
|
|
39
|
+
const lambda = __importStar(require("aws-cdk-lib/aws-lambda"));
|
|
40
|
+
const route53 = __importStar(require("aws-cdk-lib/aws-route53"));
|
|
41
|
+
const cr = __importStar(require("aws-cdk-lib/custom-resources"));
|
|
42
|
+
const constructs_1 = require("constructs");
|
|
43
|
+
const pinned_service_image_tag_1 = require("./pinned-service-image-tag");
|
|
44
|
+
const data_plane_construct_1 = require("./internal/data-plane-construct");
|
|
45
|
+
const ingress_construct_1 = require("./internal/ingress-construct");
|
|
46
|
+
const migrate_on_deploy_construct_1 = require("./internal/migrate-on-deploy-construct");
|
|
47
|
+
const networking_construct_1 = require("./internal/networking-construct");
|
|
48
|
+
const outputs_construct_1 = require("./internal/outputs-construct");
|
|
49
|
+
const secrets_construct_1 = require("./internal/secrets-construct");
|
|
50
|
+
const services_construct_1 = require("./internal/services-construct");
|
|
51
|
+
const task_definitions_construct_1 = require("./internal/task-definitions-construct");
|
|
52
|
+
const DEFAULT_BACKUP_RETENTION_DAYS = 7;
|
|
53
|
+
const ORG_SLUG_PATTERN = /^[a-z0-9-]+$/;
|
|
54
|
+
class CtxPipe extends constructs_1.Construct {
|
|
55
|
+
appUrl;
|
|
56
|
+
databaseUrlSecret;
|
|
57
|
+
modelProviderSecret;
|
|
58
|
+
smtpSecret;
|
|
59
|
+
connectorSecret;
|
|
60
|
+
constructor(scope, id, props) {
|
|
61
|
+
super(scope, id);
|
|
62
|
+
this.validateOrgSlug(props);
|
|
63
|
+
this.validateModelProvider(props);
|
|
64
|
+
const resolvedCustomDomain = this.resolveCustomDomain(props);
|
|
65
|
+
const defaults = this.resolveDefaults(props, resolvedCustomDomain);
|
|
66
|
+
const networking = new networking_construct_1.NetworkingConstruct(this, "Networking", {
|
|
67
|
+
maxAzs: 2,
|
|
68
|
+
natGateways: 1,
|
|
69
|
+
});
|
|
70
|
+
const dataPlane = new data_plane_construct_1.DataPlaneConstruct(this, "DataPlane", {
|
|
71
|
+
networking: networking.resources,
|
|
72
|
+
defaults,
|
|
73
|
+
});
|
|
74
|
+
const secrets = new secrets_construct_1.SecretsConstruct(this, "Secrets", {
|
|
75
|
+
dataPlane: dataPlane.resources,
|
|
76
|
+
databaseName: defaults.databaseName,
|
|
77
|
+
modelProviderApiKey: props.modelProvider.apiKey,
|
|
78
|
+
hostedZone: resolvedCustomDomain.hostedZone,
|
|
79
|
+
connectorSecrets: props.connectorSecrets,
|
|
80
|
+
emailFromAddress: defaults.emailFromAddress,
|
|
81
|
+
});
|
|
82
|
+
const taskDefinitions = new task_definitions_construct_1.TaskDefinitionsConstruct(this, "TaskDefinitions", {
|
|
83
|
+
orgSlug: props.orgSlug,
|
|
84
|
+
networking: networking.resources,
|
|
85
|
+
dataPlane: dataPlane.resources,
|
|
86
|
+
secrets: secrets.resources,
|
|
87
|
+
customDomain: resolvedCustomDomain,
|
|
88
|
+
modelProviderBaseUrl: props.modelProvider.baseUrl,
|
|
89
|
+
modelProviderDefaultModel: props.modelProvider.defaultModel,
|
|
90
|
+
defaultImageTag: defaults.defaultImageTag,
|
|
91
|
+
});
|
|
92
|
+
const migrateOnDeploy = new migrate_on_deploy_construct_1.MigrateOnDeployConstruct(this, "MigrateOnDeploy", {
|
|
93
|
+
networking: networking.resources,
|
|
94
|
+
dataPlane: dataPlane.resources,
|
|
95
|
+
tasks: taskDefinitions.resources,
|
|
96
|
+
secrets: secrets.resources,
|
|
97
|
+
});
|
|
98
|
+
const services = new services_construct_1.ServicesConstruct(this, "Services", {
|
|
99
|
+
networking: networking.resources,
|
|
100
|
+
tasks: taskDefinitions.resources,
|
|
101
|
+
migrateDependency: migrateOnDeploy.resources.migrateResource,
|
|
102
|
+
});
|
|
103
|
+
const ingress = new ingress_construct_1.IngressConstruct(this, "Ingress", {
|
|
104
|
+
networking: networking.resources,
|
|
105
|
+
backendService: services.resources.backendService,
|
|
106
|
+
customDomain: resolvedCustomDomain,
|
|
107
|
+
});
|
|
108
|
+
this.databaseUrlSecret = secrets.resources.databaseUrlSecret;
|
|
109
|
+
this.modelProviderSecret = secrets.resources.modelProviderSecret;
|
|
110
|
+
this.smtpSecret = secrets.resources.smtpSecret;
|
|
111
|
+
this.connectorSecret = secrets.resources.connectorSecret;
|
|
112
|
+
this.appUrl = ingress.resources.appUrl;
|
|
113
|
+
new outputs_construct_1.OutputsConstruct(this, "Outputs", {
|
|
114
|
+
appUrl: this.appUrl,
|
|
115
|
+
albDnsName: networking.resources.alb.loadBalancerDnsName,
|
|
116
|
+
databaseUrlSecretArn: this.databaseUrlSecret.secretArn,
|
|
117
|
+
modelProviderSecretArn: this.modelProviderSecret.secretArn,
|
|
118
|
+
smtpSecretArn: this.smtpSecret.secretArn,
|
|
119
|
+
connectorSecretArn: this.connectorSecret?.secretArn,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
validateModelProvider(props) {
|
|
123
|
+
if (props.modelProvider.baseUrl.length === 0) {
|
|
124
|
+
throw new Error("modelProvider.baseUrl is required");
|
|
125
|
+
}
|
|
126
|
+
if (props.modelProvider.defaultModel.length === 0) {
|
|
127
|
+
throw new Error("modelProvider.defaultModel is required");
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
validateOrgSlug(props) {
|
|
131
|
+
const orgSlug = props.orgSlug.trim();
|
|
132
|
+
if (orgSlug.length === 0) {
|
|
133
|
+
throw new Error("orgSlug is required");
|
|
134
|
+
}
|
|
135
|
+
if (!ORG_SLUG_PATTERN.test(orgSlug)) {
|
|
136
|
+
throw new Error("orgSlug must contain only lowercase letters, numbers, or hyphens");
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
resolveDefaults(props, customDomain) {
|
|
140
|
+
const normalizedZoneName = customDomain.hostedZoneName.replace(/\.$/, "");
|
|
141
|
+
return {
|
|
142
|
+
databaseName: "ctxpipe",
|
|
143
|
+
backupRetentionDays: DEFAULT_BACKUP_RETENTION_DAYS,
|
|
144
|
+
defaultImageTag: pinned_service_image_tag_1.PINNED_SERVICE_IMAGE_TAG,
|
|
145
|
+
emailFromAddress: `ctxpipe-noreply@${normalizedZoneName}`,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
resolveCustomDomain(props) {
|
|
149
|
+
const hostedZoneName = this.resolveHostedZoneName(props.customDomain.hostedZoneId);
|
|
150
|
+
const hostedZone = route53.HostedZone.fromHostedZoneAttributes(this, "CustomDomainHostedZone", {
|
|
151
|
+
hostedZoneId: this.normalizeHostedZoneId(props.customDomain.hostedZoneId),
|
|
152
|
+
zoneName: hostedZoneName,
|
|
153
|
+
});
|
|
154
|
+
return {
|
|
155
|
+
...props.customDomain,
|
|
156
|
+
hostedZone,
|
|
157
|
+
hostedZoneName,
|
|
158
|
+
certificate: new acm.Certificate(this, "CustomDomainCertificate", {
|
|
159
|
+
domainName: props.customDomain.domainName,
|
|
160
|
+
validation: acm.CertificateValidation.fromDns(hostedZone),
|
|
161
|
+
}),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
resolveHostedZoneName(hostedZoneId) {
|
|
165
|
+
const lookup = new cr.AwsCustomResource(this, "HostedZoneLookup", {
|
|
166
|
+
onCreate: {
|
|
167
|
+
service: "Route53",
|
|
168
|
+
action: "getHostedZone",
|
|
169
|
+
parameters: {
|
|
170
|
+
Id: this.toHostedZoneApiId(hostedZoneId),
|
|
171
|
+
},
|
|
172
|
+
physicalResourceId: cr.PhysicalResourceId.of(`route53-hosted-zone-${this.normalizeHostedZoneId(hostedZoneId)}`),
|
|
173
|
+
},
|
|
174
|
+
onUpdate: {
|
|
175
|
+
service: "Route53",
|
|
176
|
+
action: "getHostedZone",
|
|
177
|
+
parameters: {
|
|
178
|
+
Id: this.toHostedZoneApiId(hostedZoneId),
|
|
179
|
+
},
|
|
180
|
+
physicalResourceId: cr.PhysicalResourceId.of(`route53-hosted-zone-${this.normalizeHostedZoneId(hostedZoneId)}`),
|
|
181
|
+
},
|
|
182
|
+
policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
|
|
183
|
+
resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE,
|
|
184
|
+
}),
|
|
185
|
+
installLatestAwsSdk: false,
|
|
186
|
+
});
|
|
187
|
+
const normalizeFunction = new lambda.Function(this, "HostedZoneNameNormalizeFunction", {
|
|
188
|
+
runtime: lambda.Runtime.NODEJS_20_X,
|
|
189
|
+
handler: "index.handler",
|
|
190
|
+
timeout: cdk.Duration.seconds(15),
|
|
191
|
+
code: lambda.Code.fromInline(`
|
|
192
|
+
exports.handler = async (event) => {
|
|
193
|
+
const physicalId = event.PhysicalResourceId || "hosted-zone-name-normalized";
|
|
194
|
+
if (event.RequestType === "Delete") {
|
|
195
|
+
return { PhysicalResourceId: physicalId };
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const rawName = String(event.ResourceProperties.HostedZoneName || "");
|
|
199
|
+
const normalizedName = rawName.replace(/\\.$/, "");
|
|
200
|
+
return {
|
|
201
|
+
PhysicalResourceId: physicalId,
|
|
202
|
+
Data: {
|
|
203
|
+
HostedZoneName: normalizedName
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
};
|
|
207
|
+
`),
|
|
208
|
+
});
|
|
209
|
+
const normalizeProvider = new cr.Provider(this, "HostedZoneNameNormalizeProvider", {
|
|
210
|
+
onEventHandler: normalizeFunction,
|
|
211
|
+
});
|
|
212
|
+
const normalizeResource = new cdk.CustomResource(this, "HostedZoneNameNormalize", {
|
|
213
|
+
serviceToken: normalizeProvider.serviceToken,
|
|
214
|
+
properties: {
|
|
215
|
+
HostedZoneName: lookup.getResponseField("HostedZone.Name"),
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
return normalizeResource.getAttString("HostedZoneName");
|
|
219
|
+
}
|
|
220
|
+
normalizeHostedZoneId(hostedZoneId) {
|
|
221
|
+
return hostedZoneId.startsWith("/hostedzone/")
|
|
222
|
+
? hostedZoneId.slice("/hostedzone/".length)
|
|
223
|
+
: hostedZoneId;
|
|
224
|
+
}
|
|
225
|
+
toHostedZoneApiId(hostedZoneId) {
|
|
226
|
+
return hostedZoneId.startsWith("/hostedzone/")
|
|
227
|
+
? hostedZoneId
|
|
228
|
+
: `/hostedzone/${hostedZoneId}`;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
exports.CtxPipe = CtxPipe;
|
|
232
|
+
//# sourceMappingURL=ctxpipe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ctxpipe.js","sourceRoot":"","sources":["../src/ctxpipe.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EACV,4BAA4B,EAC5B,wBAAwB,EACxB,yBAAyB,EACzB,YAAY,GACb,MAAM,SAAS,CAAC"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CtxPipe = void 0;
|
|
4
|
+
var ctxpipe_1 = require("./ctxpipe");
|
|
5
|
+
Object.defineProperty(exports, "CtxPipe", { enumerable: true, get: function () { return ctxpipe_1.CtxPipe; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,qCAAoC;AAA3B,kGAAA,OAAO,OAAA"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type * as cdk from "aws-cdk-lib";
|
|
2
|
+
import type * as acm from "aws-cdk-lib/aws-certificatemanager";
|
|
3
|
+
import type * as ec2 from "aws-cdk-lib/aws-ec2";
|
|
4
|
+
import type * as ecs from "aws-cdk-lib/aws-ecs";
|
|
5
|
+
import type * as efs from "aws-cdk-lib/aws-efs";
|
|
6
|
+
import type * as elbv2 from "aws-cdk-lib/aws-elasticloadbalancingv2";
|
|
7
|
+
import type * as neptune from "aws-cdk-lib/aws-neptune";
|
|
8
|
+
import type * as rds from "aws-cdk-lib/aws-rds";
|
|
9
|
+
import type * as route53 from "aws-cdk-lib/aws-route53";
|
|
10
|
+
import type * as secretsmanager from "aws-cdk-lib/aws-secretsmanager";
|
|
11
|
+
import type { IDependable } from "constructs";
|
|
12
|
+
import type { CtxPipeConnectorSecretsProps, CtxPipeCustomDomainProps } from "../types";
|
|
13
|
+
export interface ResolvedCtxPipeCustomDomainProps extends CtxPipeCustomDomainProps {
|
|
14
|
+
readonly hostedZone: route53.IHostedZone;
|
|
15
|
+
readonly hostedZoneName: string;
|
|
16
|
+
readonly certificate: acm.ICertificate;
|
|
17
|
+
}
|
|
18
|
+
export interface CtxPipeResolvedDefaults {
|
|
19
|
+
readonly databaseName: string;
|
|
20
|
+
readonly backupRetentionDays: number;
|
|
21
|
+
readonly defaultImageTag: string;
|
|
22
|
+
readonly emailFromAddress: string;
|
|
23
|
+
}
|
|
24
|
+
export interface NetworkingResources {
|
|
25
|
+
readonly vpc: ec2.Vpc;
|
|
26
|
+
readonly appSecurityGroup: ec2.SecurityGroup;
|
|
27
|
+
readonly dbSecurityGroup: ec2.SecurityGroup;
|
|
28
|
+
readonly neptuneSecurityGroup: ec2.SecurityGroup;
|
|
29
|
+
readonly efsSecurityGroup: ec2.SecurityGroup;
|
|
30
|
+
readonly cluster: ecs.Cluster;
|
|
31
|
+
readonly alb: elbv2.ApplicationLoadBalancer;
|
|
32
|
+
readonly httpListener: elbv2.ApplicationListener;
|
|
33
|
+
}
|
|
34
|
+
export interface DataPlaneResources {
|
|
35
|
+
readonly dbCluster: rds.DatabaseCluster;
|
|
36
|
+
readonly dbCredentialsSecret: secretsmanager.Secret;
|
|
37
|
+
readonly neptuneCluster: neptune.CfnDBCluster;
|
|
38
|
+
readonly neptuneInstance: neptune.CfnDBInstance;
|
|
39
|
+
readonly codesearchFileSystem: efs.FileSystem;
|
|
40
|
+
readonly graphDbUri: string;
|
|
41
|
+
}
|
|
42
|
+
export interface SecretsResources {
|
|
43
|
+
readonly authSecret: secretsmanager.Secret;
|
|
44
|
+
readonly databaseUrlSecret: secretsmanager.Secret;
|
|
45
|
+
readonly modelProviderSecret: secretsmanager.Secret;
|
|
46
|
+
readonly smtpSecret: secretsmanager.Secret;
|
|
47
|
+
readonly connectorSecret?: secretsmanager.Secret;
|
|
48
|
+
readonly connectorEnv: Record<string, ecs.Secret>;
|
|
49
|
+
}
|
|
50
|
+
export interface TaskDefinitionsResources {
|
|
51
|
+
readonly backendTask: ecs.FargateTaskDefinition;
|
|
52
|
+
readonly workerTask: ecs.FargateTaskDefinition;
|
|
53
|
+
readonly uiTask: ecs.FargateTaskDefinition;
|
|
54
|
+
readonly codesearchTask: ecs.FargateTaskDefinition;
|
|
55
|
+
readonly migrateTask: ecs.FargateTaskDefinition;
|
|
56
|
+
}
|
|
57
|
+
export interface ServiceResources {
|
|
58
|
+
readonly backendService: ecs.FargateService;
|
|
59
|
+
readonly workerService: ecs.FargateService;
|
|
60
|
+
readonly uiService: ecs.FargateService;
|
|
61
|
+
readonly codesearchService: ecs.FargateService;
|
|
62
|
+
}
|
|
63
|
+
export interface IngressResources {
|
|
64
|
+
readonly appUrl: string;
|
|
65
|
+
}
|
|
66
|
+
export interface MigrateOnDeployResources {
|
|
67
|
+
readonly migrateResource: cdk.CustomResource;
|
|
68
|
+
}
|
|
69
|
+
export interface NetworkingConstructProps {
|
|
70
|
+
readonly maxAzs: number;
|
|
71
|
+
readonly natGateways: number;
|
|
72
|
+
}
|
|
73
|
+
export interface DataPlaneConstructProps {
|
|
74
|
+
readonly networking: NetworkingResources;
|
|
75
|
+
readonly defaults: CtxPipeResolvedDefaults;
|
|
76
|
+
}
|
|
77
|
+
export interface SecretsConstructProps {
|
|
78
|
+
readonly dataPlane: DataPlaneResources;
|
|
79
|
+
readonly databaseName: string;
|
|
80
|
+
readonly modelProviderApiKey: cdk.SecretValue;
|
|
81
|
+
readonly hostedZone: route53.IHostedZone;
|
|
82
|
+
readonly connectorSecrets?: CtxPipeConnectorSecretsProps;
|
|
83
|
+
readonly emailFromAddress: string;
|
|
84
|
+
}
|
|
85
|
+
export interface TaskDefinitionsConstructProps {
|
|
86
|
+
readonly orgSlug: string;
|
|
87
|
+
readonly networking: NetworkingResources;
|
|
88
|
+
readonly dataPlane: DataPlaneResources;
|
|
89
|
+
readonly secrets: SecretsResources;
|
|
90
|
+
readonly customDomain: ResolvedCtxPipeCustomDomainProps;
|
|
91
|
+
readonly modelProviderBaseUrl: string;
|
|
92
|
+
readonly modelProviderDefaultModel: string;
|
|
93
|
+
readonly defaultImageTag: string;
|
|
94
|
+
}
|
|
95
|
+
export interface ServicesConstructProps {
|
|
96
|
+
readonly networking: NetworkingResources;
|
|
97
|
+
readonly tasks: TaskDefinitionsResources;
|
|
98
|
+
readonly migrateDependency?: IDependable;
|
|
99
|
+
}
|
|
100
|
+
export interface IngressConstructProps {
|
|
101
|
+
readonly networking: NetworkingResources;
|
|
102
|
+
readonly backendService: ecs.FargateService;
|
|
103
|
+
readonly customDomain: ResolvedCtxPipeCustomDomainProps;
|
|
104
|
+
}
|
|
105
|
+
export interface MigrateOnDeployConstructProps {
|
|
106
|
+
readonly networking: NetworkingResources;
|
|
107
|
+
readonly dataPlane: DataPlaneResources;
|
|
108
|
+
readonly tasks: TaskDefinitionsResources;
|
|
109
|
+
readonly secrets: SecretsResources;
|
|
110
|
+
}
|
|
111
|
+
export interface OutputsConstructProps {
|
|
112
|
+
readonly appUrl: string;
|
|
113
|
+
readonly albDnsName: string;
|
|
114
|
+
readonly databaseUrlSecretArn: string;
|
|
115
|
+
readonly modelProviderSecretArn: string;
|
|
116
|
+
readonly smtpSecretArn: string;
|
|
117
|
+
readonly connectorSecretArn?: string;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/internal/contracts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../src/internal/contracts.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Construct } from "constructs";
|
|
2
|
+
import type { DataPlaneConstructProps, DataPlaneResources } from "./contracts";
|
|
3
|
+
export declare class DataPlaneConstruct extends Construct {
|
|
4
|
+
readonly resources: DataPlaneResources;
|
|
5
|
+
constructor(scope: Construct, id: string, props: DataPlaneConstructProps);
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=data-plane-construct.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-plane-construct.d.ts","sourceRoot":"","sources":["../../src/internal/data-plane-construct.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAE/E,qBAAa,kBAAmB,SAAQ,SAAS;IAC/C,SAAgB,SAAS,EAAE,kBAAkB,CAAC;gBAE3B,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,uBAAuB;CA6EhF"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.DataPlaneConstruct = void 0;
|
|
37
|
+
const cdk = __importStar(require("aws-cdk-lib"));
|
|
38
|
+
const ec2 = __importStar(require("aws-cdk-lib/aws-ec2"));
|
|
39
|
+
const efs = __importStar(require("aws-cdk-lib/aws-efs"));
|
|
40
|
+
const neptune = __importStar(require("aws-cdk-lib/aws-neptune"));
|
|
41
|
+
const rds = __importStar(require("aws-cdk-lib/aws-rds"));
|
|
42
|
+
const secretsmanager = __importStar(require("aws-cdk-lib/aws-secretsmanager"));
|
|
43
|
+
const constructs_1 = require("constructs");
|
|
44
|
+
class DataPlaneConstruct extends constructs_1.Construct {
|
|
45
|
+
resources;
|
|
46
|
+
constructor(scope, id, props) {
|
|
47
|
+
super(scope, id);
|
|
48
|
+
const dbCredentialsSecret = new secretsmanager.Secret(this, "DatabaseCredentialsSecret", {
|
|
49
|
+
generateSecretString: {
|
|
50
|
+
secretStringTemplate: JSON.stringify({ username: "ctxpipe" }),
|
|
51
|
+
generateStringKey: "password",
|
|
52
|
+
excludePunctuation: true,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
const dbCluster = new rds.DatabaseCluster(this, "Database", {
|
|
56
|
+
engine: rds.DatabaseClusterEngine.auroraPostgres({
|
|
57
|
+
version: rds.AuroraPostgresEngineVersion.of("16.4", "16"),
|
|
58
|
+
}),
|
|
59
|
+
credentials: rds.Credentials.fromSecret(dbCredentialsSecret),
|
|
60
|
+
defaultDatabaseName: props.defaults.databaseName,
|
|
61
|
+
writer: rds.ClusterInstance.provisioned("writer", {
|
|
62
|
+
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T4G, ec2.InstanceSize.MEDIUM),
|
|
63
|
+
}),
|
|
64
|
+
backup: {
|
|
65
|
+
retention: cdk.Duration.days(props.defaults.backupRetentionDays),
|
|
66
|
+
},
|
|
67
|
+
vpc: props.networking.vpc,
|
|
68
|
+
vpcSubnets: {
|
|
69
|
+
subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
|
|
70
|
+
},
|
|
71
|
+
securityGroups: [props.networking.dbSecurityGroup],
|
|
72
|
+
storageEncrypted: true,
|
|
73
|
+
removalPolicy: cdk.RemovalPolicy.SNAPSHOT,
|
|
74
|
+
});
|
|
75
|
+
const neptuneSubnetGroup = new neptune.CfnDBSubnetGroup(this, "NeptuneSubnetGroup", {
|
|
76
|
+
dbSubnetGroupDescription: "Private subnets for ctxpipe neptune",
|
|
77
|
+
subnetIds: props.networking.vpc.selectSubnets({
|
|
78
|
+
subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
|
|
79
|
+
}).subnetIds,
|
|
80
|
+
});
|
|
81
|
+
const neptuneCluster = new neptune.CfnDBCluster(this, "Neptune", {
|
|
82
|
+
dbSubnetGroupName: neptuneSubnetGroup.ref,
|
|
83
|
+
vpcSecurityGroupIds: [props.networking.neptuneSecurityGroup.securityGroupId],
|
|
84
|
+
backupRetentionPeriod: props.defaults.backupRetentionDays,
|
|
85
|
+
storageEncrypted: true,
|
|
86
|
+
iamAuthEnabled: false,
|
|
87
|
+
});
|
|
88
|
+
neptuneCluster.applyRemovalPolicy(cdk.RemovalPolicy.SNAPSHOT);
|
|
89
|
+
const neptuneInstance = new neptune.CfnDBInstance(this, "NeptuneInstance", {
|
|
90
|
+
dbClusterIdentifier: neptuneCluster.ref,
|
|
91
|
+
dbInstanceClass: "db.t4g.medium",
|
|
92
|
+
});
|
|
93
|
+
neptuneInstance.applyRemovalPolicy(cdk.RemovalPolicy.SNAPSHOT);
|
|
94
|
+
const codesearchFileSystem = new efs.FileSystem(this, "CodesearchEfs", {
|
|
95
|
+
vpc: props.networking.vpc,
|
|
96
|
+
encrypted: true,
|
|
97
|
+
securityGroup: props.networking.efsSecurityGroup,
|
|
98
|
+
removalPolicy: cdk.RemovalPolicy.RETAIN,
|
|
99
|
+
lifecyclePolicy: efs.LifecyclePolicy.AFTER_14_DAYS,
|
|
100
|
+
performanceMode: efs.PerformanceMode.GENERAL_PURPOSE,
|
|
101
|
+
});
|
|
102
|
+
const graphDbUri = cdk.Fn.join("", ["bolt+s://", neptuneCluster.attrEndpoint, ":8182"]);
|
|
103
|
+
this.resources = {
|
|
104
|
+
dbCluster,
|
|
105
|
+
dbCredentialsSecret,
|
|
106
|
+
neptuneCluster,
|
|
107
|
+
neptuneInstance,
|
|
108
|
+
codesearchFileSystem,
|
|
109
|
+
graphDbUri,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.DataPlaneConstruct = DataPlaneConstruct;
|
|
114
|
+
//# sourceMappingURL=data-plane-construct.js.map
|