@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.
- package/dist/src/lib/construct/api-to-eventbridge-target/main.js +6 -0
- package/dist/src/lib/construct/site-with-ecs-backend/main.d.ts +7 -0
- package/dist/src/lib/construct/site-with-ecs-backend/main.js +12 -1
- package/dist/src/lib/construct/static-site/main.d.ts +7 -0
- package/dist/src/lib/construct/static-site/main.js +12 -1
- package/dist/src/lib/manager/aws/cloudfront-manager.d.ts +6 -3
- package/dist/src/lib/manager/aws/cloudfront-manager.js +9 -6
- package/dist/src/lib/manager/aws/iam-manager.d.ts +5 -0
- package/dist/src/lib/manager/aws/iam-manager.js +11 -0
- package/dist/src/lib/types/aws/index.d.ts +2 -0
- package/package.json +1 -1
- package/src/lib/construct/api-to-eventbridge-target/main.ts +8 -0
- package/src/lib/construct/site-with-ecs-backend/main.ts +15 -1
- package/src/lib/construct/static-site/main.ts +15 -1
- package/src/lib/manager/aws/cloudfront-manager.ts +12 -6
- package/src/lib/manager/aws/iam-manager.ts +12 -0
- package/src/lib/types/aws/index.ts +2 -0
|
@@ -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:
|
|
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:
|
|
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:
|
|
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
|
@@ -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:
|
|
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:
|
|
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:
|
|
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
|