@gradientedge/cdk-utils 8.125.0 → 8.127.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.
Files changed (23) hide show
  1. package/app/api-destined-function/node_modules/.bin/rimraf +4 -4
  2. package/app/api-destined-function/package.json +1 -1
  3. package/dist/src/lib/aws/construct/index.d.ts +1 -0
  4. package/dist/src/lib/aws/construct/index.js +1 -0
  5. package/dist/src/lib/aws/construct/site-with-lambda-backend/constants.d.ts +5 -0
  6. package/dist/src/lib/aws/construct/site-with-lambda-backend/constants.js +9 -0
  7. package/dist/src/lib/aws/construct/site-with-lambda-backend/index.d.ts +3 -0
  8. package/dist/src/lib/aws/construct/site-with-lambda-backend/index.js +19 -0
  9. package/dist/src/lib/aws/construct/site-with-lambda-backend/main.d.ts +116 -0
  10. package/dist/src/lib/aws/construct/site-with-lambda-backend/main.js +317 -0
  11. package/dist/src/lib/aws/construct/site-with-lambda-backend/types.d.ts +45 -0
  12. package/dist/src/lib/aws/construct/site-with-lambda-backend/types.js +2 -0
  13. package/dist/src/lib/aws/services/cloudwatch/main.js +10 -10
  14. package/dist/src/lib/aws/services/lambda/main.d.ts +4 -2
  15. package/dist/src/lib/aws/services/lambda/main.js +9 -1
  16. package/package.json +16 -16
  17. package/src/lib/aws/construct/index.ts +1 -0
  18. package/src/lib/aws/construct/site-with-lambda-backend/constants.ts +6 -0
  19. package/src/lib/aws/construct/site-with-lambda-backend/index.ts +3 -0
  20. package/src/lib/aws/construct/site-with-lambda-backend/main.ts +433 -0
  21. package/src/lib/aws/construct/site-with-lambda-backend/types.ts +64 -0
  22. package/src/lib/aws/services/cloudwatch/main.ts +10 -10
  23. package/src/lib/aws/services/lambda/main.ts +18 -1
@@ -6,12 +6,12 @@ case `uname` in
6
6
  esac
7
7
 
8
8
  if [ -z "$NODE_PATH" ]; then
9
- export NODE_PATH="/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.1/node_modules/rimraf/dist/cjs/src/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.1/node_modules/rimraf/dist/cjs/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.1/node_modules/rimraf/dist/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.1/node_modules/rimraf/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.1/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/node_modules"
9
+ export NODE_PATH="/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.5/node_modules/rimraf/dist/esm/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.5/node_modules/rimraf/dist/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.5/node_modules/rimraf/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.5/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/node_modules"
10
10
  else
11
- export NODE_PATH="/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.1/node_modules/rimraf/dist/cjs/src/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.1/node_modules/rimraf/dist/cjs/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.1/node_modules/rimraf/dist/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.1/node_modules/rimraf/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.1/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/node_modules:$NODE_PATH"
11
+ export NODE_PATH="/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.5/node_modules/rimraf/dist/esm/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.5/node_modules/rimraf/dist/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.5/node_modules/rimraf/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.5/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/node_modules:$NODE_PATH"
12
12
  fi
13
13
  if [ -x "$basedir/node" ]; then
14
- exec "$basedir/node" "$basedir/../rimraf/dist/cjs/src/bin.js" "$@"
14
+ exec "$basedir/node" "$basedir/../rimraf/dist/esm/bin.mjs" "$@"
15
15
  else
16
- exec node "$basedir/../rimraf/dist/cjs/src/bin.js" "$@"
16
+ exec node "$basedir/../rimraf/dist/esm/bin.mjs" "$@"
17
17
  fi
@@ -21,6 +21,6 @@
21
21
  },
22
22
  "devDependencies": {
23
23
  "mkdirp": "^3.0.1",
24
- "rimraf": "^5.0.1"
24
+ "rimraf": "^5.0.5"
25
25
  }
26
26
  }
@@ -9,5 +9,6 @@ export * from './lambda-with-iam-access';
9
9
  export * from './rest-api-lambda';
10
10
  export * from './rest-api-lambda-with-cache';
11
11
  export * from './site-with-ecs-backend';
12
+ export * from './site-with-lambda-backend';
12
13
  export * from './static-asset-deployment';
13
14
  export * from './static-site';
@@ -25,5 +25,6 @@ __exportStar(require("./lambda-with-iam-access"), exports);
25
25
  __exportStar(require("./rest-api-lambda"), exports);
26
26
  __exportStar(require("./rest-api-lambda-with-cache"), exports);
27
27
  __exportStar(require("./site-with-ecs-backend"), exports);
