@jaypie/constructs 1.2.31 → 1.2.33
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/JaypieEnvSecret.d.ts +1 -0
- package/dist/cjs/JaypieOrganizationTrail.d.ts +18 -1
- package/dist/cjs/__tests__/JaypieOrganizationTrail.spec.d.ts +1 -0
- package/dist/cjs/index.cjs +163 -3
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/esm/JaypieDistribution.d.ts +41 -0
- package/dist/esm/JaypieEnvSecret.d.ts +1 -0
- package/dist/esm/JaypieOrganizationTrail.d.ts +18 -1
- package/dist/esm/__tests__/JaypieOrganizationTrail.spec.d.ts +1 -0
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +163 -4
- 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";
|
|
@@ -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;
|
|
@@ -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 {};
|
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";
|
package/dist/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as cdk from 'aws-cdk-lib';
|
|
2
|
-
import { Tags, Stack, Fn, CfnOutput, SecretValue,
|
|
2
|
+
import { Tags, Stack, Fn, CfnOutput, SecretValue, RemovalPolicy, Duration, CfnStack } from 'aws-cdk-lib';
|
|
3
3
|
import * as s3 from 'aws-cdk-lib/aws-s3';
|
|
4
4
|
import { Bucket, StorageClass, BucketAccessControl, EventType } from 'aws-cdk-lib/aws-s3';
|
|
5
5
|
import { Construct } from 'constructs';
|
|
@@ -24,10 +24,12 @@ 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';
|
|
29
30
|
import { Nextjs } from 'cdk-nextjs-standalone';
|
|
30
31
|
import * as path from 'path';
|
|
32
|
+
import { CfnAnalyzer } from 'aws-cdk-lib/aws-accessanalyzer';
|
|
31
33
|
import { Trail, ReadWriteType } from 'aws-cdk-lib/aws-cloudtrail';
|
|
32
34
|
import { CfnPermissionSet, CfnAssignment } from 'aws-cdk-lib/aws-sso';
|
|
33
35
|
import { CfnApplication } from 'aws-cdk-lib/aws-sam';
|
|
@@ -911,7 +913,7 @@ class JaypieEnvSecret extends Construct {
|
|
|
911
913
|
process.env[idOrEnvKey] !== "";
|
|
912
914
|
const id = treatAsEnvKey ? `EnvSecret_${idOrEnvKey}` : idOrEnvKey;
|
|
913
915
|
super(scope, id);
|
|
914
|
-
const { consumer = checkEnvIsConsumer$1(), envKey: envKeyProp, export: exportParam, generateSecretString, provider = checkEnvIsProvider$1(), roleTag, vendorTag, value, } = props || {};
|
|
916
|
+
const { consumer = checkEnvIsConsumer$1(), envKey: envKeyProp, export: exportParam, generateSecretString, provider = checkEnvIsProvider$1(), removalPolicy, roleTag, vendorTag, value, } = props || {};
|
|
915
917
|
const envKey = treatAsEnvKey ? idOrEnvKey : envKeyProp;
|
|
916
918
|
this._envKey = envKey;
|
|
917
919
|
let exportName;
|
|
@@ -938,6 +940,14 @@ class JaypieEnvSecret extends Construct {
|
|
|
938
940
|
: undefined,
|
|
939
941
|
};
|
|
940
942
|
this._secret = new secretsmanager.Secret(this, id, secretProps);
|
|
943
|
+
if (removalPolicy !== undefined) {
|
|
944
|
+
const policy = typeof removalPolicy === "boolean"
|
|
945
|
+
? removalPolicy
|
|
946
|
+
? RemovalPolicy.RETAIN
|
|
947
|
+
: RemovalPolicy.DESTROY
|
|
948
|
+
: removalPolicy;
|
|
949
|
+
this._secret.applyRemovalPolicy(policy);
|
|
950
|
+
}
|
|
941
951
|
if (roleTag) {
|
|
942
952
|
Tags.of(this._secret).add(CDK$2.TAG.ROLE, roleTag);
|
|
943
953
|
}
|
|
@@ -2332,10 +2342,15 @@ class JaypieDatadogSecret extends JaypieEnvSecret {
|
|
|
2332
2342
|
}
|
|
2333
2343
|
}
|
|
2334
2344
|
|
|
2345
|
+
const DEFAULT_RATE_LIMIT = 2000;
|
|
2346
|
+
const DEFAULT_MANAGED_RULES = [
|
|
2347
|
+
"AWSManagedRulesCommonRuleSet",
|
|
2348
|
+
"AWSManagedRulesKnownBadInputsRuleSet",
|
|
2349
|
+
];
|
|
2335
2350
|
class JaypieDistribution extends Construct {
|
|
2336
2351
|
constructor(scope, id, props) {
|
|
2337
2352
|
super(scope, id);
|
|
2338
|
-
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;
|
|
2353
|
+
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;
|
|
2339
2354
|
// Validate environment variables
|
|
2340
2355
|
if (process.env.CDK_ENV_API_SUBDOMAIN &&
|
|
2341
2356
|
!isValidSubdomain(process.env.CDK_ENV_API_SUBDOMAIN)) {
|
|
@@ -2578,6 +2593,119 @@ class JaypieDistribution extends Construct {
|
|
|
2578
2593
|
this.distributionDomainName = this.distribution.distributionDomainName;
|
|
2579
2594
|
this.distributionId = this.distribution.distributionId;
|
|
2580
2595
|
this.domainName = this.distribution.domainName;
|
|
2596
|
+
// Create and attach WAF WebACL
|
|
2597
|
+
let resolvedWebAclArn;
|
|
2598
|
+
const wafConfig = this.resolveWafConfig(wafProp);
|
|
2599
|
+
if (wafConfig) {
|
|
2600
|
+
if (wafConfig.webAclArn) {
|
|
2601
|
+
// Use existing WebACL
|
|
2602
|
+
resolvedWebAclArn = wafConfig.webAclArn;
|
|
2603
|
+
this.distribution.attachWebAclId(wafConfig.webAclArn);
|
|
2604
|
+
}
|
|
2605
|
+
else {
|
|
2606
|
+
// Create new WebACL
|
|
2607
|
+
const { managedRules = DEFAULT_MANAGED_RULES, rateLimitPerIp = DEFAULT_RATE_LIMIT, } = wafConfig;
|
|
2608
|
+
let priority = 0;
|
|
2609
|
+
const rules = [];
|
|
2610
|
+
// Add managed rule groups
|
|
2611
|
+
for (const ruleName of managedRules) {
|
|
2612
|
+
rules.push({
|
|
2613
|
+
name: ruleName,
|
|
2614
|
+
priority: priority++,
|
|
2615
|
+
overrideAction: { none: {} },
|
|
2616
|
+
statement: {
|
|
2617
|
+
managedRuleGroupStatement: {
|
|
2618
|
+
name: ruleName,
|
|
2619
|
+
vendorName: "AWS",
|
|
2620
|
+
},
|
|
2621
|
+
},
|
|
2622
|
+
visibilityConfig: {
|
|
2623
|
+
cloudWatchMetricsEnabled: true,
|
|
2624
|
+
metricName: ruleName,
|
|
2625
|
+
sampledRequestsEnabled: true,
|
|
2626
|
+
},
|
|
2627
|
+
});
|
|
2628
|
+
}
|
|
2629
|
+
// Add rate-based rule
|
|
2630
|
+
rules.push({
|
|
2631
|
+
name: "RateLimitPerIp",
|
|
2632
|
+
priority: priority++,
|
|
2633
|
+
action: { block: {} },
|
|
2634
|
+
statement: {
|
|
2635
|
+
rateBasedStatement: {
|
|
2636
|
+
aggregateKeyType: "IP",
|
|
2637
|
+
limit: rateLimitPerIp,
|
|
2638
|
+
},
|
|
2639
|
+
},
|
|
2640
|
+
visibilityConfig: {
|
|
2641
|
+
cloudWatchMetricsEnabled: true,
|
|
2642
|
+
metricName: "RateLimitPerIp",
|
|
2643
|
+
sampledRequestsEnabled: true,
|
|
2644
|
+
},
|
|
2645
|
+
});
|
|
2646
|
+
const webAcl = new wafv2.CfnWebACL(this, "WebAcl", {
|
|
2647
|
+
defaultAction: { allow: {} },
|
|
2648
|
+
name: constructEnvName("WebAcl"),
|
|
2649
|
+
rules,
|
|
2650
|
+
scope: "CLOUDFRONT",
|
|
2651
|
+
visibilityConfig: {
|
|
2652
|
+
cloudWatchMetricsEnabled: true,
|
|
2653
|
+
metricName: constructEnvName("WebAcl"),
|
|
2654
|
+
sampledRequestsEnabled: true,
|
|
2655
|
+
},
|
|
2656
|
+
});
|
|
2657
|
+
this.webAcl = webAcl;
|
|
2658
|
+
resolvedWebAclArn = webAcl.attrArn;
|
|
2659
|
+
this.distribution.attachWebAclId(webAcl.attrArn);
|
|
2660
|
+
Tags.of(webAcl).add(CDK$2.TAG.ROLE, roleTag);
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
// Create WAF logging
|
|
2664
|
+
if (resolvedWebAclArn && wafConfig) {
|
|
2665
|
+
const { logBucket: wafLogBucketProp = true } = wafConfig;
|
|
2666
|
+
let wafLogBucket;
|
|
2667
|
+
if (wafLogBucketProp === true) {
|
|
2668
|
+
// Create inline WAF logging bucket with Datadog forwarding
|
|
2669
|
+
const createdBucket = new s3.Bucket(this, constructEnvName("WafLogBucket"), {
|
|
2670
|
+
autoDeleteObjects: true,
|
|
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.DESTROY,
|
|
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
|
+
}
|
|
2581
2709
|
// Create DNS records if we have host and zone
|
|
2582
2710
|
if (host && hostedZone) {
|
|
2583
2711
|
const aRecord = new route53.ARecord(this, "AliasRecord", {
|
|
@@ -2624,6 +2752,15 @@ class JaypieDistribution extends Construct {
|
|
|
2624
2752
|
"exportName" in value &&
|
|
2625
2753
|
typeof value.exportName === "string");
|
|
2626
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
|
+
}
|
|
2627
2764
|
resolveLogBucket(logBucketProp) {
|
|
2628
2765
|
// true = use account logging bucket
|
|
2629
2766
|
if (logBucketProp === true) {
|
|
@@ -3463,7 +3600,7 @@ class JaypieOrganizationTrail extends Construct {
|
|
|
3463
3600
|
// Resolve options with defaults
|
|
3464
3601
|
const { bucketName = process.env.PROJECT_NONCE
|
|
3465
3602
|
? `organization-cloudtrail-${process.env.PROJECT_NONCE}`
|
|
3466
|
-
: "organization-cloudtrail", enableDatadogNotifications = true, enableFileValidation = false, expirationDays = 365, glacierTransitionDays = 180, infrequentAccessTransitionDays = 30, project, service = CDK$2.SERVICE.INFRASTRUCTURE, trailName = process.env.PROJECT_NONCE
|
|
3603
|
+
: "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
|
|
3467
3604
|
? `organization-cloudtrail-${process.env.PROJECT_NONCE}`
|
|
3468
3605
|
: "organization-cloudtrail", } = props;
|
|
3469
3606
|
// Create the S3 bucket for CloudTrail logs
|
|
@@ -3523,12 +3660,34 @@ class JaypieOrganizationTrail extends Construct {
|
|
|
3523
3660
|
managementEvents: ReadWriteType.ALL,
|
|
3524
3661
|
trailName,
|
|
3525
3662
|
});
|
|
3663
|
+
// Add data event selectors
|
|
3664
|
+
if (enableLambdaDataEvents) {
|
|
3665
|
+
this.trail.logAllLambdaDataEvents();
|
|
3666
|
+
}
|
|
3667
|
+
if (enableS3DataEvents) {
|
|
3668
|
+
this.trail.logAllS3DataEvents();
|
|
3669
|
+
}
|
|
3526
3670
|
// Add tags to trail
|
|
3527
3671
|
cdk.Tags.of(this.trail).add(CDK$2.TAG.SERVICE, service);
|
|
3528
3672
|
cdk.Tags.of(this.trail).add(CDK$2.TAG.ROLE, CDK$2.ROLE.MONITORING);
|
|
3529
3673
|
if (project) {
|
|
3530
3674
|
cdk.Tags.of(this.trail).add(CDK$2.TAG.PROJECT, project);
|
|
3531
3675
|
}
|
|
3676
|
+
// Create IAM Access Analyzer
|
|
3677
|
+
if (enableAccessAnalyzer) {
|
|
3678
|
+
const analyzerName = process.env.PROJECT_NONCE
|
|
3679
|
+
? `organization-access-analyzer-${process.env.PROJECT_NONCE}`
|
|
3680
|
+
: "organization-access-analyzer";
|
|
3681
|
+
this.analyzer = new CfnAnalyzer(this, "AccessAnalyzer", {
|
|
3682
|
+
analyzerName,
|
|
3683
|
+
type: "ORGANIZATION",
|
|
3684
|
+
});
|
|
3685
|
+
cdk.Tags.of(this.analyzer).add(CDK$2.TAG.SERVICE, service);
|
|
3686
|
+
cdk.Tags.of(this.analyzer).add(CDK$2.TAG.ROLE, CDK$2.ROLE.MONITORING);
|
|
3687
|
+
if (project) {
|
|
3688
|
+
cdk.Tags.of(this.analyzer).add(CDK$2.TAG.PROJECT, project);
|
|
3689
|
+
}
|
|
3690
|
+
}
|
|
3532
3691
|
}
|
|
3533
3692
|
}
|
|
3534
3693
|
|