@gradientedge/cdk-utils 5.9.0 → 5.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -477,6 +477,10 @@ class ApiToEventBridgeTarget extends common_1.CommonConstruct {
477
477
  this.apiDestinedRestApi.api = apig.RestApi.fromRestApiId(this, `${this.id}-sns-rest-api`, cdk.Fn.importValue(this.props.api.importedRestApiRef));
478
478
  return;
479
479
  }
480
+ const accessLogGroup = this.logManager.createLogGroup(`${this.id}-sns-rest-api-access-log`, this, {
481
+ logGroupName: `/custom/api/${this.id}-destined-rest-api-access-${this.props.stage}`,
482
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
483
+ });
480
484
  this.apiDestinedRestApi.api = new apig.RestApi(this, `${this.id}-sns-rest-api`, {
481
485
  ...{
482
486
  defaultIntegration: this.apiDestinedRestApi.integration,
@@ -489,6 +493,8 @@ class ApiToEventBridgeTarget extends common_1.CommonConstruct {
489
493
  loggingLevel: apig.MethodLoggingLevel.INFO,
490
494
  metricsEnabled: true,
491
495
  stageName: this.props.stage,
496
+ accessLogDestination: new apig.LogGroupLogDestination(accessLogGroup),
497
+ accessLogFormat: apig.AccessLogFormat.jsonWithStandardFields(),
492
498
  },
493
499
  endpointConfiguration: {
494
500
  types: [apig.EndpointType.REGIONAL],
@@ -9,6 +9,7 @@ import * as logs from 'aws-cdk-lib/aws-logs';
9
9
  import * as route53 from 'aws-cdk-lib/aws-route53';
10
10
  import * as s3 from 'aws-cdk-lib/aws-s3';
11
11
  import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
12
+ import * as wafv2 from 'aws-cdk-lib/aws-wafv2';
12
13
  import { Construct } from 'constructs';
13
14
  import { CommonConstruct } from '../../common';
14
15
  import { SiteWithEcsBackendProps } from '../../types';
@@ -61,6 +62,7 @@ export declare class SiteWithEcsBackend extends CommonConstruct {
61
62
  siteDomainNames: string[];
62
63
  siteCloudfrontFunction: cloudfront.Function;
63
64
  siteFunctionAssociations: cloudfront.FunctionAssociation[];
65
+ siteWebAcl: wafv2.CfnWebACL;
64
66
  constructor(parent: Construct, id: string, props: SiteWithEcsBackendProps);
65
67
  /**
66
68
  * @summary Initialise and provision resources
@@ -149,6 +151,11 @@ export declare class SiteWithEcsBackend extends CommonConstruct {
149
151
  * @protected
150
152
  */
151
153
  protected resolveSiteFunctionAssociations(): void;
154
+ /**
155
+ * @summary Method to create WAF
156
+ * @protected
157
+ */
158
+ protected createSiteWebAcl(): void;
152
159
  /**
153
160
  * Method to create Site distribution
154
161
  * @protected
@@ -80,6 +80,7 @@ class SiteWithEcsBackend extends common_1.CommonConstruct {
80
80
  siteDomainNames;
81
81
  siteCloudfrontFunction;
82
82
  siteFunctionAssociations;
83
+ siteWebAcl;
83
84
  constructor(parent, id, props) {
84
85
  super(parent, id, props);
85
86
  this.props = props;
@@ -107,6 +108,7 @@ class SiteWithEcsBackend extends common_1.CommonConstruct {
107
108
  this.createSiteOrigin();
108
109
  this.createSiteCloudfrontFunction();
109
110
  this.resolveSiteFunctionAssociations();
111
+ this.createSiteWebAcl();
110
112
  this.createDistribution();
111
113
  this.createNetworkMappings();
112
114
  this.invalidateDistributionCache();
@@ -305,12 +307,21 @@ class SiteWithEcsBackend extends common_1.CommonConstruct {
305
307
  ];
306
308
  }
307
309
  }
310
+ /**
311
+ * @summary Method to create WAF
312
+ * @protected
313
+ */
314
+ createSiteWebAcl() {
315
+ if (!this.props.siteWebAcl)
316
+ throw 'SiteWebAcl props undefined';
317
+ this.siteWebAcl = this.wafManager.createWebAcl(`${this.id}-waf`, this, this.props.siteWebAcl);
318
+ }
308
319
  /**
309
320
  * Method to create Site distribution
310
321
  * @protected
311
322
  */
312
323
  createDistribution() {
313
- this.siteDistribution = this.cloudFrontManager.createDistributionWithHttpOrigin(`${this.id}-distribution`, this, this.props.siteDistribution, this.siteOrigin, this.siteDomainNames, this.siteLogBucket, this.siteCertificate, this.siteFunctionAssociations);
324
+ this.siteDistribution = this.cloudFrontManager.createDistributionWithHttpOrigin(`${this.id}-distribution`, this, this.props.siteDistribution, this.siteOrigin, this.siteDomainNames, this.siteLogBucket, this.siteCertificate, this.siteFunctionAssociations, this.siteWebAcl.attrId);
314
325
  }
315
326
  /**
316
327
  * Method to create Route53 records for distribution
@@ -3,6 +3,7 @@ import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
3
3
  import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
4
4
  import * as route53 from 'aws-cdk-lib/aws-route53';
5
5
  import * as s3 from 'aws-cdk-lib/aws-s3';
6
+ import * as wafv2 from 'aws-cdk-lib/aws-wafv2';
6
7
  import { Construct } from 'constructs';
7
8
  import { CommonConstruct } from '../../common';
8
9
  import { StaticSiteProps } from '../../types';
@@ -39,6 +40,7 @@ export declare class StaticSite extends CommonConstruct {
39
40
  siteOriginAccessIdentity: cloudfront.OriginAccessIdentity;
40
41
  siteCloudfrontFunction: cloudfront.Function;
41
42
  siteFunctionAssociations: cloudfront.FunctionAssociation[];
43
+ siteWebAcl: wafv2.CfnWebACL;
42
44
  constructor(parent: Construct, id: string, props: StaticSiteProps);
43
45
  /**
44
46
  * @summary Initialise and provision resources
@@ -76,6 +78,11 @@ export declare class StaticSite extends CommonConstruct {
76
78
  * @protected
77
79
  */
78
80
  protected resolveSiteFunctionAssociations(): void;
81
+ /**
82
+ * @summary Method to create WAF
83
+ * @protected
84
+ */
85
+ protected createSiteWebAcl(): void;
79
86
  /**
80
87
  * @summary Method to create a site cloudfront distribution
81
88
  * @protected
@@ -62,6 +62,7 @@ class StaticSite extends common_1.CommonConstruct {
62
62
  siteOriginAccessIdentity;
63
63
  siteCloudfrontFunction;
64
64
  siteFunctionAssociations;
65
+ siteWebAcl;
65
66
  constructor(parent, id, props) {
66
67
  super(parent, id, props);
67
68
  this.props = props;
@@ -79,6 +80,7 @@ class StaticSite extends common_1.CommonConstruct {
79
80
  this.createSiteOrigin();
80
81
  this.createSiteCloudfrontFunction();
81
82
  this.resolveSiteFunctionAssociations();
83
+ this.createSiteWebAcl();
82
84
  this.createSiteDistribution();
83
85
  this.createSiteRouteAssets();
84
86
  this.deploySite();
@@ -142,6 +144,15 @@ class StaticSite extends common_1.CommonConstruct {
142
144
  ];
143
145
  }
144
146
  }
147
+ /**
148
+ * @summary Method to create WAF
149
+ * @protected
150
+ */
151
+ createSiteWebAcl() {
152
+ if (!this.props.siteWebAcl)
153
+ throw 'SiteWebAcl props undefined';
154
+ this.siteWebAcl = this.wafManager.createWebAcl(`${this.id}-waf`, this, this.props.siteWebAcl);
155
+ }
145
156
  /**
146
157
  * @summary Method to create a site cloudfront distribution
147
158
  * @protected
@@ -149,7 +160,7 @@ class StaticSite extends common_1.CommonConstruct {
149
160
  createSiteDistribution() {
150
161
  if (!this.props.siteDistribution)
151
162
  throw 'SiteDistribution props undefined';
152
- this.siteDistribution = this.cloudFrontManager.createDistributionWithS3Origin(`${this.id}-distribution`, this, this.props.siteDistribution, this.siteOrigin, this.siteBucket, this.siteLogBucket, this.siteOriginAccessIdentity, this.siteCertificate, this.props.siteAliases, this.siteFunctionAssociations);
163
+ this.siteDistribution = this.cloudFrontManager.createDistributionWithS3Origin(`${this.id}-distribution`, this, this.props.siteDistribution, this.siteOrigin, this.siteBucket, this.siteLogBucket, this.siteOriginAccessIdentity, this.siteCertificate, this.props.siteAliases, this.siteFunctionAssociations, this.siteWebAcl.attrId);
153
164
  }
154
165
  /**
155
166
  * @summary Method to create route53 records for static site
@@ -49,8 +49,9 @@ export declare class CloudFrontManager {
49
49
  * @param {cloudfront.OriginAccessIdentity?} oai
50
50
  * @param {acm.ICertificate?} certificate
51
51
  * @param {string[]?} aliases
52
+ * @param {string?} webAclId
52
53
  */
53
- createCloudFrontDistribution(id: string, scope: common.CommonConstruct, props: types.CloudFrontProps, siteBucket?: s3.IBucket, logBucket?: s3.IBucket, oai?: cloudfront.OriginAccessIdentity, certificate?: acm.ICertificate, aliases?: string[]): cdk.aws_cloudfront.CloudFrontWebDistribution;
54
+ createCloudFrontDistribution(id: string, scope: common.CommonConstruct, props: types.CloudFrontProps, siteBucket?: s3.IBucket, logBucket?: s3.IBucket, oai?: cloudfront.OriginAccessIdentity, certificate?: acm.ICertificate, aliases?: string[], webAclId?: string): cdk.aws_cloudfront.CloudFrontWebDistribution;
54
55
  /**
55
56
  * Method to create a CloudFront distribution with S3 Origin
56
57
  * @param {string} id scoped id of the resource
@@ -63,8 +64,9 @@ export declare class CloudFrontManager {
63
64
  * @param {acm.ICertificate?} certificate
64
65
  * @param {string[]?} aliases
65
66
  * @param {cloudfront.FunctionAssociation?} defaultFunctionAssociations
67
+ * @param {string?} webAclId
66
68
  */
67
- createDistributionWithS3Origin(id: string, scope: common.CommonConstruct, props: types.DistributionProps, origin: origins.S3Origin, siteBucket: s3.IBucket, logBucket?: s3.IBucket, oai?: cloudfront.OriginAccessIdentity, certificate?: acm.ICertificate, aliases?: string[], defaultFunctionAssociations?: cloudfront.FunctionAssociation[]): cdk.aws_cloudfront.Distribution;
69
+ createDistributionWithS3Origin(id: string, scope: common.CommonConstruct, props: types.DistributionProps, origin: origins.S3Origin, siteBucket: s3.IBucket, logBucket?: s3.IBucket, oai?: cloudfront.OriginAccessIdentity, certificate?: acm.ICertificate, aliases?: string[], defaultFunctionAssociations?: cloudfront.FunctionAssociation[], webAclId?: string): cdk.aws_cloudfront.Distribution;
68
70
  /**
69
71
  * Method to create a CloudFront distribution with HTTP Origin
70
72
  * @param {string} id scoped id of the resource
@@ -75,8 +77,9 @@ export declare class CloudFrontManager {
75
77
  * @param {s3.IBucket?} logBucket
76
78
  * @param {acm.ICertificate?} certificate
77
79
  * @param {cloudfront.FunctionAssociation?} defaultFunctionAssociations
80
+ * @param {string?} webAclId
78
81
  */
79
- createDistributionWithHttpOrigin(id: string, scope: common.CommonConstruct, props: types.DistributionProps, origin: origins.HttpOrigin, domainNames: string[], logBucket?: s3.IBucket, certificate?: acm.ICertificate, defaultFunctionAssociations?: cloudfront.FunctionAssociation[]): cdk.aws_cloudfront.Distribution;
82
+ createDistributionWithHttpOrigin(id: string, scope: common.CommonConstruct, props: types.DistributionProps, origin: origins.HttpOrigin, domainNames: string[], logBucket?: s3.IBucket, certificate?: acm.ICertificate, defaultFunctionAssociations?: cloudfront.FunctionAssociation[], webAclId?: string): cdk.aws_cloudfront.Distribution;
80
83
  /**
81
84
  * @summary Method to provision a Lambda@Edge function
82
85
  *
@@ -78,8 +78,9 @@ class CloudFrontManager {
78
78
  * @param {cloudfront.OriginAccessIdentity?} oai
79
79
  * @param {acm.ICertificate?} certificate
80
80
  * @param {string[]?} aliases
81
+ * @param {string?} webAclId
81
82
  */
82
- createCloudFrontDistribution(id, scope, props, siteBucket, logBucket, oai, certificate, aliases) {
83
+ createCloudFrontDistribution(id, scope, props, siteBucket, logBucket, oai, certificate, aliases, webAclId) {
83
84
  if (!siteBucket)
84
85
  throw `SiteBucket not defined`;
85
86
  if (!certificate)
@@ -113,7 +114,7 @@ class CloudFrontManager {
113
114
  securityPolicy: cloudfront.SecurityPolicyProtocol.TLS_V1_1_2016,
114
115
  sslMethod: cloudfront.SSLMethod.SNI,
115
116
  }),
116
- webACLId: props.webACLId,
117
+ webACLId: webAclId,
117
118
  });
118
119
  utils.createCfnOutput(`${id}-distributionId`, scope, distribution.distributionId);
119
120
  utils.createCfnOutput(`${id}-distributionDomainName`, scope, distribution.distributionDomainName);
@@ -131,8 +132,9 @@ class CloudFrontManager {
131
132
  * @param {acm.ICertificate?} certificate
132
133
  * @param {string[]?} aliases
133
134
  * @param {cloudfront.FunctionAssociation?} defaultFunctionAssociations
135
+ * @param {string?} webAclId
134
136
  */
135
- createDistributionWithS3Origin(id, scope, props, origin, siteBucket, logBucket, oai, certificate, aliases, defaultFunctionAssociations) {
137
+ createDistributionWithS3Origin(id, scope, props, origin, siteBucket, logBucket, oai, certificate, aliases, defaultFunctionAssociations, webAclId) {
136
138
  const distribution = new cloudfront.Distribution(scope, `${id}`, {
137
139
  certificate: certificate,
138
140
  comment: `${id} - ${scope.props.stage} stage`,
@@ -157,7 +159,7 @@ class CloudFrontManager {
157
159
  logFilePrefix: props.logFilePrefix ?? `edge/`,
158
160
  minimumProtocolVersion: props.minimumProtocolVersion ?? cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021,
159
161
  priceClass: props.priceClass ?? cloudfront.PriceClass.PRICE_CLASS_ALL,
160
- webAclId: props.webAclId,
162
+ webAclId: webAclId,
161
163
  });
162
164
  utils.createCfnOutput(`${id}-distributionId`, scope, distribution.distributionId);
163
165
  utils.createCfnOutput(`${id}-distributionDomainName`, scope, distribution.distributionDomainName);
@@ -173,8 +175,9 @@ class CloudFrontManager {
173
175
  * @param {s3.IBucket?} logBucket
174
176
  * @param {acm.ICertificate?} certificate
175
177
  * @param {cloudfront.FunctionAssociation?} defaultFunctionAssociations
178
+ * @param {string?} webAclId
176
179
  */
177
- createDistributionWithHttpOrigin(id, scope, props, origin, domainNames, logBucket, certificate, defaultFunctionAssociations) {
180
+ createDistributionWithHttpOrigin(id, scope, props, origin, domainNames, logBucket, certificate, defaultFunctionAssociations, webAclId) {
178
181
  const distribution = new cloudfront.Distribution(scope, `${id}`, {
179
182
  certificate: certificate,
180
183
  comment: `${id} - ${scope.props.stage} stage`,
@@ -199,7 +202,7 @@ class CloudFrontManager {
199
202
  logFilePrefix: props.logFilePrefix ?? `edge/`,
200
203
  minimumProtocolVersion: props.minimumProtocolVersion ?? cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021,
201
204
  priceClass: props.priceClass ?? cloudfront.PriceClass.PRICE_CLASS_ALL,
202
- webAclId: props.webAclId,
205
+ webAclId: webAclId,
203
206
  });
204
207
  utils.createCfnOutput(`${id}-distributionId`, scope, distribution.distributionId);
205
208
  utils.createCfnOutput(`${id}-distributionDomainName`, scope, distribution.distributionDomainName);
@@ -146,6 +146,11 @@ export declare class IamManager {
146
146
  * @param {string[]} resourceArns list of ARNs to allow access to
147
147
  */
148
148
  statementForReadTableItems(resourceArns?: string[]): cdk.aws_iam.PolicyStatement;
149
+ /**
150
+ * @summary Method to create iam statement to write items from dynamodb table
151
+ * @param {string[]} resourceArns list of ARNs to allow access to
152
+ */
153
+ statementForWriteTableItems(resourceArns?: string[]): cdk.aws_iam.PolicyStatement;
149
154
  /**
150
155
  * @summary Method to create iam statement for cloud trail
151
156
  * @param {string} id scoped id of the resource
@@ -337,6 +337,17 @@ class IamManager {
337
337
  resources: resourceArns ?? ['*'],
338
338
  });
339
339
  }
340
+ /**
341
+ * @summary Method to create iam statement to write items from dynamodb table
342
+ * @param {string[]} resourceArns list of ARNs to allow access to
343
+ */
344
+ statementForWriteTableItems(resourceArns) {
345
+ return new iam.PolicyStatement({
346
+ effect: iam.Effect.ALLOW,
347
+ actions: ['dynamodb:BatchWriteItem', 'dynamodb:DeleteItem', 'dynamodb:PutItem', 'dynamodb:UpdateItem'],
348
+ resources: resourceArns ?? ['*'],
349
+ });
350
+ }
340
351
  /**
341
352
  * @summary Method to create iam statement for cloud trail
342
353
  * @param {string} id scoped id of the resource
@@ -72,6 +72,7 @@ export interface SiteWithEcsBackendProps extends CommonStackProps {
72
72
  siteSubDomain: string;
73
73
  siteTask: ecsPatterns.ApplicationLoadBalancedFargateServiceProps;
74
74
  siteVpc: ec2.VpcProps;
75
+ siteWebAcl?: WafWebACLProps;
75
76
  useExistingHostedZone: boolean;
76
77
  nodeEnv: string;
77
78
  logLevel: string;
@@ -94,6 +95,7 @@ export interface StaticSiteProps extends CommonStackProps {
94
95
  siteRecordName?: string;
95
96
  siteSubDomain?: string;
96
97
  siteAliases?: string[];
98
+ siteWebAcl?: WafWebACLProps;
97
99
  useExistingHostedZone: boolean;
98
100
  nodeEnv: string;
99
101
  logLevel: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradientedge/cdk-utils",
3
- "version": "5.9.0",
3
+ "version": "5.12.0",
4
4
  "description": "Utilities for AWS CDK provisioning",
5
5
  "main": "dist/index.js",
6
6
  "engines": {
@@ -532,6 +532,12 @@ export class ApiToEventBridgeTarget extends CommonConstruct {
532
532
  )
533
533
  return
534
534
  }
535
+
536
+ const accessLogGroup = this.logManager.createLogGroup(`${this.id}-sns-rest-api-access-log`, this, {
537
+ logGroupName: `/custom/api/${this.id}-destined-rest-api-access-${this.props.stage}`,
538
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
539
+ })
540
+
535
541
  this.apiDestinedRestApi.api = new apig.RestApi(this, `${this.id}-sns-rest-api`, {
536
542
  ...{
537
543
  defaultIntegration: this.apiDestinedRestApi.integration,
@@ -544,6 +550,8 @@ export class ApiToEventBridgeTarget extends CommonConstruct {
544
550
  loggingLevel: apig.MethodLoggingLevel.INFO,
545
551
  metricsEnabled: true,
546
552
  stageName: this.props.stage,
553
+ accessLogDestination: new apig.LogGroupLogDestination(accessLogGroup),
554
+ accessLogFormat: apig.AccessLogFormat.jsonWithStandardFields(),
547
555
  },
548
556
  endpointConfiguration: {
549
557
  types: [apig.EndpointType.REGIONAL],
@@ -11,6 +11,7 @@ import * as logs from 'aws-cdk-lib/aws-logs'
11
11
  import * as route53 from 'aws-cdk-lib/aws-route53'
12
12
  import * as s3 from 'aws-cdk-lib/aws-s3'
13
13
  import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager'
14
+ import * as wafv2 from 'aws-cdk-lib/aws-wafv2'
14
15
  import { Construct } from 'constructs'
15
16
  import { CommonConstruct } from '../../common'
16
17
  import { SiteWithEcsBackendProps } from '../../types'
@@ -65,6 +66,7 @@ export class SiteWithEcsBackend extends CommonConstruct {
65
66
  siteDomainNames: string[]
66
67
  siteCloudfrontFunction: cloudfront.Function
67
68
  siteFunctionAssociations: cloudfront.FunctionAssociation[]
69
+ siteWebAcl: wafv2.CfnWebACL
68
70
 
69
71
  constructor(parent: Construct, id: string, props: SiteWithEcsBackendProps) {
70
72
  super(parent, id, props)
@@ -95,6 +97,7 @@ export class SiteWithEcsBackend extends CommonConstruct {
95
97
  this.createSiteOrigin()
96
98
  this.createSiteCloudfrontFunction()
97
99
  this.resolveSiteFunctionAssociations()
100
+ this.createSiteWebAcl()
98
101
  this.createDistribution()
99
102
  this.createNetworkMappings()
100
103
  this.invalidateDistributionCache()
@@ -339,6 +342,16 @@ export class SiteWithEcsBackend extends CommonConstruct {
339
342
  }
340
343
  }
341
344
 
345
+ /**
346
+ * @summary Method to create WAF
347
+ * @protected
348
+ */
349
+ protected createSiteWebAcl() {
350
+ if (!this.props.siteWebAcl) throw 'SiteWebAcl props undefined'
351
+
352
+ this.siteWebAcl = this.wafManager.createWebAcl(`${this.id}-waf`, this, this.props.siteWebAcl)
353
+ }
354
+
342
355
  /**
343
356
  * Method to create Site distribution
344
357
  * @protected
@@ -352,7 +365,8 @@ export class SiteWithEcsBackend extends CommonConstruct {
352
365
  this.siteDomainNames,
353
366
  this.siteLogBucket,
354
367
  this.siteCertificate,
355
- this.siteFunctionAssociations
368
+ this.siteFunctionAssociations,
369
+ this.siteWebAcl.attrId
356
370
  )
357
371
  }
358
372
 
@@ -3,6 +3,7 @@ import * as cloudfront from 'aws-cdk-lib/aws-cloudfront'
3
3
  import * as origins from 'aws-cdk-lib/aws-cloudfront-origins'
4
4
  import * as route53 from 'aws-cdk-lib/aws-route53'
5
5
  import * as s3 from 'aws-cdk-lib/aws-s3'
6
+ import * as wafv2 from 'aws-cdk-lib/aws-wafv2'
6
7
  import { Construct } from 'constructs'
7
8
  import { CommonConstruct } from '../../common'
8
9
  import { StaticSiteProps } from '../../types'
@@ -43,6 +44,7 @@ export class StaticSite extends CommonConstruct {
43
44
  siteOriginAccessIdentity: cloudfront.OriginAccessIdentity
44
45
  siteCloudfrontFunction: cloudfront.Function
45
46
  siteFunctionAssociations: cloudfront.FunctionAssociation[]
47
+ siteWebAcl: wafv2.CfnWebACL
46
48
 
47
49
  constructor(parent: Construct, id: string, props: StaticSiteProps) {
48
50
  super(parent, id, props)
@@ -63,6 +65,7 @@ export class StaticSite extends CommonConstruct {
63
65
  this.createSiteOrigin()
64
66
  this.createSiteCloudfrontFunction()
65
67
  this.resolveSiteFunctionAssociations()
68
+ this.createSiteWebAcl()
66
69
  this.createSiteDistribution()
67
70
  this.createSiteRouteAssets()
68
71
  this.deploySite()
@@ -153,6 +156,16 @@ export class StaticSite extends CommonConstruct {
153
156
  }
154
157
  }
155
158
 
159
+ /**
160
+ * @summary Method to create WAF
161
+ * @protected
162
+ */
163
+ protected createSiteWebAcl() {
164
+ if (!this.props.siteWebAcl) throw 'SiteWebAcl props undefined'
165
+
166
+ this.siteWebAcl = this.wafManager.createWebAcl(`${this.id}-waf`, this, this.props.siteWebAcl)
167
+ }
168
+
156
169
  /**
157
170
  * @summary Method to create a site cloudfront distribution
158
171
  * @protected
@@ -170,7 +183,8 @@ export class StaticSite extends CommonConstruct {
170
183
  this.siteOriginAccessIdentity,
171
184
  this.siteCertificate,
172
185
  this.props.siteAliases,
173
- this.siteFunctionAssociations
186
+ this.siteFunctionAssociations,
187
+ this.siteWebAcl.attrId
174
188
  )
175
189
  }
176
190
 
@@ -61,6 +61,7 @@ export class CloudFrontManager {
61
61
  * @param {cloudfront.OriginAccessIdentity?} oai
62
62
  * @param {acm.ICertificate?} certificate
63
63
  * @param {string[]?} aliases
64
+ * @param {string?} webAclId
64
65
  */
65
66
  public createCloudFrontDistribution(
66
67
  id: string,
@@ -70,7 +71,8 @@ export class CloudFrontManager {
70
71
  logBucket?: s3.IBucket,
71
72
  oai?: cloudfront.OriginAccessIdentity,
72
73
  certificate?: acm.ICertificate,
73
- aliases?: string[]
74
+ aliases?: string[],
75
+ webAclId?: string
74
76
  ) {
75
77
  if (!siteBucket) throw `SiteBucket not defined`
76
78
  if (!certificate) throw `Certificate not defined`
@@ -103,7 +105,7 @@ export class CloudFrontManager {
103
105
  securityPolicy: cloudfront.SecurityPolicyProtocol.TLS_V1_1_2016,
104
106
  sslMethod: cloudfront.SSLMethod.SNI,
105
107
  }),
106
- webACLId: props.webACLId,
108
+ webACLId: webAclId,
107
109
  })
108
110
 
109
111
  utils.createCfnOutput(`${id}-distributionId`, scope, distribution.distributionId)
@@ -124,6 +126,7 @@ export class CloudFrontManager {
124
126
  * @param {acm.ICertificate?} certificate
125
127
  * @param {string[]?} aliases
126
128
  * @param {cloudfront.FunctionAssociation?} defaultFunctionAssociations
129
+ * @param {string?} webAclId
127
130
  */
128
131
  public createDistributionWithS3Origin(
129
132
  id: string,
@@ -135,7 +138,8 @@ export class CloudFrontManager {
135
138
  oai?: cloudfront.OriginAccessIdentity,
136
139
  certificate?: acm.ICertificate,
137
140
  aliases?: string[],
138
- defaultFunctionAssociations?: cloudfront.FunctionAssociation[]
141
+ defaultFunctionAssociations?: cloudfront.FunctionAssociation[],
142
+ webAclId?: string
139
143
  ) {
140
144
  const distribution = new cloudfront.Distribution(scope, `${id}`, {
141
145
  certificate: certificate,
@@ -161,7 +165,7 @@ export class CloudFrontManager {
161
165
  logFilePrefix: props.logFilePrefix ?? `edge/`,
162
166
  minimumProtocolVersion: props.minimumProtocolVersion ?? cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021,
163
167
  priceClass: props.priceClass ?? cloudfront.PriceClass.PRICE_CLASS_ALL,
164
- webAclId: props.webAclId,
168
+ webAclId: webAclId,
165
169
  })
166
170
 
167
171
  utils.createCfnOutput(`${id}-distributionId`, scope, distribution.distributionId)
@@ -180,6 +184,7 @@ export class CloudFrontManager {
180
184
  * @param {s3.IBucket?} logBucket
181
185
  * @param {acm.ICertificate?} certificate
182
186
  * @param {cloudfront.FunctionAssociation?} defaultFunctionAssociations
187
+ * @param {string?} webAclId
183
188
  */
184
189
  public createDistributionWithHttpOrigin(
185
190
  id: string,
@@ -189,7 +194,8 @@ export class CloudFrontManager {
189
194
  domainNames: string[],
190
195
  logBucket?: s3.IBucket,
191
196
  certificate?: acm.ICertificate,
192
- defaultFunctionAssociations?: cloudfront.FunctionAssociation[]
197
+ defaultFunctionAssociations?: cloudfront.FunctionAssociation[],
198
+ webAclId?: string
193
199
  ) {
194
200
  const distribution = new cloudfront.Distribution(scope, `${id}`, {
195
201
  certificate: certificate,
@@ -215,7 +221,7 @@ export class CloudFrontManager {
215
221
  logFilePrefix: props.logFilePrefix ?? `edge/`,
216
222
  minimumProtocolVersion: props.minimumProtocolVersion ?? cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021,
217
223
  priceClass: props.priceClass ?? cloudfront.PriceClass.PRICE_CLASS_ALL,
218
- webAclId: props.webAclId,
224
+ webAclId: webAclId,
219
225
  })
220
226
 
221
227
  utils.createCfnOutput(`${id}-distributionId`, scope, distribution.distributionId)
@@ -343,6 +343,18 @@ export class IamManager {
343
343
  })
344
344
  }
345
345
 
346
+ /**
347
+ * @summary Method to create iam statement to write items from dynamodb table
348
+ * @param {string[]} resourceArns list of ARNs to allow access to
349
+ */
350
+ public statementForWriteTableItems(resourceArns?: string[]) {
351
+ return new iam.PolicyStatement({
352
+ effect: iam.Effect.ALLOW,
353
+ actions: ['dynamodb:BatchWriteItem', 'dynamodb:DeleteItem', 'dynamodb:PutItem', 'dynamodb:UpdateItem'],
354
+ resources: resourceArns ?? ['*'],
355
+ })
356
+ }
357
+
346
358
  /**
347
359
  * @summary Method to create iam statement for cloud trail
348
360
  * @param {string} id scoped id of the resource
@@ -75,6 +75,7 @@ export interface SiteWithEcsBackendProps extends CommonStackProps {
75
75
  siteSubDomain: string
76
76
  siteTask: ecsPatterns.ApplicationLoadBalancedFargateServiceProps
77
77
  siteVpc: ec2.VpcProps
78
+ siteWebAcl?: WafWebACLProps
78
79
  useExistingHostedZone: boolean
79
80
  nodeEnv: string
80
81
  logLevel: string
@@ -98,6 +99,7 @@ export interface StaticSiteProps extends CommonStackProps {
98
99
  siteRecordName?: string
99
100
  siteSubDomain?: string
100
101
  siteAliases?: string[]
102
+ siteWebAcl?: WafWebACLProps
101
103
  useExistingHostedZone: boolean
102
104
  nodeEnv: string
103
105
  logLevel: string