28
+ __exportStar(require("./site-with-lambda-backend"), exports);
28
29
  __exportStar(require("./static-asset-deployment"), exports);
29
30
  __exportStar(require("./static-site"), exports);
@@ -0,0 +1,5 @@
1
+ export declare enum SiteWithLambdaBackendResponseHeaderPolicyType {
2
+ ORIGIN = "origin",
3
+ STATIC = "static"
4
+ }
5
+ export declare const LAMBDA_ALIAS_NAME_CURRENT = "current";
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LAMBDA_ALIAS_NAME_CURRENT = exports.SiteWithLambdaBackendResponseHeaderPolicyType = void 0;
4
+ var SiteWithLambdaBackendResponseHeaderPolicyType;
5
+ (function (SiteWithLambdaBackendResponseHeaderPolicyType) {
6
+ SiteWithLambdaBackendResponseHeaderPolicyType["ORIGIN"] = "origin";
7
+ SiteWithLambdaBackendResponseHeaderPolicyType["STATIC"] = "static";
8
+ })(SiteWithLambdaBackendResponseHeaderPolicyType || (exports.SiteWithLambdaBackendResponseHeaderPolicyType = SiteWithLambdaBackendResponseHeaderPolicyType = {}));
9
+ exports.LAMBDA_ALIAS_NAME_CURRENT = 'current';
@@ -0,0 +1,3 @@
1
+ export * from './constants';
2
+ export * from './main';
3
+ export * from './types';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./constants"), exports);
18
+ __exportStar(require("./main"), exports);
19
+ __exportStar(require("./types"), exports);
@@ -0,0 +1,116 @@
1
+ import { ICertificate } from 'aws-cdk-lib/aws-certificatemanager';
2
+ import { CachePolicy, IFunction as CfIFunction, Distribution, FunctionAssociation, OriginRequestPolicy, ResponseHeadersPolicy } from 'aws-cdk-lib/aws-cloudfront';
3
+ import { HttpOrigin } from 'aws-cdk-lib/aws-cloudfront-origins';
4
+ import { PolicyDocument, Role } from 'aws-cdk-lib/aws-iam';
5
+ import { AssetCode, FunctionUrl, IFunction, ILayerVersion } from 'aws-cdk-lib/aws-lambda';
6
+ import { IHostedZone } from 'aws-cdk-lib/aws-route53';
7
+ import { IBucket } from 'aws-cdk-lib/aws-s3';
8
+ import { BucketDeployment } from 'aws-cdk-lib/aws-s3-deployment';
9
+ import { Construct } from 'constructs';
10
+ import { CommonConstruct } from '../../common';
11
+ import { SiteWithLambdaBackendCachePolicyProps, SiteWithLambdaBackendProps, SiteWithLambdaBackendResponseHeadersPolicyProps } from './types';
12
+ /**
13
+ * @classdesc Provides a construct to create and deploy a site hosted with an clustered ECS/ELB backend
14
+ * @example
15
+ * import { SiteWithLambdaBackend, SiteWithLambdaBackendProps } '@gradientedge/cdk-utils'
16
+ * import { Construct } from 'constructs'
17
+ *
18
+ * class CustomConstruct extends SiteWithLambdaBackend {
19
+ * constructor(parent: Construct, id: string, props: SiteWithLambdaBackendProps) {
20
+ * super(parent, id, props)
21
+ * this.props = props
22
+ * this.id = id
23
+ * this.initResources()
24
+ * }
25
+ * }
26
+ */
27
+ export declare class SiteWithLambdaBackend extends CommonConstruct {
28
+ props: SiteWithLambdaBackendProps;
29
+ id: string;
30
+ siteHostedZone: IHostedZone;
31
+ siteCertificate: ICertificate;
32
+ siteRegionalCertificate: ICertificate;
33
+ siteSecrets: any;
34
+ siteLogBucket: IBucket;
35
+ siteOrigin: HttpOrigin;
36
+ siteDistribution: Distribution;
37
+ siteInternalDomainName: string;
38
+ siteExternalDomainName: string;
39
+ siteDomainNames: string[];
40
+ siteCloudfrontFunction: CfIFunction;
41
+ siteFunctionAssociations: FunctionAssociation[];
42
+ siteOriginRequestPolicy: OriginRequestPolicy;
43
+ siteOriginResponseHeadersPolicy?: ResponseHeadersPolicy;
44
+ siteCachePolicy: CachePolicy;
45
+ siteStaticAssetDeployment: BucketDeployment;
46
+ siteLambdaPolicy: PolicyDocument;
47
+ siteLambdaRole: Role;
48
+ siteLambdaEnvironment: any;
49
+ siteLambdaLayers: ILayerVersion[];
50
+ siteLambdaApplication: AssetCode;
51
+ siteLambdaFunction: IFunction;
52
+ siteLambdaUrl: FunctionUrl;
53
+ constructor(parent: Construct, id: string, props: SiteWithLambdaBackendProps);
54
+ /**
55
+ * @summary Initialise and provision resources
56
+ */
57
+ protected initResources(): void;
58
+ /**
59
+ * @summary Method to resolve a hosted zone based on domain attributes
60
+ */
61
+ protected resolveHostedZone(): void;
62
+ /**
63
+ * @summary Method to resolve a certificate based on attributes
64
+ */
65
+ protected resolveCertificate(): void;
66
+ protected resolveGlobalCertificate(): void;
67
+ protected resolveRegionalCertificate(): void;
68
+ /**
69
+ * @summary Method to resolve secrets from SecretsManager
70
+ * - To be implemented in the overriding method in the implementation class
71
+ */
72
+ protected resolveSiteSecrets(): void;
73
+ /**
74
+ * @summary Method to resolve site domain names
75
+ */
76
+ protected resolveSiteDomainNames(): void;
77
+ /**
78
+ * Method to create log bucket for site distribution
79
+ */
80
+ protected createSiteLogBucket(): void;
81
+ protected createSiteCachePolicy(id: string, siteCachePolicy: SiteWithLambdaBackendCachePolicyProps): CachePolicy;
82
+ protected createSiteOriginCachePolicy(): void;
83
+ protected createSiteOriginRequestPolicy(): void;
84
+ protected createResponseHeaderPolicy(props: SiteWithLambdaBackendResponseHeadersPolicyProps): ResponseHeadersPolicy | undefined;
85
+ protected createSiteOriginResponseHeadersPolicy(): void;
86
+ protected createSiteOrigin(): void;
87
+ protected createSiteOriginResources(): void;
88
+ protected createSiteStaticAssetDeployment(): void;
89
+ protected createSiteLambdaPolicy(): void;
90
+ protected createSiteLambdaRole(): void;
91
+ protected createSiteLambdaEnvironment(): void;
92
+ protected createSiteLambdaLayers(): void;
93
+ protected createSiteLambdaApplication(): void;
94
+ protected createSiteLambda(): void;
95
+ protected createSiteLambdaUrl(): void;
96
+ /**
97
+ * @summary Method to create a site cloudfront function
98
+ */
99
+ protected createSiteCloudfrontFunction(): void;
100
+ /**
101
+ * @summary Method to create a site cloudfront function associations
102
+ */
103
+ protected resolveSiteFunctionAssociations(): void;
104
+ /**
105
+ * Method to create Site distribution
106
+ */
107
+ protected createDistribution(): void;
108
+ /**
109
+ * Method to create Route53 records for distribution
110
+ */
111
+ protected createNetworkMappings(): void;
112
+ /**
113
+ * Method to invalidation the cloudfront distribution cache after a deployment
114
+ */
115
+ protected invalidateDistributionCache(): void;
116
+ }
@@ -0,0 +1,317 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SiteWithLambdaBackend = void 0;
7
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
8
+ const aws_cloudfront_1 = require("aws-cdk-lib/aws-cloudfront");
9
+ const aws_cloudfront_origins_1 = require("aws-cdk-lib/aws-cloudfront-origins");
10
+ const aws_iam_1 = require("aws-cdk-lib/aws-iam");
11
+ const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
12
+ const lodash_1 = __importDefault(require("lodash"));
13
+ const common_1 = require("../../common");
14
+ const constants_1 = require("./constants");
15
+ /**
16
+ * @classdesc Provides a construct to create and deploy a site hosted with an clustered ECS/ELB backend
17
+ * @example
18
+ * import { SiteWithLambdaBackend, SiteWithLambdaBackendProps } '@gradientedge/cdk-utils'
19
+ * import { Construct } from 'constructs'
20
+ *
21
+ * class CustomConstruct extends SiteWithLambdaBackend {
22
+ * constructor(parent: Construct, id: string, props: SiteWithLambdaBackendProps) {
23
+ * super(parent, id, props)
24
+ * this.props = props
25
+ * this.id = id
26
+ * this.initResources()
27
+ * }
28
+ * }
29
+ */
30
+ class SiteWithLambdaBackend extends common_1.CommonConstruct {
31
+ /* site properties */
32
+ props;
33
+ id;
34
+ /* site resources */
35
+ siteHostedZone;
36
+ siteCertificate;
37
+ siteRegionalCertificate;
38
+ siteSecrets;
39
+ siteLogBucket;
40
+ siteOrigin;
41
+ siteDistribution;
42
+ siteInternalDomainName;
43
+ siteExternalDomainName;
44
+ siteDomainNames;
45
+ siteCloudfrontFunction;
46
+ siteFunctionAssociations;
47
+ siteOriginRequestPolicy;
48
+ siteOriginResponseHeadersPolicy;
49
+ siteCachePolicy;
50
+ siteStaticAssetDeployment;
51
+ siteLambdaPolicy;
52
+ siteLambdaRole;
53
+ siteLambdaEnvironment;
54
+ siteLambdaLayers;
55
+ siteLambdaApplication;
56
+ siteLambdaFunction;
57
+ siteLambdaUrl;
58
+ constructor(parent, id, props) {
59
+ super(parent, id, props);
60
+ this.props = props;
61
+ this.id = id;
62
+ }
63
+ /**
64
+ * @summary Initialise and provision resources
65
+ */
66
+ initResources() {
67
+ this.resolveHostedZone();
68
+ this.resolveCertificate();
69
+ this.resolveSiteSecrets();
70
+ this.resolveSiteDomainNames();
71
+ this.createSiteLogBucket();
72
+ this.createSiteOriginCachePolicy();
73
+ this.createSiteOriginRequestPolicy();
74
+ this.createSiteOriginResponseHeadersPolicy();
75
+ this.createSiteOrigin();
76
+ this.createSiteCloudfrontFunction();
77
+ this.resolveSiteFunctionAssociations();
78
+ this.createDistribution();
79
+ this.createNetworkMappings();
80
+ this.invalidateDistributionCache();
81
+ }
82
+ /**
83
+ * @summary Method to resolve a hosted zone based on domain attributes
84
+ */
85
+ resolveHostedZone() {
86
+ this.siteHostedZone = this.route53Manager.withHostedZoneFromFullyQualifiedDomainName(`${this.id}-hosted-zone`, this, this.props.useExistingHostedZone);
87
+ }
88
+ /**
89
+ * @summary Method to resolve a certificate based on attributes
90
+ */
91
+ resolveCertificate() {
92
+ this.resolveGlobalCertificate();
93
+ this.resolveRegionalCertificate();
94
+ }
95
+ resolveGlobalCertificate() {
96
+ if (this.props.siteCertificate.useExistingCertificate &&
97
+ this.props.siteCertificate.certificateSsmName &&
98
+ this.props.siteCertificate.certificateRegion) {
99
+ this.props.siteCertificate.certificateArn = this.ssmManager.readStringParameterFromRegion(`${this.id}-certificate-parameter`, this, this.props.siteCertificate.certificateSsmName, this.props.siteCertificate.certificateRegion);
100
+ }
101
+ this.siteCertificate = this.acmManager.resolveCertificate(`${this.id}-certificate`, this, this.props.siteCertificate);
102
+ }
103
+ resolveRegionalCertificate() {
104
+ if (this.props.siteRegionalCertificate.useExistingCertificate &&
105
+ this.props.siteRegionalCertificate.certificateSsmName &&
106
+ this.props.siteRegionalCertificate.certificateRegion) {
107
+ this.props.siteRegionalCertificate.certificateArn = this.ssmManager.readStringParameterFromRegion(`${this.id}-regional-certificate-parameter`, this, this.props.siteRegionalCertificate.certificateSsmName, this.props.siteRegionalCertificate.certificateRegion);
108
+ }
109
+ this.siteRegionalCertificate = this.acmManager.resolveCertificate(`${this.id}-regional-certificate`, this, this.props.siteRegionalCertificate, this.siteHostedZone);
110
+ }
111
+ /**
112
+ * @summary Method to resolve secrets from SecretsManager
113
+ * - To be implemented in the overriding method in the implementation class
114
+ */
115
+ resolveSiteSecrets() { }
116
+ /**
117
+ * @summary Method to resolve site domain names
118
+ */
119
+ resolveSiteDomainNames() {
120
+ /* the internal domain name used by ELB */
121
+ this.siteInternalDomainName =
122
+ this.isProductionStage() || this.props.skipStageForARecords
123
+ ? `${this.props.siteSubDomain}-internal.${this.fullyQualifiedDomainName}`
124
+ : `${this.props.siteSubDomain}-internal-${this.props.stage}.${this.fullyQualifiedDomainName}`;
125
+ /* the external domain name exposed to CloudFront */
126
+ this.siteExternalDomainName =
127
+ this.isProductionStage() || this.props.skipStageForARecords
128
+ ? `${this.props.siteSubDomain}.${this.fullyQualifiedDomainName}`
129
+ : `${this.props.siteSubDomain}-${this.props.stage}.${this.fullyQualifiedDomainName}`;
130
+ this.siteDomainNames = [this.siteExternalDomainName];
131
+ }
132
+ /**
133
+ * Method to create log bucket for site distribution
134
+ */
135
+ createSiteLogBucket() {
136
+ this.siteLogBucket = this.s3Manager.createS3Bucket(`${this.id}-site-logs`, this, this.props.siteLogBucket);
137
+ }
138
+ createSiteCachePolicy(id, siteCachePolicy) {
139
+ return new aws_cloudfront_1.CachePolicy(this, `${id}`, {
140
+ cachePolicyName: `${this.id}-${siteCachePolicy.cachePolicyName}`,
141
+ comment: `Policy for ${this.id}-distribution - ${this.props.stage} stage`,
142
+ cookieBehavior: siteCachePolicy.cookieBehavior,
143
+ enableAcceptEncodingBrotli: siteCachePolicy.enableAcceptEncodingBrotli,
144
+ enableAcceptEncodingGzip: siteCachePolicy.enableAcceptEncodingGzip,
145
+ headerBehavior: siteCachePolicy.headerBehavior,
146
+ maxTtl: aws_cdk_lib_1.Duration.seconds(siteCachePolicy.maxTtlInSeconds),
147
+ minTtl: aws_cdk_lib_1.Duration.seconds(siteCachePolicy.minTtlInSeconds),
148
+ queryStringBehavior: siteCachePolicy.queryStringBehavior,
149
+ });
150
+ }
151
+ createSiteOriginCachePolicy() {
152
+ if (!this.props.siteCachePolicy)
153
+ return;
154
+ this.siteCachePolicy = this.createSiteCachePolicy(`${this.id}-site-cache-policy`, this.props.siteCachePolicy);
155
+ lodash_1.default.assign(this.props.siteDistribution.defaultBehavior, {
156
+ cachePolicy: this.siteCachePolicy,
157
+ });
158
+ }
159
+ createSiteOriginRequestPolicy() {
160
+ if (!this.props.siteOriginRequestPolicy)
161
+ return;
162
+ this.siteOriginRequestPolicy = new aws_cloudfront_1.OriginRequestPolicy(this, `${this.id}-sorp`, {
163
+ comment: `Request Policy for ${this.id}-distribution - ${this.props.stage} stage`,
164
+ cookieBehavior: this.props.siteOriginRequestPolicy.cookieBehavior,
165
+ headerBehavior: this.props.siteOriginRequestPolicy.headerBehavior,
166
+ originRequestPolicyName: `${this.id}-origin-request`,
167
+ queryStringBehavior: this.props.siteOriginRequestPolicy.queryStringBehavior,
168
+ });
169
+ lodash_1.default.assign(this.props.siteDistribution.defaultBehavior, {
170
+ originRequestPolicy: this.siteOriginRequestPolicy,
171
+ });
172
+ }
173
+ createResponseHeaderPolicy(props) {
174
+ if (!props)
175
+ return undefined;
176
+ return new aws_cloudfront_1.ResponseHeadersPolicy(this, `${this.id}-${props.type}-srhp`, {
177
+ ...props,
178
+ comment: `Response Header Policy for ${props.type} for ${this.id}-distribution - ${this.props.stage} stage`,
179
+ responseHeadersPolicyName: `${this.id}-${props.type}-response`,
180
+ securityHeadersBehavior: {
181
+ ...props.securityHeadersBehavior,
182
+ strictTransportSecurity: {
183
+ ...props.securityHeadersBehavior?.strictTransportSecurity,
184
+ accessControlMaxAge: aws_cdk_lib_1.Duration.seconds(props.securityHeadersBehavior?.strictTransportSecurity?.accessControlMaxAgeInSeconds),
185
+ },
186
+ },
187
+ });
188
+ }
189
+ createSiteOriginResponseHeadersPolicy() {
190
+ if (!this.props.siteOriginResponseHeadersPolicy)
191
+ return;
192
+ this.siteOriginResponseHeadersPolicy = this.createResponseHeaderPolicy(this.props.siteOriginResponseHeadersPolicy);
193
+ lodash_1.default.assign(this.props.siteDistribution.defaultBehavior, {
194
+ responseHeadersPolicy: this.siteOriginResponseHeadersPolicy,
195
+ });
196
+ }
197
+ createSiteOrigin() {
198
+ this.createSiteOriginResources();
199
+ this.siteOrigin = new aws_cloudfront_origins_1.HttpOrigin(aws_cdk_lib_1.Fn.select(2, aws_cdk_lib_1.Fn.split('/', this.siteLambdaUrl.url)), {
200
+ httpPort: 443,
201
+ originId: `${this.id}-server`,
202
+ protocolPolicy: aws_cloudfront_1.OriginProtocolPolicy.HTTPS_ONLY,
203
+ });
204
+ }
205
+ createSiteOriginResources() {
206
+ this.createSiteStaticAssetDeployment();
207
+ this.createSiteLambdaPolicy();
208
+ this.createSiteLambdaRole();
209
+ this.createSiteLambdaEnvironment();
210
+ this.createSiteLambdaLayers();
211
+ this.createSiteLambdaApplication();
212
+ this.createSiteLambda();
213
+ this.createSiteLambdaUrl();
214
+ }
215
+ createSiteStaticAssetDeployment() { }
216
+ createSiteLambdaPolicy() {
217
+ this.siteLambdaPolicy = new aws_iam_1.PolicyDocument({
218
+ statements: [
219
+ new aws_iam_1.PolicyStatement({
220
+ actions: ['lambda:InvokeFunctionUrl'],
221
+ effect: aws_iam_1.Effect.ALLOW,
222
+ resources: ['*'],
223
+ }),
224
+ ],
225
+ });
226
+ }
227
+ createSiteLambdaRole() {
228
+ this.siteLambdaRole = this.iamManager.createRoleForLambda(`${this.id}-role`, this, this.siteLambdaPolicy);
229
+ }
230
+ createSiteLambdaEnvironment() {
231
+ this.siteLambdaEnvironment = {
232
+ AWS_LAMBDA_EXEC_WRAPPER: this.props.siteExecWrapperPath ?? '/opt/bootstrap',
233
+ LOG_LEVEL: this.props.logLevel,
234
+ NODE_ENV: this.props.nodeEnv,
235
+ PORT: this.props.sitePort,
236
+ READINESS_CHECK_PATH: this.props.siteHealthEndpoint,
237
+ READINESS_CHECK_PORT: this.props.sitePort,
238
+ STAGE: this.props.stage,
239
+ TZ: this.props.timezone,
240
+ };
241
+ }
242
+ createSiteLambdaLayers() {
243
+ this.siteLambdaLayers = this.lambdaManager.createWebAdapterLayer(`${this.id}-web-adapter`, this);
244
+ }
245
+ createSiteLambdaApplication() { }
246
+ createSiteLambda() {
247
+ this.siteLambdaFunction = this.lambdaManager.createLambdaFunction(`${this.id}-lambda`, this, this.props.siteLambda, this.siteLambdaRole, this.siteLambdaLayers, this.siteLambdaApplication, this.props.siteLambda.handler, this.siteLambdaEnvironment);
248
+ }
249
+ createSiteLambdaUrl() {
250
+ const lambdaAlias = lodash_1.default.find(this.props.siteLambda.lambdaAliases, alias => alias.aliasName === constants_1.LAMBDA_ALIAS_NAME_CURRENT);
251
+ const lambdaFn = lambdaAlias
252
+ ? aws_lambda_1.Function.fromFunctionAttributes(this, `${this.id}-fn-alias`, {
253
+ functionArn: `${this.siteLambdaFunction.functionArn}:${lambdaAlias.aliasName}`,
254
+ sameEnvironment: true,
255
+ })
256
+ : this.siteLambdaFunction;
257
+ lambdaFn.node.addDependency(this.siteLambdaFunction);
258
+ this.siteLambdaUrl = lambdaFn.addFunctionUrl({
259
+ authType: aws_lambda_1.FunctionUrlAuthType.NONE,
260
+ });
261
+ this.siteLambdaUrl.node.addDependency(this.siteLambdaFunction);
262
+ this.siteLambdaUrl.node.addDependency(lambdaFn);
263
+ const principal = new aws_iam_1.AnyPrincipal();
264
+ principal.addToPolicy(new aws_iam_1.PolicyStatement({
265
+ actions: ['lambda:InvokeFunctionUrl'],
266
+ conditions: { StringEquals: { 'lambda:FunctionUrlAuthType': aws_lambda_1.FunctionUrlAuthType.NONE } },
267
+ effect: aws_iam_1.Effect.ALLOW,
268
+ resources: ['*'],
269
+ }));
270
+ lambdaFn.grantInvokeUrl({ grantPrincipal: principal });
271
+ this.addCfnOutput(`${this.id}-url`, this.siteLambdaUrl.url);
272
+ }
273
+ /**
274
+ * @summary Method to create a site cloudfront function
275
+ */
276
+ createSiteCloudfrontFunction() {
277
+ if (this.props.siteCloudfrontFunctionProps) {
278
+ this.siteCloudfrontFunction = this.cloudFrontManager.createCloudfrontFunction(`${this.id}-function`, this, this.props.siteCloudfrontFunctionProps);
279
+ }
280
+ }
281
+ /**
282
+ * @summary Method to create a site cloudfront function associations
283
+ */
284
+ resolveSiteFunctionAssociations() {
285
+ if (this.props.siteCloudfrontFunctionProps) {
286
+ this.siteFunctionAssociations = [
287
+ {
288
+ eventType: aws_cloudfront_1.FunctionEventType.VIEWER_REQUEST,
289
+ function: this.siteCloudfrontFunction,
290
+ },
291
+ ];
292
+ }
293
+ }
294
+ /**
295
+ * Method to create Site distribution
296
+ */
297
+ createDistribution() {
298
+ this.siteDistribution = this.cloudFrontManager.createDistributionWithHttpOrigin(`${this.id}-distribution`, this, this.props.siteDistribution, this.siteOrigin, this.siteDomainNames, this.siteLogBucket, this.siteCertificate, this.siteFunctionAssociations, this.props.siteDistribution.defaultBehavior.responseHeadersPolicy);
299
+ this.siteDistribution.node.addDependency(this.siteLambdaFunction);
300
+ this.siteDistribution.node.addDependency(this.siteLambdaUrl);
301
+ }
302
+ /**
303
+ * Method to create Route53 records for distribution
304
+ */
305
+ createNetworkMappings() {
306
+ this.route53Manager.createCloudFrontTargetARecord(`${this.id}-a-record`, this, this.siteDistribution, this.siteHostedZone, this.props.siteRecordName, this.props.skipStageForARecords);
307
+ }
308
+ /**
309
+ * Method to invalidation the cloudfront distribution cache after a deployment
310
+ */
311
+ invalidateDistributionCache() {
312
+ if (this.props.siteCacheInvalidationDockerFilePath) {
313
+ this.cloudFrontManager.invalidateCache(`${this.id}-cache-invalidation`, this, this.props.siteCacheInvalidationDockerFilePath, this.siteDistribution.distributionId);
314
+ }
315
+ }
316
+ }
317
+ exports.SiteWithLambdaBackend = SiteWithLambdaBackend;
@@ -0,0 +1,45 @@
1
+ import { CachePolicyProps, OriginRequestPolicyProps, ResponseHeadersPolicyProps, ResponseHeadersStrictTransportSecurity, ResponseSecurityHeadersBehavior } from 'aws-cdk-lib/aws-cloudfront';
2
+ import { CommonStackProps } from '../../common';
3
+ import { AcmProps, CloudfrontFunctionProps, DistributionProps, LambdaProps, LogProps, S3BucketProps } from '../../services';
4
+ import { SiteWithLambdaBackendResponseHeaderPolicyType } from './constants';
5
+ /**
6
+ */
7
+ export interface SiteWithLambdaBackendProps extends CommonStackProps {
8
+ logLevel: string;
9
+ nodeEnv: string;
10
+ siteCacheInvalidationDockerFilePath?: string;
11
+ siteCertificate: AcmProps;
12
+ siteCloudfrontFunctionProps?: CloudfrontFunctionProps;
13
+ siteDistribution: DistributionProps;
14
+ siteExecWrapperPath: string;
15
+ siteFunctionFilePath?: string;
16
+ siteHealthEndpoint: string;
17
+ siteLambda: LambdaProps;
18
+ siteLog: LogProps;
19
+ siteLogBucket: S3BucketProps;
20
+ sitePort: string;
21
+ siteCachePolicy?: SiteWithLambdaBackendCachePolicyProps;
22
+ siteOriginRequestPolicy: OriginRequestPolicyProps;
23
+ siteOriginResponseHeadersPolicy: SiteWithLambdaBackendResponseHeadersPolicyProps;
24
+ siteRecordName?: string;
25
+ siteRegionalCertificate: AcmProps;
26
+ siteSubDomain: string;
27
+ timezone: string;
28
+ useExistingHostedZone: boolean;
29
+ useExistingVpc: boolean;
30
+ }
31
+ export interface SiteWithLambdaBackendResponseHeadersStrictTransportSecurity extends ResponseHeadersStrictTransportSecurity {
32
+ accessControlMaxAgeInSeconds: number;
33
+ }
34
+ export interface SiteWithLambdaBackendSecurityHeadersBehavior extends ResponseSecurityHeadersBehavior {
35
+ strictTransportSecurity: SiteWithLambdaBackendResponseHeadersStrictTransportSecurity;
36
+ }
37
+ export interface SiteWithLambdaBackendResponseHeadersPolicyProps extends ResponseHeadersPolicyProps {
38
+ securityHeadersBehavior: SiteWithLambdaBackendSecurityHeadersBehavior;
39
+ type: SiteWithLambdaBackendResponseHeaderPolicyType;
40
+ }
41
+ export interface SiteWithLambdaBackendCachePolicyProps extends CachePolicyProps {
42
+ defaultTtlInSeconds: number;
43
+ minTtlInSeconds: number;
44
+ maxTtlInSeconds: number;
45
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -182,7 +182,7 @@ class CloudWatchManager {
182
182
  const metricProps = props.metricProps;
183
183
  return this.createWidget(id, scope, {
184
184
  ...props,
185
- metricProps: lodash_1.default.map(metricProps, { ...lodash_1.default, distributionId }),
185
+ metricProps: metricProps.map(metricProp => ({ ...metricProp, distributionId })),
186
186
  });
187
187
  }
188
188
  /**
@@ -198,7 +198,7 @@ class CloudWatchManager {
198
198
  const metricProps = props.metricProps;
199
199
  return this.createWidget(id, scope, {
200
200
  ...props,
201
- metricProps: lodash_1.default.map(metricProps, { ...lodash_1.default, stateMachineArn }),
201
+ metricProps: metricProps.map(metricProp => ({ ...metricProp, stateMachineArn })),
202
202
  });
203
203
  }
204
204
  /**
@@ -215,7 +215,7 @@ class CloudWatchManager {
215
215
  const metricProps = props.metricProps;
216
216
  return this.createWidget(id, scope, {
217
217
  ...props,
218
- metricProps: lodash_1.default.map(metricProps, { ...lodash_1.default, eventBusName, ruleName }),
218
+ metricProps: metricProps.map(metricProp => ({ ...metricProp, eventBusName, ruleName })),
219
219
  });
220
220
  }
221
221
  /**
@@ -231,7 +231,7 @@ class CloudWatchManager {
231
231
  const metricProps = props.metricProps;
232
232
  return this.createWidget(id, scope, {
233
233
  ...props,
234
- metricProps: lodash_1.default.map(metricProps, { ...lodash_1.default, apiName }),
234
+ metricProps: metricProps.map(metricProp => ({ ...metricProp, apiName })),
235
235
  });
236
236
  }
237
237
  /**
@@ -247,7 +247,7 @@ class CloudWatchManager {
247
247
  const metricProps = props.metricProps;
248
248
  return this.createWidget(id, scope, {
249
249
  ...props,
250
- metricProps: lodash_1.default.map(metricProps, { ...lodash_1.default, functionName }),
250
+ metricProps: metricProps.map(metricProp => ({ ...metricProp, functionName })),
251
251
  });
252
252
  }
253
253
  /**
@@ -263,7 +263,7 @@ class CloudWatchManager {
263
263
  const metricProps = props.metricProps;
264
264
  return this.createWidget(id, scope, {
265
265
  ...props,
266
- metricProps: lodash_1.default.map(metricProps, { ...lodash_1.default, service }),
266
+ metricProps: metricProps.map(metricProp => ({ ...metricProp, service })),
267
267
  });
268
268
  }
269
269
  /**
@@ -279,7 +279,7 @@ class CloudWatchManager {
279
279
  const metricProps = props.metricProps;
280
280
  return this.createWidget(id, scope, {
281
281
  ...props,
282
- metricProps: lodash_1.default.map(metricProps, { ...lodash_1.default, clusterName }),
282
+ metricProps: metricProps.map(metricProp => ({ ...metricProp, clusterName })),
283
283
  });
284
284
  }
285
285
  /**
@@ -296,7 +296,7 @@ class CloudWatchManager {
296
296
  const metricProps = props.metricProps;
297
297
  return this.createWidget(id, scope, {
298
298
  ...props,
299
- metricProps: lodash_1.default.map(metricProps, { ...lodash_1.default, clusterName, serviceName }),
299
+ metricProps: metricProps.map(metricProp => ({ ...metricProp, clusterName, serviceName })),
300
300
  });
301
301
  }
302
302
  /**
@@ -312,7 +312,7 @@ class CloudWatchManager {
312
312
  const metricProps = props.metricProps;
313
313
  return this.createWidget(id, scope, {
314
314
  ...props,
315
- metricProps: lodash_1.default.map(metricProps, { ...lodash_1.default, loadBalancer }),
315
+ metricProps: metricProps.map(metricProp => ({ ...metricProp, loadBalancer })),
316
316
  });
317
317
  }
318
318
  /**
@@ -328,7 +328,7 @@ class CloudWatchManager {
328
328
  const metricProps = props.metricProps;
329
329
  return this.createWidget(id, scope, {
330
330
  ...props,
331
- metricProps: lodash_1.default.map(metricProps, { ...lodash_1.default, cacheClusterId }),
331
+ metricProps: metricProps.map(metricProp => ({ ...metricProp, cacheClusterId })),
332
332
  });
333
333
  }
334
334
  /**