@jaypie/constructs 1.1.52 → 1.1.54
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/dist/cjs/JaypieAccountLoggingBucket.d.ts +60 -0
- package/dist/cjs/JaypieDatadogBucket.d.ts +45 -0
- package/dist/cjs/JaypieDatadogForwarder.d.ts +76 -0
- package/dist/cjs/JaypieEventsRule.d.ts +45 -0
- package/dist/cjs/JaypieOrganizationTrail.d.ts +62 -0
- package/dist/cjs/constants.d.ts +151 -0
- package/dist/cjs/helpers/extendDatadogRole.d.ts +31 -0
- package/dist/cjs/helpers/index.d.ts +4 -0
- package/dist/cjs/helpers/isValidHostname.d.ts +1 -0
- package/dist/cjs/helpers/isValidSubdomain.d.ts +1 -0
- package/dist/cjs/helpers/mergeDomain.d.ts +1 -0
- package/dist/cjs/index.cjs +864 -157
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +6 -1
- package/dist/esm/JaypieAccountLoggingBucket.d.ts +60 -0
- package/dist/esm/JaypieDatadogBucket.d.ts +45 -0
- package/dist/esm/JaypieDatadogForwarder.d.ts +76 -0
- package/dist/esm/JaypieEventsRule.d.ts +45 -0
- package/dist/esm/JaypieOrganizationTrail.d.ts +62 -0
- package/dist/esm/constants.d.ts +151 -0
- package/dist/esm/helpers/extendDatadogRole.d.ts +31 -0
- package/dist/esm/helpers/index.d.ts +4 -0
- package/dist/esm/helpers/isValidHostname.d.ts +1 -0
- package/dist/esm/helpers/isValidSubdomain.d.ts +1 -0
- package/dist/esm/helpers/mergeDomain.d.ts +1 -0
- package/dist/esm/index.d.ts +6 -1
- package/dist/esm/index.js +711 -9
- package/dist/esm/index.js.map +1 -1
- package/package.json +2 -3
package/dist/esm/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { CDK as CDK$2, ConfigurationError, mergeDomain, isValidSubdomain, isValidHostname as isValidHostname$1 } from '@jaypie/cdk';
|
|
2
|
-
export { CDK } from '@jaypie/cdk';
|
|
3
|
-
import { Construct } from 'constructs';
|
|
4
1
|
import * as cdk from 'aws-cdk-lib';
|
|
5
|
-
import { Tags, Stack, Duration, RemovalPolicy, Fn, CfnOutput, SecretValue } from 'aws-cdk-lib';
|
|
2
|
+
import { Tags, Stack, Duration, RemovalPolicy, CfnStack, Fn, CfnOutput, SecretValue } from 'aws-cdk-lib';
|
|
3
|
+
import * as s3 from 'aws-cdk-lib/aws-s3';
|
|
4
|
+
import { Bucket, StorageClass, BucketAccessControl, EventType } from 'aws-cdk-lib/aws-s3';
|
|
5
|
+
import { Construct } from 'constructs';
|
|
6
6
|
import * as acm from 'aws-cdk-lib/aws-certificatemanager';
|
|
7
7
|
import * as apiGateway from 'aws-cdk-lib/aws-apigateway';
|
|
8
8
|
import * as route53 from 'aws-cdk-lib/aws-route53';
|
|
@@ -10,20 +10,242 @@ import { TxtRecord, NsRecord, MxRecord, CnameRecord, ARecord, RecordTarget, Host
|
|
|
10
10
|
import * as route53Targets from 'aws-cdk-lib/aws-route53-targets';
|
|
11
11
|
import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
|
|
12
12
|
import { DatadogLambda } from 'datadog-cdk-constructs-v2';
|
|
13
|
+
import { ConfigurationError } from '@jaypie/errors';
|
|
14
|
+
import { Role, PolicyStatement, Policy, FederatedPrincipal, Effect, ServicePrincipal, ManagedPolicy } from 'aws-cdk-lib/aws-iam';
|
|
13
15
|
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
14
16
|
import * as logDestinations from 'aws-cdk-lib/aws-logs-destinations';
|
|
15
|
-
import * as s3 from 'aws-cdk-lib/aws-s3';
|
|
16
17
|
import * as s3n from 'aws-cdk-lib/aws-s3-notifications';
|
|
18
|
+
import { LambdaDestination } from 'aws-cdk-lib/aws-s3-notifications';
|
|
17
19
|
import * as sqs from 'aws-cdk-lib/aws-sqs';
|
|
18
20
|
import * as lambdaEventSources from 'aws-cdk-lib/aws-lambda-event-sources';
|
|
19
|
-
import {
|
|
21
|
+
import { Rule, RuleTargetInput } from 'aws-cdk-lib/aws-events';
|
|
22
|
+
import { LambdaFunction } from 'aws-cdk-lib/aws-events-targets';
|
|
20
23
|
import { LogGroup, RetentionDays, FilterPattern } from 'aws-cdk-lib/aws-logs';
|
|
24
|
+
import { Trail, ReadWriteType } from 'aws-cdk-lib/aws-cloudtrail';
|
|
21
25
|
import { CfnPermissionSet, CfnAssignment } from 'aws-cdk-lib/aws-sso';
|
|
22
26
|
import { CfnApplication } from 'aws-cdk-lib/aws-sam';
|
|
23
|
-
import { ConfigurationError as ConfigurationError$1 } from '@jaypie/errors';
|
|
24
27
|
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
|
|
25
28
|
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
|
|
26
29
|
|
|
30
|
+
const CDK$2 = {
|
|
31
|
+
ACCOUNT: {
|
|
32
|
+
DEVELOPMENT: "development",
|
|
33
|
+
MANAGEMENT: "management",
|
|
34
|
+
OPERATIONS: "operations",
|
|
35
|
+
PRODUCTION: "production",
|
|
36
|
+
SANDBOX: "sandbox",
|
|
37
|
+
SECURITY: "security",
|
|
38
|
+
STAGE: "stage",
|
|
39
|
+
},
|
|
40
|
+
BUILD: {
|
|
41
|
+
CONFIG: {
|
|
42
|
+
ALL: "all",
|
|
43
|
+
API: "api",
|
|
44
|
+
INFRASTRUCTURE: "infrastructure",
|
|
45
|
+
NONE: "none",
|
|
46
|
+
WEB: "web",
|
|
47
|
+
},
|
|
48
|
+
PERSONAL: "personal",
|
|
49
|
+
/**
|
|
50
|
+
* @deprecated rename "ephemeral" to "personal" (since 2/24/2025)
|
|
51
|
+
*/
|
|
52
|
+
EPHEMERAL: "ephemeral",
|
|
53
|
+
/**
|
|
54
|
+
* @deprecated as even "ephemeral" builds have static assets (since 7/6/2024)
|
|
55
|
+
*/
|
|
56
|
+
STATIC: "static",
|
|
57
|
+
},
|
|
58
|
+
CREATION: {
|
|
59
|
+
CDK: "cdk",
|
|
60
|
+
CLOUDFORMATION_TEMPLATE: "template",
|
|
61
|
+
MANUAL: "manual",
|
|
62
|
+
},
|
|
63
|
+
DATADOG: {
|
|
64
|
+
SITE: "datadoghq.com",
|
|
65
|
+
LAYER: {
|
|
66
|
+
// https://docs.datadoghq.com/serverless/aws_lambda/installation/nodejs/?tab=awscdk
|
|
67
|
+
NODE: 127, // 127 on 9/12/2025
|
|
68
|
+
EXTENSION: 86, // 86 on 9/12/2025
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
DEFAULT: {
|
|
72
|
+
REGION: "us-east-1",
|
|
73
|
+
},
|
|
74
|
+
DNS: {
|
|
75
|
+
CONFIG: {
|
|
76
|
+
TTL: 300, // 5 minutes in seconds for Route53
|
|
77
|
+
},
|
|
78
|
+
RECORD: {
|
|
79
|
+
A: "A",
|
|
80
|
+
CNAME: "CNAME",
|
|
81
|
+
MX: "MX",
|
|
82
|
+
NS: "NS",
|
|
83
|
+
TXT: "TXT",
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
DURATION: {
|
|
87
|
+
EXPRESS_API: 30,
|
|
88
|
+
LAMBDA_MAXIMUM: 900,
|
|
89
|
+
LAMBDA_WORKER: 900,
|
|
90
|
+
},
|
|
91
|
+
ENV: {
|
|
92
|
+
DEMO: "demo", // Mirror of production
|
|
93
|
+
DEVELOPMENT: "development", // Internal most stable development space
|
|
94
|
+
/** @deprecated */ EPHEMERAL: "ephemeral", // Alias for "build"
|
|
95
|
+
LOCAL: "local",
|
|
96
|
+
/** @deprecated */ MAIN: "main", // Alias for development
|
|
97
|
+
META: "meta", // For non-environment/infrastructure stacks
|
|
98
|
+
PERSONAL: "personal", // Personal builds using resources provided by sandbox
|
|
99
|
+
PREVIEW: "preview", // External next thing to be released
|
|
100
|
+
PRODUCTION: "production",
|
|
101
|
+
RELEASE: "release", // Internal next thing to be released
|
|
102
|
+
REVIEW: "review", // Internal place to collaborate on issues
|
|
103
|
+
SANDBOX: "sandbox", // Internal build space with no guaranteed longevity
|
|
104
|
+
TRAINING: "training", // aka "test"; mirror of production for external audiences
|
|
105
|
+
},
|
|
106
|
+
HOST: {
|
|
107
|
+
APEX: "@",
|
|
108
|
+
},
|
|
109
|
+
IMPORT: {
|
|
110
|
+
DATADOG_LOG_FORWARDER: "account-datadog-forwarder",
|
|
111
|
+
DATADOG_ROLE: "account-datadog-role",
|
|
112
|
+
DATADOG_SECRET: "account-datadog-secret",
|
|
113
|
+
LOG_BUCKET: "account-log-bucket",
|
|
114
|
+
OIDC_PROVIDER: "github-oidc-provider",
|
|
115
|
+
},
|
|
116
|
+
LAMBDA: {
|
|
117
|
+
LOG_RETENTION: 90,
|
|
118
|
+
MEMORY_SIZE: 1024,
|
|
119
|
+
},
|
|
120
|
+
PRINCIPAL: {
|
|
121
|
+
ROUTE53: "route53.amazonaws.com",
|
|
122
|
+
},
|
|
123
|
+
PRINCIPAL_TYPE: {
|
|
124
|
+
GROUP: "GROUP",
|
|
125
|
+
USER: "USER",
|
|
126
|
+
},
|
|
127
|
+
PROJECT: {
|
|
128
|
+
INFRASTRUCTURE: "infrastructure",
|
|
129
|
+
},
|
|
130
|
+
ROLE: {
|
|
131
|
+
API: "api",
|
|
132
|
+
DEPLOY: "deploy",
|
|
133
|
+
HOSTING: "hosting",
|
|
134
|
+
MONITORING: "monitoring",
|
|
135
|
+
NETWORKING: "networking",
|
|
136
|
+
PROCESSING: "processing",
|
|
137
|
+
SECURITY: "security",
|
|
138
|
+
STACK: "stack",
|
|
139
|
+
STORAGE: "storage",
|
|
140
|
+
TOY: "toy",
|
|
141
|
+
},
|
|
142
|
+
SERVICE: {
|
|
143
|
+
DATADOG: "datadog",
|
|
144
|
+
INFRASTRUCTURE: "infrastructure",
|
|
145
|
+
LIBRARIES: "libraries",
|
|
146
|
+
NONE: "none",
|
|
147
|
+
SSO: "sso",
|
|
148
|
+
TRACE: "trace",
|
|
149
|
+
},
|
|
150
|
+
TAG: {
|
|
151
|
+
BUILD_DATE: "buildDate",
|
|
152
|
+
BUILD_HEX: "buildHex",
|
|
153
|
+
BUILD_NUMBER: "buildNumber",
|
|
154
|
+
BUILD_TIME: "buildTime",
|
|
155
|
+
BUILD_TYPE: "buildType",
|
|
156
|
+
COMMIT: "commit",
|
|
157
|
+
CREATION: "creation",
|
|
158
|
+
ENV: "env",
|
|
159
|
+
NONCE: "nonce",
|
|
160
|
+
PROJECT: "project",
|
|
161
|
+
ROLE: "role",
|
|
162
|
+
SERVICE: "service",
|
|
163
|
+
SPONSOR: "sponsor",
|
|
164
|
+
STACK: "stack",
|
|
165
|
+
STACK_SHA: "stackSha",
|
|
166
|
+
VENDOR: "vendor",
|
|
167
|
+
VERSION: "version",
|
|
168
|
+
},
|
|
169
|
+
TARGET_TYPE: {
|
|
170
|
+
AWS_ACCOUNT: "AWS_ACCOUNT",
|
|
171
|
+
},
|
|
172
|
+
VENDOR: {
|
|
173
|
+
ANTHROPIC: "anthropic",
|
|
174
|
+
AUTH0: "auth0",
|
|
175
|
+
DATADOG: "datadog",
|
|
176
|
+
KNOWTRACE: "knowtrace",
|
|
177
|
+
MONGODB: "mongodb",
|
|
178
|
+
OPENAI: "openai",
|
|
179
|
+
SPLINTERLANDS: "splinterlands",
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
class JaypieAccountLoggingBucket extends Construct {
|
|
184
|
+
/**
|
|
185
|
+
* Create a new account-wide logging S3 bucket with lifecycle policies and export
|
|
186
|
+
*/
|
|
187
|
+
constructor(scope, idOrProps, propsOrUndefined) {
|
|
188
|
+
// Handle overloaded constructor signatures
|
|
189
|
+
let props;
|
|
190
|
+
let id;
|
|
191
|
+
if (typeof idOrProps === "string") {
|
|
192
|
+
// First param is ID, second is props
|
|
193
|
+
props = propsOrUndefined || {};
|
|
194
|
+
id = idOrProps;
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
// First param is props
|
|
198
|
+
props = idOrProps || {};
|
|
199
|
+
id = props.id || "AccountLoggingBucket";
|
|
200
|
+
}
|
|
201
|
+
super(scope, id);
|
|
202
|
+
// Generate default bucket name with PROJECT_NONCE
|
|
203
|
+
const defaultBucketName = process.env.PROJECT_NONCE
|
|
204
|
+
? `account-logging-stack-${process.env.PROJECT_NONCE.toLowerCase()}`
|
|
205
|
+
: "account-logging-stack";
|
|
206
|
+
// Extract Jaypie-specific options
|
|
207
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
208
|
+
const { bucketName = defaultBucketName, createOutput = true, expirationDays = 365, exportName = CDK$2.IMPORT.LOG_BUCKET, glacierTransitionDays = 180, id: _id, infrequentAccessTransitionDays = 30, outputDescription = "Account-wide logging bucket", project, service = CDK$2.SERVICE.INFRASTRUCTURE, ...bucketProps } = props;
|
|
209
|
+
// Create the bucket with lifecycle rules
|
|
210
|
+
this.bucket = new Bucket(this, "Bucket", {
|
|
211
|
+
accessControl: BucketAccessControl.LOG_DELIVERY_WRITE,
|
|
212
|
+
bucketName,
|
|
213
|
+
lifecycleRules: [
|
|
214
|
+
{
|
|
215
|
+
expiration: cdk.Duration.days(expirationDays),
|
|
216
|
+
transitions: [
|
|
217
|
+
{
|
|
218
|
+
storageClass: StorageClass.INFREQUENT_ACCESS,
|
|
219
|
+
transitionAfter: cdk.Duration.days(infrequentAccessTransitionDays),
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
storageClass: StorageClass.GLACIER,
|
|
223
|
+
transitionAfter: cdk.Duration.days(glacierTransitionDays),
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
},
|
|
227
|
+
],
|
|
228
|
+
...bucketProps,
|
|
229
|
+
});
|
|
230
|
+
// Add tags
|
|
231
|
+
cdk.Tags.of(this.bucket).add(CDK$2.TAG.ROLE, CDK$2.ROLE.MONITORING);
|
|
232
|
+
if (service) {
|
|
233
|
+
cdk.Tags.of(this.bucket).add(CDK$2.TAG.SERVICE, service);
|
|
234
|
+
}
|
|
235
|
+
if (project) {
|
|
236
|
+
cdk.Tags.of(this.bucket).add(CDK$2.TAG.PROJECT, project);
|
|
237
|
+
}
|
|
238
|
+
// Create CloudFormation output if enabled
|
|
239
|
+
if (createOutput) {
|
|
240
|
+
new cdk.CfnOutput(this, "BucketNameOutput", {
|
|
241
|
+
description: outputDescription,
|
|
242
|
+
exportName,
|
|
243
|
+
value: this.bucket.bucketName,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
27
249
|
function addDatadogLayers(lambdaFunction, options = {}) {
|
|
28
250
|
const datadogApiKeyArn = options?.datadogApiKeyArn;
|
|
29
251
|
const resolvedDatadogApiKeyArn = datadogApiKeyArn ||
|
|
@@ -146,6 +368,55 @@ function envHostname({ component, domain, env, subdomain, } = {}) {
|
|
|
146
368
|
return parts.join(".");
|
|
147
369
|
}
|
|
148
370
|
|
|
371
|
+
/**
|
|
372
|
+
* Extends the Datadog IAM role with additional permissions
|
|
373
|
+
*
|
|
374
|
+
* Checks for CDK_ENV_DATADOG_ROLE_ARN environment variable.
|
|
375
|
+
* If found, creates a custom policy with:
|
|
376
|
+
* - budgets:ViewBudget
|
|
377
|
+
* - logs:DescribeLogGroups
|
|
378
|
+
*
|
|
379
|
+
* @param scope - The construct scope
|
|
380
|
+
* @param options - Configuration options
|
|
381
|
+
* @returns The created Policy, or undefined if CDK_ENV_DATADOG_ROLE_ARN is not set
|
|
382
|
+
*/
|
|
383
|
+
function extendDatadogRole(scope, options) {
|
|
384
|
+
const datadogRoleArn = process.env.CDK_ENV_DATADOG_ROLE_ARN;
|
|
385
|
+
// Early return if no Datadog role ARN is configured
|
|
386
|
+
if (!datadogRoleArn) {
|
|
387
|
+
return undefined;
|
|
388
|
+
}
|
|
389
|
+
const { id = "DatadogCustomPolicy", project, service = CDK$2.SERVICE.DATADOG, } = options || {};
|
|
390
|
+
// Lookup the Datadog role
|
|
391
|
+
const datadogRole = Role.fromRoleArn(scope, "DatadogRole", datadogRoleArn);
|
|
392
|
+
// Build policy statements
|
|
393
|
+
const statements = [
|
|
394
|
+
// Allow view budget
|
|
395
|
+
new PolicyStatement({
|
|
396
|
+
actions: ["budgets:ViewBudget"],
|
|
397
|
+
resources: ["*"],
|
|
398
|
+
}),
|
|
399
|
+
// Allow describe log groups
|
|
400
|
+
new PolicyStatement({
|
|
401
|
+
actions: ["logs:DescribeLogGroups"],
|
|
402
|
+
resources: ["*"],
|
|
403
|
+
}),
|
|
404
|
+
];
|
|
405
|
+
// Create the custom policy
|
|
406
|
+
const datadogCustomPolicy = new Policy(scope, id, {
|
|
407
|
+
roles: [datadogRole],
|
|
408
|
+
statements,
|
|
409
|
+
});
|
|
410
|
+
// Add tags
|
|
411
|
+
cdk.Tags.of(datadogCustomPolicy).add(CDK$2.TAG.SERVICE, service);
|
|
412
|
+
cdk.Tags.of(datadogCustomPolicy).add(CDK$2.TAG.ROLE, CDK$2.ROLE.MONITORING);
|
|
413
|
+
cdk.Tags.of(datadogCustomPolicy).add(CDK$2.TAG.VENDOR, CDK$2.VENDOR.DATADOG);
|
|
414
|
+
if (project) {
|
|
415
|
+
cdk.Tags.of(datadogCustomPolicy).add(CDK$2.TAG.PROJECT, project);
|
|
416
|
+
}
|
|
417
|
+
return datadogCustomPolicy;
|
|
418
|
+
}
|
|
419
|
+
|
|
149
420
|
/**
|
|
150
421
|
* Check if the current environment matches the given environment
|
|
151
422
|
*/
|
|
@@ -165,6 +436,79 @@ function isSandboxEnv() {
|
|
|
165
436
|
return isEnv(CDK$2.ENV.SANDBOX);
|
|
166
437
|
}
|
|
167
438
|
|
|
439
|
+
// In short the RFC 1035 standard for valid hostnames is:
|
|
440
|
+
// 1. Must be less than 253 characters
|
|
441
|
+
// 2. Must start with a letter
|
|
442
|
+
// 3. Must end with a letter or number
|
|
443
|
+
// 4. Can only contain letters, numbers, and hyphens
|
|
444
|
+
// 5. Last part of the domain must be at least 2 characters
|
|
445
|
+
function validPart$1(part) {
|
|
446
|
+
if (!part.match(/^[a-z]/))
|
|
447
|
+
return false;
|
|
448
|
+
if (!part.match(/[a-z0-9]$/))
|
|
449
|
+
return false;
|
|
450
|
+
return /^[a-zA-Z0-9-]+$/.test(part);
|
|
451
|
+
}
|
|
452
|
+
function isValidHostname$1(hostname) {
|
|
453
|
+
// Check hostname is a string
|
|
454
|
+
if (typeof hostname !== "string")
|
|
455
|
+
return false;
|
|
456
|
+
// Convert hostname to lowercase
|
|
457
|
+
const check = hostname.toString().toLowerCase();
|
|
458
|
+
// Check hostname is less than 253 characters
|
|
459
|
+
if (check.length > 253)
|
|
460
|
+
return false;
|
|
461
|
+
// Split on dots
|
|
462
|
+
const parts = check.split(".");
|
|
463
|
+
// Check each part is validPart
|
|
464
|
+
const validParts = parts.map(validPart$1);
|
|
465
|
+
// Confirm all parts are valid
|
|
466
|
+
if (!validParts.every((part) => part))
|
|
467
|
+
return false;
|
|
468
|
+
// Confirm last part is at least 2 characters
|
|
469
|
+
const lastPart = parts[parts.length - 1];
|
|
470
|
+
if (lastPart.length < 2)
|
|
471
|
+
return false;
|
|
472
|
+
// Confirm last part is all letters
|
|
473
|
+
if (!lastPart.match(/^[a-z]+$/))
|
|
474
|
+
return false;
|
|
475
|
+
// This is a valid hostname
|
|
476
|
+
return true;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
function validPart(part) {
|
|
480
|
+
if (!part.match(/^[a-z]/))
|
|
481
|
+
return false;
|
|
482
|
+
if (!part.match(/[a-z0-9]$/))
|
|
483
|
+
return false;
|
|
484
|
+
return /^[a-zA-Z0-9-]+$/.test(part);
|
|
485
|
+
}
|
|
486
|
+
function isValidSubdomain(subdomain) {
|
|
487
|
+
// Check subdomain is a string
|
|
488
|
+
if (typeof subdomain !== "string")
|
|
489
|
+
return false;
|
|
490
|
+
// Special case for apex
|
|
491
|
+
if (subdomain === CDK$2.HOST.APEX)
|
|
492
|
+
return true;
|
|
493
|
+
// Convert subdomain to lowercase
|
|
494
|
+
const check = subdomain.toString().toLowerCase();
|
|
495
|
+
// Check subdomain is less than 250 characters
|
|
496
|
+
// We use 250 instead of 253 because we need to leave room for the dot top-level domain
|
|
497
|
+
if (check.length > 250)
|
|
498
|
+
return false;
|
|
499
|
+
// Split on dots
|
|
500
|
+
const parts = check.split(".");
|
|
501
|
+
// Check each part is validPart
|
|
502
|
+
const validParts = parts.map(validPart);
|
|
503
|
+
// Confirm all parts are valid
|
|
504
|
+
if (!validParts.every((part) => part))
|
|
505
|
+
return false;
|
|
506
|
+
// Do not care if last part is at least 2 characters
|
|
507
|
+
// Do not care if last part is all letters
|
|
508
|
+
// This is a valid subdomain
|
|
509
|
+
return true;
|
|
510
|
+
}
|
|
511
|
+
|
|
168
512
|
function jaypieLambdaEnv(options = {}) {
|
|
169
513
|
const { initialEnvironment = {} } = options;
|
|
170
514
|
// Start with empty environment - we'll only add valid values
|
|
@@ -219,6 +563,21 @@ function jaypieLambdaEnv(options = {}) {
|
|
|
219
563
|
return environment;
|
|
220
564
|
}
|
|
221
565
|
|
|
566
|
+
function mergeDomain(subDomain, hostedZone) {
|
|
567
|
+
if (!hostedZone) {
|
|
568
|
+
throw new ConfigurationError("hostedZone is required");
|
|
569
|
+
}
|
|
570
|
+
if (!subDomain) {
|
|
571
|
+
// Return hostedZone if subDomain is not passed
|
|
572
|
+
// Pass CDK.HOST.APEX to explicitly indicate apex domain
|
|
573
|
+
return hostedZone;
|
|
574
|
+
}
|
|
575
|
+
if (subDomain === CDK$2.HOST.APEX) {
|
|
576
|
+
return hostedZone;
|
|
577
|
+
}
|
|
578
|
+
return `${subDomain}.${hostedZone}`;
|
|
579
|
+
}
|
|
580
|
+
|
|
222
581
|
const DEFAULT_FUNCTION_NAME$1 = "DatadogForwarderFunction";
|
|
223
582
|
// Cache to store resolved functions
|
|
224
583
|
// Using nested structure to support multiple functions per scope with automatic GC
|
|
@@ -1097,6 +1456,175 @@ class JaypieBucketQueuedLambda extends JaypieQueuedLambda {
|
|
|
1097
1456
|
}
|
|
1098
1457
|
}
|
|
1099
1458
|
|
|
1459
|
+
class JaypieDatadogBucket extends Construct {
|
|
1460
|
+
/**
|
|
1461
|
+
* Create a new S3 bucket for Datadog log archiving with automatic IAM permissions
|
|
1462
|
+
*/
|
|
1463
|
+
constructor(scope, idOrProps, propsOrUndefined) {
|
|
1464
|
+
// Handle overloaded constructor signatures
|
|
1465
|
+
let props;
|
|
1466
|
+
let id;
|
|
1467
|
+
if (typeof idOrProps === "string") {
|
|
1468
|
+
// First param is ID, second is props
|
|
1469
|
+
props = propsOrUndefined || {};
|
|
1470
|
+
id = idOrProps;
|
|
1471
|
+
}
|
|
1472
|
+
else {
|
|
1473
|
+
// First param is props
|
|
1474
|
+
props = idOrProps || {};
|
|
1475
|
+
id = props.id || "DatadogArchiveBucket";
|
|
1476
|
+
}
|
|
1477
|
+
super(scope, id);
|
|
1478
|
+
// Extract Jaypie-specific options
|
|
1479
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1480
|
+
const { grantDatadogAccess = true, id: _id, project, service = CDK$2.SERVICE.DATADOG, ...bucketProps } = props;
|
|
1481
|
+
// Create the bucket
|
|
1482
|
+
this.bucket = new Bucket(this, "Bucket", bucketProps);
|
|
1483
|
+
// Add tags to bucket
|
|
1484
|
+
cdk.Tags.of(this.bucket).add(CDK$2.TAG.SERVICE, service);
|
|
1485
|
+
cdk.Tags.of(this.bucket).add(CDK$2.TAG.ROLE, CDK$2.ROLE.MONITORING);
|
|
1486
|
+
if (project) {
|
|
1487
|
+
cdk.Tags.of(this.bucket).add(CDK$2.TAG.PROJECT, project);
|
|
1488
|
+
}
|
|
1489
|
+
// Grant Datadog role access to bucket if enabled
|
|
1490
|
+
if (grantDatadogAccess) {
|
|
1491
|
+
this.policy = this.grantDatadogRoleBucketAccess({ project, service });
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
/**
|
|
1495
|
+
* Grants the Datadog IAM role access to this bucket
|
|
1496
|
+
*
|
|
1497
|
+
* Checks for CDK_ENV_DATADOG_ROLE_ARN environment variable.
|
|
1498
|
+
* If found, creates a custom policy with:
|
|
1499
|
+
* - s3:ListBucket on bucket
|
|
1500
|
+
* - s3:GetObject and s3:PutObject on bucket/*
|
|
1501
|
+
*
|
|
1502
|
+
* @param options - Configuration options
|
|
1503
|
+
* @returns The created Policy, or undefined if CDK_ENV_DATADOG_ROLE_ARN is not set
|
|
1504
|
+
*/
|
|
1505
|
+
grantDatadogRoleBucketAccess(options) {
|
|
1506
|
+
const datadogRoleArn = process.env.CDK_ENV_DATADOG_ROLE_ARN;
|
|
1507
|
+
// Early return if no Datadog role ARN is configured
|
|
1508
|
+
if (!datadogRoleArn) {
|
|
1509
|
+
return undefined;
|
|
1510
|
+
}
|
|
1511
|
+
const { project, service = CDK$2.SERVICE.DATADOG } = options || {};
|
|
1512
|
+
// Lookup the Datadog role
|
|
1513
|
+
const datadogRole = Role.fromRoleArn(this, "DatadogRole", datadogRoleArn);
|
|
1514
|
+
// Build policy statements for bucket access
|
|
1515
|
+
const statements = [
|
|
1516
|
+
// Allow list bucket
|
|
1517
|
+
new PolicyStatement({
|
|
1518
|
+
actions: ["s3:ListBucket"],
|
|
1519
|
+
resources: [this.bucket.bucketArn],
|
|
1520
|
+
}),
|
|
1521
|
+
// Allow read and write to the bucket
|
|
1522
|
+
new PolicyStatement({
|
|
1523
|
+
actions: ["s3:GetObject", "s3:PutObject"],
|
|
1524
|
+
resources: [`${this.bucket.bucketArn}/*`],
|
|
1525
|
+
}),
|
|
1526
|
+
];
|
|
1527
|
+
// Create the custom policy
|
|
1528
|
+
const datadogBucketPolicy = new Policy(this, "DatadogBucketPolicy", {
|
|
1529
|
+
roles: [datadogRole],
|
|
1530
|
+
statements,
|
|
1531
|
+
});
|
|
1532
|
+
// Add tags
|
|
1533
|
+
cdk.Tags.of(datadogBucketPolicy).add(CDK$2.TAG.SERVICE, service);
|
|
1534
|
+
cdk.Tags.of(datadogBucketPolicy).add(CDK$2.TAG.ROLE, CDK$2.ROLE.MONITORING);
|
|
1535
|
+
cdk.Tags.of(datadogBucketPolicy).add(CDK$2.TAG.VENDOR, CDK$2.VENDOR.DATADOG);
|
|
1536
|
+
if (project) {
|
|
1537
|
+
cdk.Tags.of(datadogBucketPolicy).add(CDK$2.TAG.PROJECT, project);
|
|
1538
|
+
}
|
|
1539
|
+
return datadogBucketPolicy;
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
const DATADOG_FORWARDER_TEMPLATE_URL = "https://datadog-cloudformation-template.s3.amazonaws.com/aws/forwarder/latest.yaml";
|
|
1544
|
+
const DEFAULT_RESERVED_CONCURRENCY = "10";
|
|
1545
|
+
class JaypieDatadogForwarder extends Construct {
|
|
1546
|
+
/**
|
|
1547
|
+
* Create a new Datadog forwarder with CloudFormation nested stack
|
|
1548
|
+
*/
|
|
1549
|
+
constructor(scope, idOrProps, propsOrUndefined) {
|
|
1550
|
+
// Handle overloaded constructor signatures
|
|
1551
|
+
let props;
|
|
1552
|
+
let id;
|
|
1553
|
+
if (typeof idOrProps === "string") {
|
|
1554
|
+
// First param is ID, second is props
|
|
1555
|
+
props = propsOrUndefined || {};
|
|
1556
|
+
id = idOrProps;
|
|
1557
|
+
}
|
|
1558
|
+
else {
|
|
1559
|
+
// First param is props
|
|
1560
|
+
props = idOrProps || {};
|
|
1561
|
+
id = props.id || "DatadogForwarder";
|
|
1562
|
+
}
|
|
1563
|
+
super(scope, id);
|
|
1564
|
+
// Resolve options with defaults
|
|
1565
|
+
const { account = process.env.CDK_ENV_ACCOUNT, additionalTags, createOutput = true, datadogApiKey = process.env.CDK_ENV_DATADOG_API_KEY, enableCloudFormationEvents = true, enableRoleExtension = true, exportName = CDK$2.IMPORT.DATADOG_LOG_FORWARDER, project, reservedConcurrency = DEFAULT_RESERVED_CONCURRENCY, service = CDK$2.VENDOR.DATADOG, templateUrl = DATADOG_FORWARDER_TEMPLATE_URL, } = props;
|
|
1566
|
+
// Validate required parameters
|
|
1567
|
+
if (!datadogApiKey) {
|
|
1568
|
+
throw new Error("Datadog API key is required. Provide via datadogApiKey prop or CDK_ENV_DATADOG_API_KEY environment variable.");
|
|
1569
|
+
}
|
|
1570
|
+
// Build Datadog tags
|
|
1571
|
+
let ddTags = account ? `account:${account}` : "";
|
|
1572
|
+
if (additionalTags) {
|
|
1573
|
+
ddTags = ddTags ? `${ddTags},${additionalTags}` : additionalTags;
|
|
1574
|
+
}
|
|
1575
|
+
// Deploy Datadog CloudFormation stack
|
|
1576
|
+
this.cfnStack = new CfnStack(this, "Stack", {
|
|
1577
|
+
parameters: {
|
|
1578
|
+
DdApiKey: datadogApiKey,
|
|
1579
|
+
DdTags: ddTags,
|
|
1580
|
+
ReservedConcurrency: reservedConcurrency,
|
|
1581
|
+
},
|
|
1582
|
+
templateUrl,
|
|
1583
|
+
});
|
|
1584
|
+
// Add tags to stack
|
|
1585
|
+
cdk.Tags.of(this.cfnStack).add(CDK$2.TAG.ROLE, CDK$2.ROLE.MONITORING);
|
|
1586
|
+
cdk.Tags.of(this.cfnStack).add(CDK$2.TAG.SERVICE, service);
|
|
1587
|
+
cdk.Tags.of(this.cfnStack).add(CDK$2.TAG.VENDOR, CDK$2.VENDOR.DATADOG);
|
|
1588
|
+
if (project) {
|
|
1589
|
+
cdk.Tags.of(this.cfnStack).add(CDK$2.TAG.PROJECT, project);
|
|
1590
|
+
}
|
|
1591
|
+
// Extract forwarder function from stack outputs
|
|
1592
|
+
this.forwarderFunction = lambda.Function.fromFunctionArn(this, "Function", this.cfnStack.getAtt("Outputs.DatadogForwarderArn").toString());
|
|
1593
|
+
// Extend Datadog role with custom permissions if enabled
|
|
1594
|
+
if (enableRoleExtension) {
|
|
1595
|
+
extendDatadogRole(this, { project, service });
|
|
1596
|
+
}
|
|
1597
|
+
// Create CloudFormation events rule if enabled
|
|
1598
|
+
if (enableCloudFormationEvents) {
|
|
1599
|
+
this.eventsRule = new Rule(this, "CloudFormationEventsRule", {
|
|
1600
|
+
eventPattern: {
|
|
1601
|
+
source: ["aws.cloudformation"],
|
|
1602
|
+
},
|
|
1603
|
+
targets: [
|
|
1604
|
+
new LambdaFunction(this.forwarderFunction, {
|
|
1605
|
+
event: RuleTargetInput.fromEventPath("$"),
|
|
1606
|
+
}),
|
|
1607
|
+
],
|
|
1608
|
+
});
|
|
1609
|
+
// Add tags to events rule
|
|
1610
|
+
cdk.Tags.of(this.eventsRule).add(CDK$2.TAG.ROLE, CDK$2.ROLE.MONITORING);
|
|
1611
|
+
cdk.Tags.of(this.eventsRule).add(CDK$2.TAG.SERVICE, service);
|
|
1612
|
+
cdk.Tags.of(this.eventsRule).add(CDK$2.TAG.VENDOR, CDK$2.VENDOR.DATADOG);
|
|
1613
|
+
if (project) {
|
|
1614
|
+
cdk.Tags.of(this.eventsRule).add(CDK$2.TAG.PROJECT, project);
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
// Create CloudFormation output if enabled
|
|
1618
|
+
if (createOutput) {
|
|
1619
|
+
new cdk.CfnOutput(this, "ForwarderArnOutput", {
|
|
1620
|
+
description: "Datadog Log Forwarder Lambda ARN",
|
|
1621
|
+
exportName,
|
|
1622
|
+
value: this.cfnStack.getAtt("Outputs.DatadogForwarderArn").toString(),
|
|
1623
|
+
});
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1100
1628
|
// It is a consumer if the environment is ephemeral
|
|
1101
1629
|
function checkEnvIsConsumer(env = process.env) {
|
|
1102
1630
|
return (env.PROJECT_ENV === CDK$2.ENV.PERSONAL ||
|
|
@@ -1320,6 +1848,86 @@ class JaypieDnsRecord extends Construct {
|
|
|
1320
1848
|
}
|
|
1321
1849
|
}
|
|
1322
1850
|
|
|
1851
|
+
class JaypieEventsRule extends Construct {
|
|
1852
|
+
/**
|
|
1853
|
+
* Create a new EventBridge rule that targets a Lambda function
|
|
1854
|
+
*/
|
|
1855
|
+
constructor(scope, idOrSourceOrProps, propsOrUndefined) {
|
|
1856
|
+
// Handle overloaded constructor signatures
|
|
1857
|
+
let props;
|
|
1858
|
+
let id;
|
|
1859
|
+
if (typeof idOrSourceOrProps === "string") {
|
|
1860
|
+
// Check if it looks like an AWS source (starts with "aws.")
|
|
1861
|
+
if (idOrSourceOrProps.startsWith("aws.")) {
|
|
1862
|
+
// First param is source, second is props
|
|
1863
|
+
props = propsOrUndefined || {};
|
|
1864
|
+
props.source = idOrSourceOrProps;
|
|
1865
|
+
// Generate ID from source
|
|
1866
|
+
const sourceName = idOrSourceOrProps
|
|
1867
|
+
.replace("aws.", "")
|
|
1868
|
+
.split(".")
|
|
1869
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
1870
|
+
.join("");
|
|
1871
|
+
id = props.id || `${sourceName}EventsRule`;
|
|
1872
|
+
}
|
|
1873
|
+
else {
|
|
1874
|
+
// First param is ID, second is props
|
|
1875
|
+
props = propsOrUndefined || {};
|
|
1876
|
+
id = idOrSourceOrProps;
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
else {
|
|
1880
|
+
// First param is props
|
|
1881
|
+
props = idOrSourceOrProps || {};
|
|
1882
|
+
if (props.source) {
|
|
1883
|
+
const sourceName = typeof props.source === "string"
|
|
1884
|
+
? props.source
|
|
1885
|
+
.replace("aws.", "")
|
|
1886
|
+
.split(".")
|
|
1887
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
1888
|
+
.join("")
|
|
1889
|
+
: "Events";
|
|
1890
|
+
id = props.id || `${sourceName}EventsRule`;
|
|
1891
|
+
}
|
|
1892
|
+
else {
|
|
1893
|
+
id = props.id || "EventsRule";
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
super(scope, id);
|
|
1897
|
+
// Extract Jaypie-specific options
|
|
1898
|
+
const { id: _id, project, service = CDK$2.SERVICE.DATADOG, source, targetFunction, vendor = CDK$2.VENDOR.DATADOG, ...ruleProps } = props;
|
|
1899
|
+
// Resolve target function
|
|
1900
|
+
this.targetFunction =
|
|
1901
|
+
targetFunction || resolveDatadogForwarderFunction(scope);
|
|
1902
|
+
// Build event pattern if source is specified
|
|
1903
|
+
const eventPattern = source
|
|
1904
|
+
? {
|
|
1905
|
+
...ruleProps.eventPattern,
|
|
1906
|
+
source: Array.isArray(source) ? source : [source],
|
|
1907
|
+
}
|
|
1908
|
+
: ruleProps.eventPattern;
|
|
1909
|
+
// Build rule props
|
|
1910
|
+
const finalRuleProps = {
|
|
1911
|
+
...ruleProps,
|
|
1912
|
+
eventPattern,
|
|
1913
|
+
targets: [
|
|
1914
|
+
new LambdaFunction(this.targetFunction, {
|
|
1915
|
+
event: RuleTargetInput.fromEventPath("$"),
|
|
1916
|
+
}),
|
|
1917
|
+
],
|
|
1918
|
+
};
|
|
1919
|
+
// Create the rule
|
|
1920
|
+
this.rule = new Rule(this, "Rule", finalRuleProps);
|
|
1921
|
+
// Add tags
|
|
1922
|
+
cdk.Tags.of(this.rule).add(CDK$2.TAG.ROLE, CDK$2.ROLE.MONITORING);
|
|
1923
|
+
cdk.Tags.of(this.rule).add(CDK$2.TAG.SERVICE, service);
|
|
1924
|
+
cdk.Tags.of(this.rule).add(CDK$2.TAG.VENDOR, vendor);
|
|
1925
|
+
if (project) {
|
|
1926
|
+
cdk.Tags.of(this.rule).add(CDK$2.TAG.PROJECT, project);
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1323
1931
|
class JaypieGitHubDeployRole extends Construct {
|
|
1324
1932
|
constructor(scope, id = "GitHubDeployRole", props = {}) {
|
|
1325
1933
|
super(scope, id);
|
|
@@ -1565,6 +2173,100 @@ class JaypieOpenAiSecret extends JaypieEnvSecret {
|
|
|
1565
2173
|
}
|
|
1566
2174
|
}
|
|
1567
2175
|
|
|
2176
|
+
class JaypieOrganizationTrail extends Construct {
|
|
2177
|
+
/**
|
|
2178
|
+
* Create a new organization CloudTrail with S3 bucket and lifecycle policies
|
|
2179
|
+
*/
|
|
2180
|
+
constructor(scope, idOrProps, propsOrUndefined) {
|
|
2181
|
+
// Handle overloaded constructor signatures
|
|
2182
|
+
let props;
|
|
2183
|
+
let id;
|
|
2184
|
+
if (typeof idOrProps === "string") {
|
|
2185
|
+
// First param is ID, second is props
|
|
2186
|
+
props = propsOrUndefined || {};
|
|
2187
|
+
id = idOrProps;
|
|
2188
|
+
}
|
|
2189
|
+
else {
|
|
2190
|
+
// First param is props
|
|
2191
|
+
props = idOrProps || {};
|
|
2192
|
+
const defaultName = process.env.PROJECT_NONCE
|
|
2193
|
+
? `organization-cloudtrail-${process.env.PROJECT_NONCE}`
|
|
2194
|
+
: "organization-cloudtrail";
|
|
2195
|
+
id = props.id || `${props.trailName || defaultName}-Trail`;
|
|
2196
|
+
}
|
|
2197
|
+
super(scope, id);
|
|
2198
|
+
// Resolve options with defaults
|
|
2199
|
+
const { bucketName = process.env.PROJECT_NONCE
|
|
2200
|
+
? `organization-cloudtrail-${process.env.PROJECT_NONCE}`
|
|
2201
|
+
: "organization-cloudtrail", enableDatadogNotifications = true, enableFileValidation = false, expirationDays = 365, glacierTransitionDays = 180, infrequentAccessTransitionDays = 30, project, service = CDK$2.SERVICE.INFRASTRUCTURE, trailName = process.env.PROJECT_NONCE
|
|
2202
|
+
? `organization-cloudtrail-${process.env.PROJECT_NONCE}`
|
|
2203
|
+
: "organization-cloudtrail", } = props;
|
|
2204
|
+
// Create the S3 bucket for CloudTrail logs
|
|
2205
|
+
this.bucket = new Bucket(this, "Bucket", {
|
|
2206
|
+
accessControl: BucketAccessControl.LOG_DELIVERY_WRITE,
|
|
2207
|
+
bucketName,
|
|
2208
|
+
lifecycleRules: [
|
|
2209
|
+
{
|
|
2210
|
+
expiration: cdk.Duration.days(expirationDays),
|
|
2211
|
+
transitions: [
|
|
2212
|
+
{
|
|
2213
|
+
storageClass: StorageClass.INFREQUENT_ACCESS,
|
|
2214
|
+
transitionAfter: cdk.Duration.days(infrequentAccessTransitionDays),
|
|
2215
|
+
},
|
|
2216
|
+
{
|
|
2217
|
+
storageClass: StorageClass.GLACIER,
|
|
2218
|
+
transitionAfter: cdk.Duration.days(glacierTransitionDays),
|
|
2219
|
+
},
|
|
2220
|
+
],
|
|
2221
|
+
},
|
|
2222
|
+
],
|
|
2223
|
+
});
|
|
2224
|
+
// Add CloudTrail bucket policies
|
|
2225
|
+
this.bucket.addToResourcePolicy(new PolicyStatement({
|
|
2226
|
+
actions: ["s3:GetBucketAcl"],
|
|
2227
|
+
effect: Effect.ALLOW,
|
|
2228
|
+
principals: [new ServicePrincipal("cloudtrail.amazonaws.com")],
|
|
2229
|
+
resources: [this.bucket.bucketArn],
|
|
2230
|
+
}));
|
|
2231
|
+
this.bucket.addToResourcePolicy(new PolicyStatement({
|
|
2232
|
+
actions: ["s3:PutObject"],
|
|
2233
|
+
conditions: {
|
|
2234
|
+
StringEquals: {
|
|
2235
|
+
"s3:x-amz-acl": "bucket-owner-full-control",
|
|
2236
|
+
},
|
|
2237
|
+
},
|
|
2238
|
+
effect: Effect.ALLOW,
|
|
2239
|
+
principals: [new ServicePrincipal("cloudtrail.amazonaws.com")],
|
|
2240
|
+
resources: [`${this.bucket.bucketArn}/*`],
|
|
2241
|
+
}));
|
|
2242
|
+
// Add tags to bucket
|
|
2243
|
+
cdk.Tags.of(this.bucket).add(CDK$2.TAG.SERVICE, service);
|
|
2244
|
+
cdk.Tags.of(this.bucket).add(CDK$2.TAG.ROLE, CDK$2.ROLE.MONITORING);
|
|
2245
|
+
if (project) {
|
|
2246
|
+
cdk.Tags.of(this.bucket).add(CDK$2.TAG.PROJECT, project);
|
|
2247
|
+
}
|
|
2248
|
+
// Add Datadog notifications if enabled
|
|
2249
|
+
if (enableDatadogNotifications) {
|
|
2250
|
+
const datadogForwarderFunction = resolveDatadogForwarderFunction(scope);
|
|
2251
|
+
this.bucket.addEventNotification(EventType.OBJECT_CREATED, new LambdaDestination(datadogForwarderFunction));
|
|
2252
|
+
}
|
|
2253
|
+
// Create the organization trail
|
|
2254
|
+
this.trail = new Trail(this, "Trail", {
|
|
2255
|
+
bucket: this.bucket,
|
|
2256
|
+
enableFileValidation,
|
|
2257
|
+
isOrganizationTrail: true,
|
|
2258
|
+
managementEvents: ReadWriteType.ALL,
|
|
2259
|
+
trailName,
|
|
2260
|
+
});
|
|
2261
|
+
// Add tags to trail
|
|
2262
|
+
cdk.Tags.of(this.trail).add(CDK$2.TAG.SERVICE, service);
|
|
2263
|
+
cdk.Tags.of(this.trail).add(CDK$2.TAG.ROLE, CDK$2.ROLE.MONITORING);
|
|
2264
|
+
if (project) {
|
|
2265
|
+
cdk.Tags.of(this.trail).add(CDK$2.TAG.PROJECT, project);
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
|
|
1568
2270
|
/**
|
|
1569
2271
|
* JaypieSsoPermissions Construct
|
|
1570
2272
|
*
|
|
@@ -1879,7 +2581,7 @@ class JaypieSsoSyncApplication extends Construct {
|
|
|
1879
2581
|
missingParams.push(`scimEndpointUrl or ${scimEndpointUrlEnvKey} environment variable`);
|
|
1880
2582
|
}
|
|
1881
2583
|
if (missingParams.length > 0) {
|
|
1882
|
-
throw new ConfigurationError
|
|
2584
|
+
throw new ConfigurationError(`JaypieSsoSyncApplication missing required configuration: ${missingParams.join(", ")}`);
|
|
1883
2585
|
}
|
|
1884
2586
|
// Create the SSO Sync Application
|
|
1885
2587
|
// Type assertion is safe because we validated all required values above
|
|
@@ -2178,5 +2880,5 @@ class JaypieWebDeploymentBucket extends Construct {
|
|
|
2178
2880
|
}
|
|
2179
2881
|
}
|
|
2180
2882
|
|
|
2181
|
-
export { JaypieApiGateway, JaypieAppStack, JaypieBucketQueuedLambda, JaypieDatadogSecret, JaypieDnsRecord, JaypieEnvSecret, JaypieExpressLambda, JaypieGitHubDeployRole, JaypieHostedZone, JaypieInfrastructureStack, JaypieLambda, JaypieMongoDbSecret, JaypieOpenAiSecret, JaypieQueuedLambda, JaypieSsoPermissions, JaypieSsoSyncApplication, JaypieStack, JaypieTraceSigningKeySecret, JaypieWebDeploymentBucket, addDatadogLayers, constructEnvName, constructStackName, constructTagger, envHostname, isEnv, isProductionEnv, isSandboxEnv, jaypieLambdaEnv, resolveDatadogForwarderFunction, resolveDatadogLayers, resolveDatadogLoggingDestination, resolveHostedZone, resolveParamsAndSecrets };
|
|
2883
|
+
export { CDK$2 as CDK, JaypieAccountLoggingBucket, JaypieApiGateway, JaypieAppStack, JaypieBucketQueuedLambda, JaypieDatadogBucket, JaypieDatadogForwarder, JaypieDatadogSecret, JaypieDnsRecord, JaypieEnvSecret, JaypieEventsRule, JaypieExpressLambda, JaypieGitHubDeployRole, JaypieHostedZone, JaypieInfrastructureStack, JaypieLambda, JaypieMongoDbSecret, JaypieOpenAiSecret, JaypieOrganizationTrail, JaypieQueuedLambda, JaypieSsoPermissions, JaypieSsoSyncApplication, JaypieStack, JaypieTraceSigningKeySecret, JaypieWebDeploymentBucket, addDatadogLayers, constructEnvName, constructStackName, constructTagger, envHostname, extendDatadogRole, isEnv, isProductionEnv, isSandboxEnv, isValidHostname$1 as isValidHostname, isValidSubdomain, jaypieLambdaEnv, mergeDomain, resolveDatadogForwarderFunction, resolveDatadogLayers, resolveDatadogLoggingDestination, resolveHostedZone, resolveParamsAndSecrets };
|
|
2182
2884
|
//# sourceMappingURL=index.js.map
|