@jaypie/constructs 1.2.32 → 1.2.34
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/JaypieDistribution.d.ts +41 -0
- package/dist/cjs/JaypieDynamoDb.d.ts +1 -0
- package/dist/cjs/JaypieMigration.d.ts +21 -0
- package/dist/cjs/JaypieOrganizationTrail.d.ts +18 -1
- package/dist/cjs/__tests__/JaypieMigration.spec.d.ts +1 -0
- package/dist/cjs/__tests__/JaypieOrganizationTrail.spec.d.ts +1 -0
- package/dist/cjs/index.cjs +188 -2
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +2 -1
- package/dist/esm/JaypieDistribution.d.ts +41 -0
- package/dist/esm/JaypieDynamoDb.d.ts +1 -0
- package/dist/esm/JaypieMigration.d.ts +21 -0
- package/dist/esm/JaypieOrganizationTrail.d.ts +18 -1
- package/dist/esm/__tests__/JaypieMigration.spec.d.ts +1 -0
- package/dist/esm/__tests__/JaypieOrganizationTrail.spec.d.ts +1 -0
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.js +186 -3
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cjs/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { JaypieCertificate, JaypieCertificateProps } from "./JaypieCertificate";
|
|
|
7
7
|
export { JaypieDatadogBucket, JaypieDatadogBucketProps, } from "./JaypieDatadogBucket";
|
|
8
8
|
export { JaypieDatadogForwarder, JaypieDatadogForwarderProps, } from "./JaypieDatadogForwarder";
|
|
9
9
|
export { JaypieDatadogSecret } from "./JaypieDatadogSecret";
|
|
10
|
-
export { JaypieDistribution, JaypieDistributionProps, SecurityHeadersOverrides, } from "./JaypieDistribution";
|
|
10
|
+
export { JaypieDistribution, JaypieDistributionProps, JaypieWafConfig, SecurityHeadersOverrides, } from "./JaypieDistribution";
|
|
11
11
|
export { JaypieDnsRecord, JaypieDnsRecordProps } from "./JaypieDnsRecord";
|
|
12
12
|
export { JaypieDynamoDb, JaypieDynamoDbProps } from "./JaypieDynamoDb";
|
|
13
13
|
export type { IndexDefinition } from "@jaypie/fabric";
|
|
@@ -18,6 +18,7 @@ export { JaypieGitHubDeployRole, JaypieGitHubDeployRoleProps, } from "./JaypieGi
|
|
|
18
18
|
export { JaypieHostedZone, JaypieHostedZoneRecordProps, } from "./JaypieHostedZone";
|
|
19
19
|
export { JaypieInfrastructureStack } from "./JaypieInfrastructureStack";
|
|
20
20
|
export { JaypieLambda, JaypieLambdaProps } from "./JaypieLambda";
|
|
21
|
+
export { JaypieMigration, JaypieMigrationProps } from "./JaypieMigration";
|
|
21
22
|
export { JaypieMongoDbSecret } from "./JaypieMongoDbSecret";
|
|
22
23
|
export { DomainNameConfig, JaypieNextJs, JaypieNextjsProps, } from "./JaypieNextJs";
|
|
23
24
|
export { JaypieOpenAiSecret } from "./JaypieOpenAiSecret";
|
|
@@ -5,8 +5,38 @@ import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
|
5
5
|
import * as route53 from "aws-cdk-lib/aws-route53";
|
|
6
6
|
import * as s3 from "aws-cdk-lib/aws-s3";
|
|
7
7
|
import { LambdaDestination } from "aws-cdk-lib/aws-s3-notifications";
|
|
8
|
+
import * as wafv2 from "aws-cdk-lib/aws-wafv2";
|
|
8
9
|
import { Construct } from "constructs";
|
|
9
10
|
import { HostConfig } from "./helpers";
|
|
11
|
+
export interface JaypieWafConfig {
|
|
12
|
+
/**
|
|
13
|
+
* Whether WAF is enabled
|
|
14
|
+
* @default true
|
|
15
|
+
*/
|
|
16
|
+
enabled?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* WAF logging bucket.
|
|
19
|
+
* - true/undefined: create a logging bucket with Datadog forwarding (default)
|
|
20
|
+
* - false: disable WAF logging
|
|
21
|
+
* - IBucket: use an existing bucket (must have "aws-waf-logs-" prefix)
|
|
22
|
+
* @default true
|
|
23
|
+
*/
|
|
24
|
+
logBucket?: boolean | s3.IBucket;
|
|
25
|
+
/**
|
|
26
|
+
* Managed rule group names to apply
|
|
27
|
+
* @default ["AWSManagedRulesCommonRuleSet", "AWSManagedRulesKnownBadInputsRuleSet"]
|
|
28
|
+
*/
|
|
29
|
+
managedRules?: string[];
|
|
30
|
+
/**
|
|
31
|
+
* Rate limit per IP per 5-minute window
|
|
32
|
+
* @default 2000
|
|
33
|
+
*/
|
|
34
|
+
rateLimitPerIp?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Use an existing WebACL ARN instead of creating one
|
|
37
|
+
*/
|
|
38
|
+
webAclArn?: string;
|
|
39
|
+
}
|
|
10
40
|
export interface SecurityHeadersOverrides {
|
|
11
41
|
contentSecurityPolicy?: string;
|
|
12
42
|
frameOption?: cloudfront.HeadersFrameOption;
|
|
@@ -99,6 +129,14 @@ export interface JaypieDistributionProps extends Omit<cloudfront.DistributionPro
|
|
|
99
129
|
* @default CDK.ROLE.HOSTING
|
|
100
130
|
*/
|
|
101
131
|
roleTag?: string;
|
|
132
|
+
/**
|
|
133
|
+
* WAF WebACL configuration for the CloudFront distribution.
|
|
134
|
+
* - true/undefined: create and attach a WebACL with sensible defaults
|
|
135
|
+
* - false: disable WAF
|
|
136
|
+
* - JaypieWafConfig: customize WAF behavior
|
|
137
|
+
* @default true
|
|
138
|
+
*/
|
|
139
|
+
waf?: boolean | JaypieWafConfig;
|
|
102
140
|
/**
|
|
103
141
|
* The hosted zone for DNS records
|
|
104
142
|
* @default CDK_ENV_API_HOSTED_ZONE || CDK_ENV_HOSTED_ZONE
|
|
@@ -116,11 +154,14 @@ export declare class JaypieDistribution extends Construct implements cloudfront.
|
|
|
116
154
|
readonly host?: string;
|
|
117
155
|
readonly logBucket?: s3.IBucket;
|
|
118
156
|
readonly responseHeadersPolicy?: cloudfront.IResponseHeadersPolicy;
|
|
157
|
+
readonly wafLogBucket?: s3.IBucket;
|
|
158
|
+
readonly webAcl?: wafv2.CfnWebACL;
|
|
119
159
|
constructor(scope: Construct, id: string, props: JaypieDistributionProps);
|
|
120
160
|
private isIOrigin;
|
|
121
161
|
private isIFunctionUrl;
|
|
122
162
|
private isIFunction;
|
|
123
163
|
private isExportNameObject;
|
|
164
|
+
private resolveWafConfig;
|
|
124
165
|
private resolveLogBucket;
|
|
125
166
|
get env(): {
|
|
126
167
|
account: string;
|
|
@@ -89,6 +89,7 @@ export declare class JaypieDynamoDb extends Construct implements dynamodb.ITable
|
|
|
89
89
|
get tableRef(): dynamodb.TableReference;
|
|
90
90
|
get tableStreamArn(): string | undefined;
|
|
91
91
|
get encryptionKey(): import("aws-cdk-lib/aws-kms").IKey | undefined;
|
|
92
|
+
get grants(): dynamodb.TableGrants;
|
|
92
93
|
applyRemovalPolicy(policy: RemovalPolicy): void;
|
|
93
94
|
grant(grantee: import("aws-cdk-lib/aws-iam").IGrantable, ...actions: string[]): import("aws-cdk-lib/aws-iam").Grant;
|
|
94
95
|
grantFullAccess(grantee: import("aws-cdk-lib/aws-iam").IGrantable): import("aws-cdk-lib/aws-iam").Grant;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Construct } from "constructs";
|
|
2
|
+
import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
|
|
3
|
+
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
4
|
+
import { JaypieLambda } from "./JaypieLambda";
|
|
5
|
+
import type { SecretsArrayItem } from "./helpers/index.js";
|
|
6
|
+
export interface JaypieMigrationProps {
|
|
7
|
+
/** Path to the bundled migration code (esbuild output directory) */
|
|
8
|
+
code: lambda.Code | string;
|
|
9
|
+
/** Constructs that must be created before the migration runs */
|
|
10
|
+
dependencies?: Construct[];
|
|
11
|
+
/** Lambda handler entry point */
|
|
12
|
+
handler?: string;
|
|
13
|
+
/** Secrets to make available to the migration Lambda */
|
|
14
|
+
secrets?: SecretsArrayItem[];
|
|
15
|
+
/** DynamoDB tables to grant read/write access */
|
|
16
|
+
tables?: dynamodb.ITable[];
|
|
17
|
+
}
|
|
18
|
+
export declare class JaypieMigration extends Construct {
|
|
19
|
+
readonly lambda: JaypieLambda;
|
|
20
|
+
constructor(scope: Construct, id: string, props: JaypieMigrationProps);
|
|
21
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IBucket } from "aws-cdk-lib/aws-s3";
|
|
2
|
+
import { CfnAnalyzer } from "aws-cdk-lib/aws-accessanalyzer";
|
|
2
3
|
import { Trail } from "aws-cdk-lib/aws-cloudtrail";
|
|
3
4
|
import { Construct } from "constructs";
|
|
4
5
|
export interface JaypieOrganizationTrailProps {
|
|
@@ -26,11 +27,26 @@ export interface JaypieOrganizationTrailProps {
|
|
|
26
27
|
* Optional project tag value
|
|
27
28
|
*/
|
|
28
29
|
project?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Whether to enable IAM Access Analyzer (organization-level)
|
|
32
|
+
* @default true
|
|
33
|
+
*/
|
|
34
|
+
enableAccessAnalyzer?: boolean;
|
|
29
35
|
/**
|
|
30
36
|
* Whether to enable file validation for the trail
|
|
31
|
-
* @default
|
|
37
|
+
* @default true
|
|
32
38
|
*/
|
|
33
39
|
enableFileValidation?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Whether to enable Lambda data events in CloudTrail
|
|
42
|
+
* @default true
|
|
43
|
+
*/
|
|
44
|
+
enableLambdaDataEvents?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Whether to enable S3 data events in CloudTrail
|
|
47
|
+
* @default false (opt-in due to potential high volume/cost)
|
|
48
|
+
*/
|
|
49
|
+
enableS3DataEvents?: boolean;
|
|
34
50
|
/**
|
|
35
51
|
* Number of days before logs expire
|
|
36
52
|
* @default 365
|
|
@@ -53,6 +69,7 @@ export interface JaypieOrganizationTrailProps {
|
|
|
53
69
|
enableDatadogNotifications?: boolean;
|
|
54
70
|
}
|
|
55
71
|
export declare class JaypieOrganizationTrail extends Construct {
|
|
72
|
+
readonly analyzer?: CfnAnalyzer;
|
|
56
73
|
readonly bucket: IBucket;
|
|
57
74
|
readonly trail: Trail;
|
|
58
75
|
/**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { JaypieCertificate, JaypieCertificateProps } from "./JaypieCertificate";
|
|
|
7
7
|
export { JaypieDatadogBucket, JaypieDatadogBucketProps, } from "./JaypieDatadogBucket";
|
|
8
8
|
export { JaypieDatadogForwarder, JaypieDatadogForwarderProps, } from "./JaypieDatadogForwarder";
|
|
9
9
|
export { JaypieDatadogSecret } from "./JaypieDatadogSecret";
|
|
10
|
-
export { JaypieDistribution, JaypieDistributionProps, SecurityHeadersOverrides, } from "./JaypieDistribution";
|
|
10
|
+
export { JaypieDistribution, JaypieDistributionProps, JaypieWafConfig, SecurityHeadersOverrides, } from "./JaypieDistribution";
|
|
11
11
|
export { JaypieDnsRecord, JaypieDnsRecordProps } from "./JaypieDnsRecord";
|
|
12
12
|
export { JaypieDynamoDb, JaypieDynamoDbProps } from "./JaypieDynamoDb";
|
|
13
13
|
export type { IndexDefinition } from "@jaypie/fabric";
|
|
@@ -18,6 +18,7 @@ export { JaypieGitHubDeployRole, JaypieGitHubDeployRoleProps, } from "./JaypieGi
|
|
|
18
18
|
export { JaypieHostedZone, JaypieHostedZoneRecordProps, } from "./JaypieHostedZone";
|
|
19
19
|
export { JaypieInfrastructureStack } from "./JaypieInfrastructureStack";
|
|
20
20
|
export { JaypieLambda, JaypieLambdaProps } from "./JaypieLambda";
|
|
21
|
+
export { JaypieMigration, JaypieMigrationProps } from "./JaypieMigration";
|
|
21
22
|
export { JaypieMongoDbSecret } from "./JaypieMongoDbSecret";
|
|
22
23
|
export { DomainNameConfig, JaypieNextJs, JaypieNextjsProps, } from "./JaypieNextJs";
|
|
23
24
|
export { JaypieOpenAiSecret } from "./JaypieOpenAiSecret";
|
package/dist/esm/index.js
CHANGED
|
@@ -24,10 +24,13 @@ import { Rule, RuleTargetInput } from 'aws-cdk-lib/aws-events';
|
|
|
24
24
|
import { LambdaFunction } from 'aws-cdk-lib/aws-events-targets';
|
|
25
25
|
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
|
|
26
26
|
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
|
|
27
|
+
import * as wafv2 from 'aws-cdk-lib/aws-wafv2';
|
|
27
28
|
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
|
|
28
29
|
import { generateIndexName, DEFAULT_SORT_KEY } from '@jaypie/fabric';
|
|
30
|
+
import * as cr from 'aws-cdk-lib/custom-resources';
|
|
29
31
|
import { Nextjs } from 'cdk-nextjs-standalone';
|
|
30
32
|
import * as path from 'path';
|
|
33
|
+
import { CfnAnalyzer } from 'aws-cdk-lib/aws-accessanalyzer';
|
|
31
34
|
import { Trail, ReadWriteType } from 'aws-cdk-lib/aws-cloudtrail';
|
|
32
35
|
import { CfnPermissionSet, CfnAssignment } from 'aws-cdk-lib/aws-sso';
|
|
33
36
|
import { CfnApplication } from 'aws-cdk-lib/aws-sam';
|
|
@@ -2340,10 +2343,15 @@ class JaypieDatadogSecret extends JaypieEnvSecret {
|
|
|
2340
2343
|
}
|
|
2341
2344
|
}
|
|
2342
2345
|
|
|
2346
|
+
const DEFAULT_RATE_LIMIT = 2000;
|
|
2347
|
+
const DEFAULT_MANAGED_RULES = [
|
|
2348
|
+
"AWSManagedRulesCommonRuleSet",
|
|
2349
|
+
"AWSManagedRulesKnownBadInputsRuleSet",
|
|
2350
|
+
];
|
|
2343
2351
|
class JaypieDistribution extends Construct {
|
|
2344
2352
|
constructor(scope, id, props) {
|
|
2345
2353
|
super(scope, id);
|
|
2346
|
-
const { certificate: certificateProp = true, defaultBehavior: propsDefaultBehavior, destination: destinationProp = true, handler, host: propsHost, logBucket: logBucketProp, originReadTimeout = Duration.seconds(CDK$2.DURATION.CLOUDFRONT_API), responseHeadersPolicy: responseHeadersPolicyProp, roleTag = CDK$2.ROLE.API, securityHeaders: securityHeadersProp, streaming = false, zone: propsZone, ...distributionProps } = props;
|
|
2354
|
+
const { certificate: certificateProp = true, defaultBehavior: propsDefaultBehavior, destination: destinationProp = true, handler, host: propsHost, logBucket: logBucketProp, originReadTimeout = Duration.seconds(CDK$2.DURATION.CLOUDFRONT_API), responseHeadersPolicy: responseHeadersPolicyProp, roleTag = CDK$2.ROLE.API, securityHeaders: securityHeadersProp, streaming = false, waf: wafProp = true, zone: propsZone, ...distributionProps } = props;
|
|
2347
2355
|
// Validate environment variables
|
|
2348
2356
|
if (process.env.CDK_ENV_API_SUBDOMAIN &&
|
|
2349
2357
|
!isValidSubdomain(process.env.CDK_ENV_API_SUBDOMAIN)) {
|
|
@@ -2586,6 +2594,118 @@ class JaypieDistribution extends Construct {
|
|
|
2586
2594
|
this.distributionDomainName = this.distribution.distributionDomainName;
|
|
2587
2595
|
this.distributionId = this.distribution.distributionId;
|
|
2588
2596
|
this.domainName = this.distribution.domainName;
|
|
2597
|
+
// Create and attach WAF WebACL
|
|
2598
|
+
let resolvedWebAclArn;
|
|
2599
|
+
const wafConfig = this.resolveWafConfig(wafProp);
|
|
2600
|
+
if (wafConfig) {
|
|
2601
|
+
if (wafConfig.webAclArn) {
|
|
2602
|
+
// Use existing WebACL
|
|
2603
|
+
resolvedWebAclArn = wafConfig.webAclArn;
|
|
2604
|
+
this.distribution.attachWebAclId(wafConfig.webAclArn);
|
|
2605
|
+
}
|
|
2606
|
+
else {
|
|
2607
|
+
// Create new WebACL
|
|
2608
|
+
const { managedRules = DEFAULT_MANAGED_RULES, rateLimitPerIp = DEFAULT_RATE_LIMIT, } = wafConfig;
|
|
2609
|
+
let priority = 0;
|
|
2610
|
+
const rules = [];
|
|
2611
|
+
// Add managed rule groups
|
|
2612
|
+
for (const ruleName of managedRules) {
|
|
2613
|
+
rules.push({
|
|
2614
|
+
name: ruleName,
|
|
2615
|
+
priority: priority++,
|
|
2616
|
+
overrideAction: { none: {} },
|
|
2617
|
+
statement: {
|
|
2618
|
+
managedRuleGroupStatement: {
|
|
2619
|
+
name: ruleName,
|
|
2620
|
+
vendorName: "AWS",
|
|
2621
|
+
},
|
|
2622
|
+
},
|
|
2623
|
+
visibilityConfig: {
|
|
2624
|
+
cloudWatchMetricsEnabled: true,
|
|
2625
|
+
metricName: ruleName,
|
|
2626
|
+
sampledRequestsEnabled: true,
|
|
2627
|
+
},
|
|
2628
|
+
});
|
|
2629
|
+
}
|
|
2630
|
+
// Add rate-based rule
|
|
2631
|
+
rules.push({
|
|
2632
|
+
name: "RateLimitPerIp",
|
|
2633
|
+
priority: priority++,
|
|
2634
|
+
action: { block: {} },
|
|
2635
|
+
statement: {
|
|
2636
|
+
rateBasedStatement: {
|
|
2637
|
+
aggregateKeyType: "IP",
|
|
2638
|
+
limit: rateLimitPerIp,
|
|
2639
|
+
},
|
|
2640
|
+
},
|
|
2641
|
+
visibilityConfig: {
|
|
2642
|
+
cloudWatchMetricsEnabled: true,
|
|
2643
|
+
metricName: "RateLimitPerIp",
|
|
2644
|
+
sampledRequestsEnabled: true,
|
|
2645
|
+
},
|
|
2646
|
+
});
|
|
2647
|
+
const webAcl = new wafv2.CfnWebACL(this, "WebAcl", {
|
|
2648
|
+
defaultAction: { allow: {} },
|
|
2649
|
+
name: constructEnvName("WebAcl"),
|
|
2650
|
+
rules,
|
|
2651
|
+
scope: "CLOUDFRONT",
|
|
2652
|
+
visibilityConfig: {
|
|
2653
|
+
cloudWatchMetricsEnabled: true,
|
|
2654
|
+
metricName: constructEnvName("WebAcl"),
|
|
2655
|
+
sampledRequestsEnabled: true,
|
|
2656
|
+
},
|
|
2657
|
+
});
|
|
2658
|
+
this.webAcl = webAcl;
|
|
2659
|
+
resolvedWebAclArn = webAcl.attrArn;
|
|
2660
|
+
this.distribution.attachWebAclId(webAcl.attrArn);
|
|
2661
|
+
Tags.of(webAcl).add(CDK$2.TAG.ROLE, roleTag);
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
// Create WAF logging
|
|
2665
|
+
if (resolvedWebAclArn && wafConfig) {
|
|
2666
|
+
const { logBucket: wafLogBucketProp = true } = wafConfig;
|
|
2667
|
+
let wafLogBucket;
|
|
2668
|
+
if (wafLogBucketProp === true) {
|
|
2669
|
+
// Create inline WAF logging bucket with Datadog forwarding
|
|
2670
|
+
const createdBucket = new s3.Bucket(this, constructEnvName("WafLogBucket"), {
|
|
2671
|
+
bucketName: `aws-waf-logs-${constructEnvName("waf").toLowerCase()}`,
|
|
2672
|
+
lifecycleRules: [
|
|
2673
|
+
{
|
|
2674
|
+
expiration: Duration.days(90),
|
|
2675
|
+
transitions: [
|
|
2676
|
+
{
|
|
2677
|
+
storageClass: s3.StorageClass.INFREQUENT_ACCESS,
|
|
2678
|
+
transitionAfter: Duration.days(30),
|
|
2679
|
+
},
|
|
2680
|
+
],
|
|
2681
|
+
},
|
|
2682
|
+
],
|
|
2683
|
+
objectOwnership: s3.ObjectOwnership.OBJECT_WRITER,
|
|
2684
|
+
removalPolicy: RemovalPolicy.RETAIN,
|
|
2685
|
+
});
|
|
2686
|
+
Tags.of(createdBucket).add(CDK$2.TAG.ROLE, CDK$2.ROLE.MONITORING);
|
|
2687
|
+
// Add Datadog forwarder notification
|
|
2688
|
+
if (destinationProp !== false) {
|
|
2689
|
+
const lambdaDestination = destinationProp === true
|
|
2690
|
+
? new LambdaDestination(resolveDatadogForwarderFunction(this))
|
|
2691
|
+
: destinationProp;
|
|
2692
|
+
createdBucket.addEventNotification(s3.EventType.OBJECT_CREATED, lambdaDestination);
|
|
2693
|
+
}
|
|
2694
|
+
wafLogBucket = createdBucket;
|
|
2695
|
+
}
|
|
2696
|
+
else if (typeof wafLogBucketProp === "object") {
|
|
2697
|
+
// Use provided IBucket
|
|
2698
|
+
wafLogBucket = wafLogBucketProp;
|
|
2699
|
+
}
|
|
2700
|
+
// wafLogBucketProp === false → no logging
|
|
2701
|
+
if (wafLogBucket) {
|
|
2702
|
+
this.wafLogBucket = wafLogBucket;
|
|
2703
|
+
new wafv2.CfnLoggingConfiguration(this, "WafLoggingConfig", {
|
|
2704
|
+
logDestinationConfigs: [wafLogBucket.bucketArn],
|
|
2705
|
+
resourceArn: resolvedWebAclArn,
|
|
2706
|
+
});
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2589
2709
|
// Create DNS records if we have host and zone
|
|
2590
2710
|
if (host && hostedZone) {
|
|
2591
2711
|
const aRecord = new route53.ARecord(this, "AliasRecord", {
|
|
@@ -2632,6 +2752,15 @@ class JaypieDistribution extends Construct {
|
|
|
2632
2752
|
"exportName" in value &&
|
|
2633
2753
|
typeof value.exportName === "string");
|
|
2634
2754
|
}
|
|
2755
|
+
resolveWafConfig(wafProp) {
|
|
2756
|
+
if (wafProp === false)
|
|
2757
|
+
return undefined;
|
|
2758
|
+
if (wafProp === true)
|
|
2759
|
+
return {};
|
|
2760
|
+
if (wafProp.enabled === false)
|
|
2761
|
+
return undefined;
|
|
2762
|
+
return wafProp;
|
|
2763
|
+
}
|
|
2635
2764
|
resolveLogBucket(logBucketProp) {
|
|
2636
2765
|
// true = use account logging bucket
|
|
2637
2766
|
if (logBucketProp === true) {
|
|
@@ -2895,6 +3024,9 @@ class JaypieDynamoDb extends Construct {
|
|
|
2895
3024
|
get encryptionKey() {
|
|
2896
3025
|
return this._table.encryptionKey;
|
|
2897
3026
|
}
|
|
3027
|
+
get grants() {
|
|
3028
|
+
return this._table.grants;
|
|
3029
|
+
}
|
|
2898
3030
|
applyRemovalPolicy(policy) {
|
|
2899
3031
|
this._table.applyRemovalPolicy(policy);
|
|
2900
3032
|
}
|
|
@@ -3253,6 +3385,35 @@ class JaypieInfrastructureStack extends JaypieStack {
|
|
|
3253
3385
|
}
|
|
3254
3386
|
}
|
|
3255
3387
|
|
|
3388
|
+
class JaypieMigration extends Construct {
|
|
3389
|
+
constructor(scope, id, props) {
|
|
3390
|
+
super(scope, id);
|
|
3391
|
+
const { code, dependencies = [], handler = "index.handler", secrets = [], tables = [], } = props;
|
|
3392
|
+
// Migration Lambda — 5 minute timeout for long-running migrations
|
|
3393
|
+
this.lambda = new JaypieLambda(this, "MigrationLambda", {
|
|
3394
|
+
code,
|
|
3395
|
+
description: "DynamoDB migration custom resource",
|
|
3396
|
+
handler,
|
|
3397
|
+
roleTag: CDK$2.ROLE.PROCESSING,
|
|
3398
|
+
secrets,
|
|
3399
|
+
tables,
|
|
3400
|
+
timeout: cdk.Duration.minutes(5),
|
|
3401
|
+
});
|
|
3402
|
+
// Custom Resource provider wrapping the Lambda
|
|
3403
|
+
const provider = new cr.Provider(this, "MigrationProvider", {
|
|
3404
|
+
onEventHandler: this.lambda,
|
|
3405
|
+
});
|
|
3406
|
+
// Custom Resource that triggers on every deploy
|
|
3407
|
+
const resource = new cdk.CustomResource(this, "MigrationResource", {
|
|
3408
|
+
serviceToken: provider.serviceToken,
|
|
3409
|
+
});
|
|
3410
|
+
// Ensure dependencies are created before the migration runs
|
|
3411
|
+
for (const dep of dependencies) {
|
|
3412
|
+
resource.node.addDependency(dep);
|
|
3413
|
+
}
|
|
3414
|
+
}
|
|
3415
|
+
}
|
|
3416
|
+
|
|
3256
3417
|
class JaypieMongoDbSecret extends JaypieEnvSecret {
|
|
3257
3418
|
constructor(scope, id = "MongoConnectionString", props) {
|
|
3258
3419
|
const defaultProps = {
|
|
@@ -3471,7 +3632,7 @@ class JaypieOrganizationTrail extends Construct {
|
|
|
3471
3632
|
// Resolve options with defaults
|
|
3472
3633
|
const { bucketName = process.env.PROJECT_NONCE
|
|
3473
3634
|
? `organization-cloudtrail-${process.env.PROJECT_NONCE}`
|
|
3474
|
-
: "organization-cloudtrail", enableDatadogNotifications = true, enableFileValidation = false, expirationDays = 365, glacierTransitionDays = 180, infrequentAccessTransitionDays = 30, project, service = CDK$2.SERVICE.INFRASTRUCTURE, trailName = process.env.PROJECT_NONCE
|
|
3635
|
+
: "organization-cloudtrail", enableAccessAnalyzer = true, enableDatadogNotifications = true, enableFileValidation = true, enableLambdaDataEvents = true, enableS3DataEvents = false, expirationDays = 365, glacierTransitionDays = 180, infrequentAccessTransitionDays = 30, project, service = CDK$2.SERVICE.INFRASTRUCTURE, trailName = process.env.PROJECT_NONCE
|
|
3475
3636
|
? `organization-cloudtrail-${process.env.PROJECT_NONCE}`
|
|
3476
3637
|
: "organization-cloudtrail", } = props;
|
|
3477
3638
|
// Create the S3 bucket for CloudTrail logs
|
|
@@ -3531,12 +3692,34 @@ class JaypieOrganizationTrail extends Construct {
|
|
|
3531
3692
|
managementEvents: ReadWriteType.ALL,
|
|
3532
3693
|
trailName,
|
|
3533
3694
|
});
|
|
3695
|
+
// Add data event selectors
|
|
3696
|
+
if (enableLambdaDataEvents) {
|
|
3697
|
+
this.trail.logAllLambdaDataEvents();
|
|
3698
|
+
}
|
|
3699
|
+
if (enableS3DataEvents) {
|
|
3700
|
+
this.trail.logAllS3DataEvents();
|
|
3701
|
+
}
|
|
3534
3702
|
// Add tags to trail
|
|
3535
3703
|
cdk.Tags.of(this.trail).add(CDK$2.TAG.SERVICE, service);
|
|
3536
3704
|
cdk.Tags.of(this.trail).add(CDK$2.TAG.ROLE, CDK$2.ROLE.MONITORING);
|
|
3537
3705
|
if (project) {
|
|
3538
3706
|
cdk.Tags.of(this.trail).add(CDK$2.TAG.PROJECT, project);
|
|
3539
3707
|
}
|
|
3708
|
+
// Create IAM Access Analyzer
|
|
3709
|
+
if (enableAccessAnalyzer) {
|
|
3710
|
+
const analyzerName = process.env.PROJECT_NONCE
|
|
3711
|
+
? `organization-access-analyzer-${process.env.PROJECT_NONCE}`
|
|
3712
|
+
: "organization-access-analyzer";
|
|
3713
|
+
this.analyzer = new CfnAnalyzer(this, "AccessAnalyzer", {
|
|
3714
|
+
analyzerName,
|
|
3715
|
+
type: "ORGANIZATION",
|
|
3716
|
+
});
|
|
3717
|
+
cdk.Tags.of(this.analyzer).add(CDK$2.TAG.SERVICE, service);
|
|
3718
|
+
cdk.Tags.of(this.analyzer).add(CDK$2.TAG.ROLE, CDK$2.ROLE.MONITORING);
|
|
3719
|
+
if (project) {
|
|
3720
|
+
cdk.Tags.of(this.analyzer).add(CDK$2.TAG.PROJECT, project);
|
|
3721
|
+
}
|
|
3722
|
+
}
|
|
3540
3723
|
}
|
|
3541
3724
|
}
|
|
3542
3725
|
|
|
@@ -4580,5 +4763,5 @@ class JaypieWebSocketTable extends Construct {
|
|
|
4580
4763
|
}
|
|
4581
4764
|
}
|
|
4582
4765
|
|
|
4583
|
-
export { CDK$2 as CDK, JaypieAccountLoggingBucket, JaypieApiGateway, JaypieAppStack, JaypieBucketQueuedLambda, JaypieCertificate, JaypieDatadogBucket, JaypieDatadogForwarder, JaypieDatadogSecret, JaypieDistribution, JaypieDnsRecord, JaypieDynamoDb, JaypieEnvSecret, JaypieEventsRule, JaypieExpressLambda, JaypieGitHubDeployRole, JaypieHostedZone, JaypieInfrastructureStack, JaypieLambda, JaypieMongoDbSecret, JaypieNextJs, JaypieOpenAiSecret, JaypieOrganizationTrail, JaypieQueuedLambda, JaypieSsoPermissions, JaypieSsoSyncApplication, JaypieStack, JaypieStaticWebBucket, JaypieTraceSigningKeySecret, JaypieWebDeploymentBucket, JaypieWebSocket, JaypieWebSocketLambda, JaypieWebSocketTable, addDatadogLayers, clearAllCertificateCaches, clearAllSecretsCaches, clearCertificateCache, clearSecretsCache, constructEnvName, constructStackName, constructTagger, envHostname, extendDatadogRole, isEnv, isProductionEnv, isSandboxEnv, isValidHostname$1 as isValidHostname, isValidSubdomain, jaypieLambdaEnv, mergeDomain, resolveCertificate, resolveDatadogForwarderFunction, resolveDatadogLayers, resolveDatadogLoggingDestination, resolveEnvironment, resolveHostedZone, resolveParamsAndSecrets, resolveSecrets };
|
|
4766
|
+
export { CDK$2 as CDK, JaypieAccountLoggingBucket, JaypieApiGateway, JaypieAppStack, JaypieBucketQueuedLambda, JaypieCertificate, JaypieDatadogBucket, JaypieDatadogForwarder, JaypieDatadogSecret, JaypieDistribution, JaypieDnsRecord, JaypieDynamoDb, JaypieEnvSecret, JaypieEventsRule, JaypieExpressLambda, JaypieGitHubDeployRole, JaypieHostedZone, JaypieInfrastructureStack, JaypieLambda, JaypieMigration, JaypieMongoDbSecret, JaypieNextJs, JaypieOpenAiSecret, JaypieOrganizationTrail, JaypieQueuedLambda, JaypieSsoPermissions, JaypieSsoSyncApplication, JaypieStack, JaypieStaticWebBucket, JaypieTraceSigningKeySecret, JaypieWebDeploymentBucket, JaypieWebSocket, JaypieWebSocketLambda, JaypieWebSocketTable, addDatadogLayers, clearAllCertificateCaches, clearAllSecretsCaches, clearCertificateCache, clearSecretsCache, constructEnvName, constructStackName, constructTagger, envHostname, extendDatadogRole, isEnv, isProductionEnv, isSandboxEnv, isValidHostname$1 as isValidHostname, isValidSubdomain, jaypieLambdaEnv, mergeDomain, resolveCertificate, resolveDatadogForwarderFunction, resolveDatadogLayers, resolveDatadogLoggingDestination, resolveEnvironment, resolveHostedZone, resolveParamsAndSecrets, resolveSecrets };
|
|
4584
4767
|
//# sourceMappingURL=index.js.map
|