@gradientedge/cdk-utils 9.0.0 → 9.2.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/README.md +22 -0
- package/app/api-destined-function/node_modules/.bin/rimraf +2 -2
- package/dist/src/lib/aws/common/stack.js +3 -2
- package/dist/src/lib/aws/construct/static-asset-deployment/main.d.ts +7 -3
- package/dist/src/lib/aws/construct/static-asset-deployment/main.js +60 -7
- package/dist/src/lib/aws/construct/static-asset-deployment/types.d.ts +30 -1
- package/dist/src/lib/aws/services/cloudfront/main.d.ts +2 -1
- package/dist/src/lib/aws/services/cloudfront/main.js +3 -0
- package/dist/src/lib/aws/services/eventbridge/main.js +3 -0
- package/dist/src/lib/aws/services/eventbridge/types.d.ts +1 -0
- package/dist/src/lib/azure/common/stack.js +3 -2
- package/dist/src/lib/cloudflare/common/stack.js +3 -2
- package/package.json +8 -4
- package/src/lib/aws/common/stack.ts +5 -2
- package/src/lib/aws/construct/static-asset-deployment/main.ts +71 -10
- package/src/lib/aws/construct/static-asset-deployment/types.ts +31 -1
- package/src/lib/aws/services/cloudfront/main.ts +6 -0
- package/src/lib/aws/services/eventbridge/main.ts +3 -0
- package/src/lib/aws/services/eventbridge/types.ts +1 -0
- package/src/lib/azure/common/stack.ts +3 -2
- package/src/lib/cloudflare/common/stack.ts +3 -3
package/README.md
CHANGED
|
@@ -57,6 +57,28 @@ pnpm add @gradientedge/cdk-utils
|
|
|
57
57
|
"@gradientedge/cdk-utils": "latest"
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
+
## Testing
|
|
61
|
+
|
|
62
|
+
To run test cases, use the following command:
|
|
63
|
+
|
|
64
|
+
```shell
|
|
65
|
+
pnpm run test
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
To focus on the test and watch when you make changes, use the following command:
|
|
69
|
+
|
|
70
|
+
```shell
|
|
71
|
+
pnpm test:watch static-asset-deployment-distribution-ref.test.ts
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Toolkit
|
|
75
|
+
|
|
76
|
+
There are common utilities that help with testing constructs which you can find in the [test tools](./src/test/tools/cdk) directory.
|
|
77
|
+
|
|
78
|
+
### Debug
|
|
79
|
+
|
|
80
|
+
There is a debug utility that can be used to print out the contents of a `template`. This is useful for debugging and understanding the structure which you can find in the [debug](./src/test/tools/debug) directory.
|
|
81
|
+
|
|
60
82
|
<!-- references -->
|
|
61
83
|
|
|
62
84
|
[aws-cdk]: https://docs.aws.amazon.com/cdk/latest/guide/home.html
|
|
@@ -6,9 +6,9 @@ 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.
|
|
9
|
+
export NODE_PATH="/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.7/node_modules/rimraf/dist/esm/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.7/node_modules/rimraf/dist/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.7/node_modules/rimraf/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.7/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.
|
|
11
|
+
export NODE_PATH="/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.7/node_modules/rimraf/dist/esm/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.7/node_modules/rimraf/dist/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.7/node_modules/rimraf/node_modules:/home/runner/work/cdk-utils/cdk-utils/node_modules/.pnpm/rimraf@5.0.7/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
14
|
exec "$basedir/node" "$basedir/../rimraf/dist/esm/bin.mjs" "$@"
|
|
@@ -7,6 +7,7 @@ exports.CommonStack = void 0;
|
|
|
7
7
|
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
8
8
|
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
|
|
9
9
|
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
10
11
|
const construct_1 = require("./construct");
|
|
11
12
|
const app_root_path_1 = __importDefault(require("app-root-path"));
|
|
12
13
|
const lodash_1 = __importDefault(require("lodash"));
|
|
@@ -71,7 +72,7 @@ class CommonStack extends aws_cdk_lib_1.Stack {
|
|
|
71
72
|
return;
|
|
72
73
|
}
|
|
73
74
|
lodash_1.default.forEach(extraContexts, (context) => {
|
|
74
|
-
const extraContextPath =
|
|
75
|
+
const extraContextPath = path_1.default.join(app_root_path_1.default.path, context);
|
|
75
76
|
/* scenario where extra context is configured in cdk.json but absent in file system */
|
|
76
77
|
if (!fs_1.default.existsSync(extraContextPath))
|
|
77
78
|
throw `Extra context properties unavailable in path:${extraContextPath}`;
|
|
@@ -95,7 +96,7 @@ class CommonStack extends aws_cdk_lib_1.Stack {
|
|
|
95
96
|
determineStageContexts() {
|
|
96
97
|
const stage = this.node.tryGetContext('stage');
|
|
97
98
|
const stageContextPath = this.node.tryGetContext('stageContextPath') || 'cdkEnv';
|
|
98
|
-
const stageContextFilePath =
|
|
99
|
+
const stageContextFilePath = path_1.default.join(app_root_path_1.default.path, stageContextPath, `${stage}.json`);
|
|
99
100
|
const debug = this.node.tryGetContext('debug');
|
|
100
101
|
if ((0, common_1.isDevStage)(stage)) {
|
|
101
102
|
if (debug)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IBucket } from 'aws-cdk-lib/aws-s3';
|
|
2
|
+
import { IDistribution } from 'aws-cdk-lib/aws-cloudfront';
|
|
2
3
|
import { Construct } from 'constructs';
|
|
3
4
|
import { CommonConstruct } from '../../common';
|
|
4
5
|
import { StaticAssetDeploymentProps } from './types';
|
|
@@ -11,16 +12,15 @@ import { StaticAssetDeploymentProps } from './types';
|
|
|
11
12
|
* class CustomConstruct extends StaticAssetDeployment {
|
|
12
13
|
* constructor(parent: Construct, id: string, props: StaticAssetDeploymentProps) {
|
|
13
14
|
* super(parent, id, props)
|
|
14
|
-
* this.props = props
|
|
15
|
-
* this.id = id
|
|
16
15
|
* this.initResources()
|
|
17
16
|
* }
|
|
18
17
|
* }
|
|
19
18
|
*/
|
|
20
19
|
export declare class StaticAssetDeployment extends CommonConstruct {
|
|
20
|
+
staticAssetBucket: IBucket;
|
|
21
|
+
cloudfrontDistribution?: IDistribution;
|
|
21
22
|
props: StaticAssetDeploymentProps;
|
|
22
23
|
id: string;
|
|
23
|
-
staticAssetBucket: IBucket;
|
|
24
24
|
constructor(parent: Construct, id: string, props: StaticAssetDeploymentProps);
|
|
25
25
|
/**
|
|
26
26
|
* @summary Initialise and provision resources
|
|
@@ -30,6 +30,10 @@ export declare class StaticAssetDeployment extends CommonConstruct {
|
|
|
30
30
|
* @summary Create the static asset bucket
|
|
31
31
|
*/
|
|
32
32
|
protected createAssetBucket(): void;
|
|
33
|
+
/**
|
|
34
|
+
* @summary Distribute the load for the static asset bucket if both distribution and paths are provided
|
|
35
|
+
*/
|
|
36
|
+
protected resolveDistribution(): void;
|
|
33
37
|
/**
|
|
34
38
|
* @summary Deploy the static assets into the static asset bucket
|
|
35
39
|
*/
|
|
@@ -4,9 +4,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.StaticAssetDeployment = void 0;
|
|
7
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
7
8
|
const aws_s3_deployment_1 = require("aws-cdk-lib/aws-s3-deployment");
|
|
8
9
|
const lodash_1 = __importDefault(require("lodash"));
|
|
9
10
|
const common_1 = require("../../common");
|
|
11
|
+
const app_root_path_1 = __importDefault(require("app-root-path"));
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
10
13
|
/**
|
|
11
14
|
* @classdesc Provides a construct to create and deploy static assets into S3 bucket
|
|
12
15
|
* @example
|
|
@@ -16,28 +19,27 @@ const common_1 = require("../../common");
|
|
|
16
19
|
* class CustomConstruct extends StaticAssetDeployment {
|
|
17
20
|
* constructor(parent: Construct, id: string, props: StaticAssetDeploymentProps) {
|
|
18
21
|
* super(parent, id, props)
|
|
19
|
-
* this.props = props
|
|
20
|
-
* this.id = id
|
|
21
22
|
* this.initResources()
|
|
22
23
|
* }
|
|
23
24
|
* }
|
|
24
25
|
*/
|
|
25
26
|
class StaticAssetDeployment extends common_1.CommonConstruct {
|
|
26
|
-
/* construct properties */
|
|
27
|
-
props;
|
|
28
|
-
id;
|
|
29
27
|
/* construct resources */
|
|
30
28
|
staticAssetBucket;
|
|
29
|
+
cloudfrontDistribution;
|
|
30
|
+
props;
|
|
31
|
+
id;
|
|
31
32
|
constructor(parent, id, props) {
|
|
32
33
|
super(parent, id, props);
|
|
33
|
-
this.props = props;
|
|
34
34
|
this.id = id;
|
|
35
|
+
this.props = props;
|
|
35
36
|
}
|
|
36
37
|
/**
|
|
37
38
|
* @summary Initialise and provision resources
|
|
38
39
|
*/
|
|
39
40
|
initResources() {
|
|
40
41
|
this.createAssetBucket();
|
|
42
|
+
this.resolveDistribution();
|
|
41
43
|
this.deployStaticAssets();
|
|
42
44
|
}
|
|
43
45
|
/**
|
|
@@ -46,14 +48,65 @@ class StaticAssetDeployment extends common_1.CommonConstruct {
|
|
|
46
48
|
createAssetBucket() {
|
|
47
49
|
this.staticAssetBucket = this.s3Manager.createS3Bucket(`${this.id}-sa-bucket`, this, this.props.staticAssetBucket);
|
|
48
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* @summary Distribute the load for the static asset bucket if both distribution and paths are provided
|
|
53
|
+
*/
|
|
54
|
+
resolveDistribution() {
|
|
55
|
+
if (this.props.cloudFrontDistribution &&
|
|
56
|
+
(this.props.cloudFrontDistribution.domainName || this.props.cloudFrontDistribution.domainNameRef) &&
|
|
57
|
+
(this.props.cloudFrontDistribution.distributionId || this.props.cloudFrontDistribution.distributionIdRef) &&
|
|
58
|
+
this.props.cloudFrontDistribution.invalidationPaths &&
|
|
59
|
+
this.props.cloudFrontDistribution.invalidationPaths.length > 0) {
|
|
60
|
+
let domainName = this.props.cloudFrontDistribution.domainName;
|
|
61
|
+
if (this.props.cloudFrontDistribution.domainNameRef) {
|
|
62
|
+
domainName = aws_cdk_lib_1.Fn.importValue(this.props.cloudFrontDistribution.domainNameRef);
|
|
63
|
+
}
|
|
64
|
+
let distributionId = this.props.cloudFrontDistribution.distributionId;
|
|
65
|
+
if (this.props.cloudFrontDistribution.distributionIdRef) {
|
|
66
|
+
distributionId = aws_cdk_lib_1.Fn.importValue(this.props.cloudFrontDistribution.distributionIdRef);
|
|
67
|
+
}
|
|
68
|
+
const distributionAttributes = {
|
|
69
|
+
domainName: domainName,
|
|
70
|
+
distributionId: distributionId,
|
|
71
|
+
};
|
|
72
|
+
this.cloudfrontDistribution = this.cloudFrontManager.resolveDistribution(this, distributionAttributes);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
49
75
|
/**
|
|
50
76
|
* @summary Deploy the static assets into the static asset bucket
|
|
51
77
|
*/
|
|
52
78
|
deployStaticAssets() {
|
|
79
|
+
let sources = [];
|
|
80
|
+
if (Array.isArray(this.props.staticAssetSources) &&
|
|
81
|
+
this.props.staticAssetSources.length > 0 &&
|
|
82
|
+
typeof this.props.staticAssetSources[0] === 'string') {
|
|
83
|
+
sources = this.props.staticAssetSources.map(source => {
|
|
84
|
+
const resolvedPath = path_1.default.join(app_root_path_1.default.path, source);
|
|
85
|
+
return aws_s3_deployment_1.Source.asset(resolvedPath);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
sources = this.props.staticAssetSources;
|
|
90
|
+
}
|
|
91
|
+
let distributionOptions = {};
|
|
92
|
+
if (this.cloudfrontDistribution) {
|
|
93
|
+
distributionOptions = {
|
|
94
|
+
distribution: this.cloudfrontDistribution,
|
|
95
|
+
distributionPaths: this.props.cloudFrontDistribution?.invalidationPaths,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
let destinationKeyPrefixOptions = {};
|
|
99
|
+
if (this.props.destinationKeyPrefix) {
|
|
100
|
+
destinationKeyPrefixOptions = {
|
|
101
|
+
destinationKeyPrefix: this.props.destinationKeyPrefix,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
53
104
|
new aws_s3_deployment_1.BucketDeployment(this, `${this.id}-static-deployment`, {
|
|
54
105
|
...this.props.staticAssetDeployment,
|
|
55
106
|
destinationBucket: this.staticAssetBucket,
|
|
56
|
-
sources:
|
|
107
|
+
sources: sources,
|
|
108
|
+
...destinationKeyPrefixOptions,
|
|
109
|
+
...distributionOptions,
|
|
57
110
|
});
|
|
58
111
|
const staticAssetsForExport = this.props.staticAssetsForExport;
|
|
59
112
|
if (!staticAssetsForExport)
|
|
@@ -4,9 +4,38 @@ export interface AssetExport {
|
|
|
4
4
|
key: string;
|
|
5
5
|
value: string;
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* The CloudFront distribution to associate with the bucket.
|
|
9
|
+
* When value is configured, the construct will invalidate the distribution after the deployment.
|
|
10
|
+
* Use either domainName or distributionId or domainNameRef or distributionIdRef.
|
|
11
|
+
*/
|
|
12
|
+
export interface StaticCloudFrontDistribution {
|
|
13
|
+
/**
|
|
14
|
+
* @summary The domain name to associate with the bucket.
|
|
15
|
+
*/
|
|
16
|
+
domainName?: string;
|
|
17
|
+
/**
|
|
18
|
+
* @summary The distribution ID to associate with the bucket.
|
|
19
|
+
*/
|
|
20
|
+
distributionId?: string;
|
|
21
|
+
/**
|
|
22
|
+
* @summary The reference to domain name to associate with the bucket.
|
|
23
|
+
*/
|
|
24
|
+
domainNameRef?: string;
|
|
25
|
+
/**
|
|
26
|
+
* @summary The reference to distribution ID to associate with the bucket.
|
|
27
|
+
*/
|
|
28
|
+
distributionIdRef?: string;
|
|
29
|
+
/**
|
|
30
|
+
* @summary The paths to invalidate after deployment. Default is ['/*']
|
|
31
|
+
*/
|
|
32
|
+
invalidationPaths: string[];
|
|
33
|
+
}
|
|
7
34
|
export interface StaticAssetDeploymentProps extends CommonStackProps {
|
|
8
35
|
staticAssetBucket: S3BucketProps;
|
|
9
36
|
staticAssetDeployment: BucketDeploymentProps;
|
|
10
|
-
staticAssetSources: any[];
|
|
37
|
+
staticAssetSources: any[] | string[];
|
|
11
38
|
staticAssetsForExport?: AssetExport[];
|
|
39
|
+
destinationKeyPrefix?: string;
|
|
40
|
+
cloudFrontDistribution?: StaticCloudFrontDistribution;
|
|
12
41
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ICertificate } from 'aws-cdk-lib/aws-certificatemanager';
|
|
2
2
|
import * as cf from 'aws-cdk-lib/aws-cloudfront';
|
|
3
|
-
import { FunctionAssociation, IResponseHeadersPolicy, OriginAccessIdentity } from 'aws-cdk-lib/aws-cloudfront';
|
|
3
|
+
import { IDistribution, DistributionAttributes, FunctionAssociation, IResponseHeadersPolicy, OriginAccessIdentity } from 'aws-cdk-lib/aws-cloudfront';
|
|
4
4
|
import { HttpOrigin, S3Origin } from 'aws-cdk-lib/aws-cloudfront-origins';
|
|
5
5
|
import { ISecurityGroup, IVpc } from 'aws-cdk-lib/aws-ec2';
|
|
6
6
|
import { IAccessPoint } from 'aws-cdk-lib/aws-efs';
|
|
@@ -105,4 +105,5 @@ export declare class CloudFrontManager {
|
|
|
105
105
|
* @param props
|
|
106
106
|
*/
|
|
107
107
|
createCloudfrontFunction(id: string, scope: CommonConstruct, props: CloudfrontFunctionProps): cf.Function;
|
|
108
|
+
resolveDistribution(scope: CommonConstruct, props: DistributionAttributes): IDistribution;
|
|
108
109
|
}
|
|
@@ -297,5 +297,8 @@ class CloudFrontManager {
|
|
|
297
297
|
(0, utils_1.createCfnOutput)(`${id}-functionName`, scope, cloudfrontFunction.functionName);
|
|
298
298
|
return cloudfrontFunction;
|
|
299
299
|
}
|
|
300
|
+
resolveDistribution(scope, props) {
|
|
301
|
+
return aws_cloudfront_1.Distribution.fromDistributionAttributes(scope, `${scope.node.id}-sa-distribution`, props);
|
|
302
|
+
}
|
|
300
303
|
}
|
|
301
304
|
exports.CloudFrontManager = CloudFrontManager;
|
|
@@ -225,6 +225,9 @@ class EventManager {
|
|
|
225
225
|
},
|
|
226
226
|
},
|
|
227
227
|
target: targetLambdaFunction.functionArn,
|
|
228
|
+
targetParameters: {
|
|
229
|
+
inputTemplate: props.lambdaInputTemplate,
|
|
230
|
+
},
|
|
228
231
|
});
|
|
229
232
|
(0, utils_1.createCfnOutput)(`${id}-pipeArn`, scope, pipe.attrArn);
|
|
230
233
|
(0, utils_1.createCfnOutput)(`${id}-pipeName`, scope, pipe.name);
|
|
@@ -15,6 +15,7 @@ export interface SqsToSfnPipeProps extends CfnPipeProps {
|
|
|
15
15
|
export interface SqsToLambdaPipeProps extends CfnPipeProps {
|
|
16
16
|
pipeFilterPattern?: any;
|
|
17
17
|
sqsBatchSize?: number;
|
|
18
|
+
lambdaInputTemplate?: string;
|
|
18
19
|
sqsMaximumBatchingWindowInSeconds?: number;
|
|
19
20
|
}
|
|
20
21
|
/**
|
|
@@ -10,6 +10,7 @@ const app_root_path_1 = __importDefault(require("app-root-path"));
|
|
|
10
10
|
const cdktf_1 = require("cdktf");
|
|
11
11
|
const lodash_1 = __importDefault(require("lodash"));
|
|
12
12
|
const common_1 = require("../../common");
|
|
13
|
+
const path_1 = __importDefault(require("path"));
|
|
13
14
|
/**
|
|
14
15
|
* @classdesc Common stack to use as a base for all higher level constructs.
|
|
15
16
|
* @example
|
|
@@ -66,7 +67,7 @@ class CommonAzureStack extends cdktf_1.TerraformStack {
|
|
|
66
67
|
return;
|
|
67
68
|
}
|
|
68
69
|
lodash_1.default.forEach(extraContexts, (context) => {
|
|
69
|
-
const extraContextPath =
|
|
70
|
+
const extraContextPath = path_1.default.join(app_root_path_1.default.path, context);
|
|
70
71
|
/* scenario where extra context is configured in cdk.json but absent in file system */
|
|
71
72
|
if (!fs_1.default.existsSync(extraContextPath))
|
|
72
73
|
throw `Extra context properties unavailable in path:${extraContextPath}`;
|
|
@@ -90,7 +91,7 @@ class CommonAzureStack extends cdktf_1.TerraformStack {
|
|
|
90
91
|
determineStageContexts() {
|
|
91
92
|
const stage = this.node.tryGetContext('stage');
|
|
92
93
|
const stageContextPath = this.node.tryGetContext('stageContextPath') || 'cdkEnv';
|
|
93
|
-
const stageContextFilePath =
|
|
94
|
+
const stageContextFilePath = path_1.default.join(app_root_path_1.default.path, stageContextPath, `${stage}.json`);
|
|
94
95
|
const debug = this.node.tryGetContext('debug');
|
|
95
96
|
if ((0, common_1.isDevStage)(stage)) {
|
|
96
97
|
if (debug)
|
|
@@ -9,6 +9,7 @@ const app_root_path_1 = __importDefault(require("app-root-path"));
|
|
|
9
9
|
const cdktf_1 = require("cdktf");
|
|
10
10
|
const lodash_1 = __importDefault(require("lodash"));
|
|
11
11
|
const common_1 = require("../../common");
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
12
13
|
/**
|
|
13
14
|
* @classdesc Common stack to use as a base for all higher level constructs.
|
|
14
15
|
* @example
|
|
@@ -65,7 +66,7 @@ class CommonCloudflareStack extends cdktf_1.TerraformStack {
|
|
|
65
66
|
return;
|
|
66
67
|
}
|
|
67
68
|
lodash_1.default.forEach(extraContexts, (context) => {
|
|
68
|
-
const extraContextPath =
|
|
69
|
+
const extraContextPath = path_1.default.join(app_root_path_1.default.path, context);
|
|
69
70
|
/* scenario where extra context is configured in cdk.json but absent in file system */
|
|
70
71
|
if (!fs_1.default.existsSync(extraContextPath))
|
|
71
72
|
throw `Extra context properties unavailable in path:${extraContextPath}`;
|
|
@@ -89,7 +90,7 @@ class CommonCloudflareStack extends cdktf_1.TerraformStack {
|
|
|
89
90
|
determineStageContexts() {
|
|
90
91
|
const stage = this.node.tryGetContext('stage');
|
|
91
92
|
const stageContextPath = this.node.tryGetContext('stageContextPath') || 'cdkEnv';
|
|
92
|
-
const stageContextFilePath =
|
|
93
|
+
const stageContextFilePath = path_1.default.join(app_root_path_1.default.path, stageContextPath, `${stage}.json`);
|
|
93
94
|
const debug = this.node.tryGetContext('debug');
|
|
94
95
|
if ((0, common_1.isDevStage)(stage)) {
|
|
95
96
|
if (debug)
|
package/package.json
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradientedge/cdk-utils",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.2.0",
|
|
4
4
|
"description": "Utilities for AWS CDK provisioning",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"engines": {
|
|
7
|
-
"node": ">=16 <=20"
|
|
7
|
+
"node": ">=16 <=20",
|
|
8
|
+
"pnpm": "=8"
|
|
8
9
|
},
|
|
10
|
+
"packageManager": "pnpm@8.15.8",
|
|
9
11
|
"repository": {
|
|
10
12
|
"type": "git",
|
|
11
13
|
"url": "git+https://github.com/gradientedge/cdk-utils.git"
|
|
@@ -38,6 +40,7 @@
|
|
|
38
40
|
"prettier": "npx prettier --cache --check \"**/*.{ts,json,md}\"",
|
|
39
41
|
"prettify": "npx prettier --cache --write \"**/*.{ts,json,md}\"",
|
|
40
42
|
"test": "npx rimraf coverage && npx jest --ci --maxWorkers=100%",
|
|
43
|
+
"test:watch": "npx jest --coverage=false --watchAll",
|
|
41
44
|
"update:deps": "ncu -u --deep --reject react,react-dom",
|
|
42
45
|
"validate": "pnpm prettier && pnpm lint && pnpm test"
|
|
43
46
|
},
|
|
@@ -57,7 +60,7 @@
|
|
|
57
60
|
"@types/node": "^20.12.7",
|
|
58
61
|
"@types/uuid": "^9.0.8",
|
|
59
62
|
"app-root-path": "^3.1.0",
|
|
60
|
-
"aws-cdk-lib": "^2.
|
|
63
|
+
"aws-cdk-lib": "^2.141.0",
|
|
61
64
|
"cdktf": "^0.20.7",
|
|
62
65
|
"cdktf-local-exec": "^0.5.13",
|
|
63
66
|
"constructs": "^10.3.0",
|
|
@@ -101,7 +104,8 @@
|
|
|
101
104
|
"taffydb": "^2.7.3",
|
|
102
105
|
"ts-jest": "^29.1.2",
|
|
103
106
|
"ts-node": "^10.9.2",
|
|
104
|
-
"typescript": "5.4.5"
|
|
107
|
+
"typescript": "5.4.5",
|
|
108
|
+
"yaml": "^2.4.2"
|
|
105
109
|
},
|
|
106
110
|
"optionalDependencies": {
|
|
107
111
|
"prop-types": "^15.8.1",
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { App, Stack, StackProps } from 'aws-cdk-lib'
|
|
2
2
|
import { Runtime } from 'aws-cdk-lib/aws-lambda'
|
|
3
3
|
import fs from 'fs'
|
|
4
|
+
import path from 'path'
|
|
5
|
+
|
|
4
6
|
import { CommonConstruct } from './construct'
|
|
5
7
|
import { CommonStackProps } from './types'
|
|
6
8
|
|
|
@@ -77,7 +79,7 @@ export class CommonStack extends Stack {
|
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
_.forEach(extraContexts, (context: string) => {
|
|
80
|
-
const extraContextPath =
|
|
82
|
+
const extraContextPath = path.join(appRoot.path, context)
|
|
81
83
|
|
|
82
84
|
/* scenario where extra context is configured in cdk.json but absent in file system */
|
|
83
85
|
if (!fs.existsSync(extraContextPath)) throw `Extra context properties unavailable in path:${extraContextPath}`
|
|
@@ -104,7 +106,8 @@ export class CommonStack extends Stack {
|
|
|
104
106
|
protected determineStageContexts() {
|
|
105
107
|
const stage = this.node.tryGetContext('stage')
|
|
106
108
|
const stageContextPath = this.node.tryGetContext('stageContextPath') || 'cdkEnv'
|
|
107
|
-
const stageContextFilePath =
|
|
109
|
+
const stageContextFilePath = path.join(appRoot.path, stageContextPath, `${stage}.json`)
|
|
110
|
+
|
|
108
111
|
const debug = this.node.tryGetContext('debug')
|
|
109
112
|
|
|
110
113
|
if (isDevStage(stage)) {
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import { Fn } from 'aws-cdk-lib'
|
|
1
2
|
import { IBucket } from 'aws-cdk-lib/aws-s3'
|
|
2
|
-
import {
|
|
3
|
+
import { IDistribution, DistributionAttributes } from 'aws-cdk-lib/aws-cloudfront'
|
|
3
4
|
import { Construct } from 'constructs'
|
|
5
|
+
import { BucketDeployment, Source, BucketDeploymentProps, ISource } from 'aws-cdk-lib/aws-s3-deployment'
|
|
4
6
|
import _ from 'lodash'
|
|
5
7
|
import { CommonConstruct } from '../../common'
|
|
6
8
|
import { StaticAssetDeploymentProps } from './types'
|
|
9
|
+
import appRoot from 'app-root-path'
|
|
10
|
+
import path from 'path'
|
|
7
11
|
|
|
8
12
|
/**
|
|
9
13
|
* @classdesc Provides a construct to create and deploy static assets into S3 bucket
|
|
@@ -14,31 +18,28 @@ import { StaticAssetDeploymentProps } from './types'
|
|
|
14
18
|
* class CustomConstruct extends StaticAssetDeployment {
|
|
15
19
|
* constructor(parent: Construct, id: string, props: StaticAssetDeploymentProps) {
|
|
16
20
|
* super(parent, id, props)
|
|
17
|
-
* this.props = props
|
|
18
|
-
* this.id = id
|
|
19
21
|
* this.initResources()
|
|
20
22
|
* }
|
|
21
23
|
* }
|
|
22
24
|
*/
|
|
23
25
|
export class StaticAssetDeployment extends CommonConstruct {
|
|
24
|
-
/* construct properties */
|
|
25
|
-
props: StaticAssetDeploymentProps
|
|
26
|
-
id: string
|
|
27
|
-
|
|
28
26
|
/* construct resources */
|
|
29
27
|
staticAssetBucket: IBucket
|
|
28
|
+
cloudfrontDistribution?: IDistribution
|
|
29
|
+
props: StaticAssetDeploymentProps
|
|
30
|
+
id: string
|
|
30
31
|
|
|
31
32
|
constructor(parent: Construct, id: string, props: StaticAssetDeploymentProps) {
|
|
32
33
|
super(parent, id, props)
|
|
33
|
-
this.props = props
|
|
34
34
|
this.id = id
|
|
35
|
+
this.props = props
|
|
35
36
|
}
|
|
36
|
-
|
|
37
37
|
/**
|
|
38
38
|
* @summary Initialise and provision resources
|
|
39
39
|
*/
|
|
40
40
|
public initResources() {
|
|
41
41
|
this.createAssetBucket()
|
|
42
|
+
this.resolveDistribution()
|
|
42
43
|
this.deployStaticAssets()
|
|
43
44
|
}
|
|
44
45
|
|
|
@@ -49,14 +50,74 @@ export class StaticAssetDeployment extends CommonConstruct {
|
|
|
49
50
|
this.staticAssetBucket = this.s3Manager.createS3Bucket(`${this.id}-sa-bucket`, this, this.props.staticAssetBucket)
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
/**
|
|
54
|
+
* @summary Distribute the load for the static asset bucket if both distribution and paths are provided
|
|
55
|
+
*/
|
|
56
|
+
protected resolveDistribution() {
|
|
57
|
+
if (
|
|
58
|
+
this.props.cloudFrontDistribution &&
|
|
59
|
+
(this.props.cloudFrontDistribution.domainName || this.props.cloudFrontDistribution.domainNameRef) &&
|
|
60
|
+
(this.props.cloudFrontDistribution.distributionId || this.props.cloudFrontDistribution.distributionIdRef) &&
|
|
61
|
+
this.props.cloudFrontDistribution.invalidationPaths &&
|
|
62
|
+
this.props.cloudFrontDistribution.invalidationPaths.length > 0
|
|
63
|
+
) {
|
|
64
|
+
let domainName = this.props.cloudFrontDistribution.domainName
|
|
65
|
+
if (this.props.cloudFrontDistribution.domainNameRef) {
|
|
66
|
+
domainName = Fn.importValue(this.props.cloudFrontDistribution.domainNameRef)
|
|
67
|
+
}
|
|
68
|
+
let distributionId = this.props.cloudFrontDistribution.distributionId
|
|
69
|
+
if (this.props.cloudFrontDistribution.distributionIdRef) {
|
|
70
|
+
distributionId = Fn.importValue(this.props.cloudFrontDistribution.distributionIdRef)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const distributionAttributes = {
|
|
74
|
+
domainName: domainName,
|
|
75
|
+
distributionId: distributionId,
|
|
76
|
+
} as any as DistributionAttributes
|
|
77
|
+
|
|
78
|
+
this.cloudfrontDistribution = this.cloudFrontManager.resolveDistribution(this, distributionAttributes)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
52
82
|
/**
|
|
53
83
|
* @summary Deploy the static assets into the static asset bucket
|
|
54
84
|
*/
|
|
55
85
|
protected deployStaticAssets() {
|
|
86
|
+
let sources: Array<ISource> = []
|
|
87
|
+
if (
|
|
88
|
+
Array.isArray(this.props.staticAssetSources) &&
|
|
89
|
+
this.props.staticAssetSources.length > 0 &&
|
|
90
|
+
typeof this.props.staticAssetSources[0] === 'string'
|
|
91
|
+
) {
|
|
92
|
+
sources = this.props.staticAssetSources.map(source => {
|
|
93
|
+
const resolvedPath = path.join(appRoot.path, source)
|
|
94
|
+
return Source.asset(resolvedPath)
|
|
95
|
+
})
|
|
96
|
+
} else {
|
|
97
|
+
sources = this.props.staticAssetSources as ISource[]
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let distributionOptions: Pick<BucketDeploymentProps, 'distribution' | 'distributionPaths'> = {}
|
|
101
|
+
if (this.cloudfrontDistribution) {
|
|
102
|
+
distributionOptions = {
|
|
103
|
+
distribution: this.cloudfrontDistribution,
|
|
104
|
+
distributionPaths: this.props.cloudFrontDistribution?.invalidationPaths,
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
let destinationKeyPrefixOptions = {}
|
|
109
|
+
if (this.props.destinationKeyPrefix) {
|
|
110
|
+
destinationKeyPrefixOptions = {
|
|
111
|
+
destinationKeyPrefix: this.props.destinationKeyPrefix,
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
56
115
|
new BucketDeployment(this, `${this.id}-static-deployment`, {
|
|
57
116
|
...this.props.staticAssetDeployment,
|
|
58
117
|
destinationBucket: this.staticAssetBucket,
|
|
59
|
-
sources:
|
|
118
|
+
sources: sources,
|
|
119
|
+
...destinationKeyPrefixOptions,
|
|
120
|
+
...distributionOptions,
|
|
60
121
|
})
|
|
61
122
|
|
|
62
123
|
const staticAssetsForExport = this.props.staticAssetsForExport
|
|
@@ -6,9 +6,39 @@ export interface AssetExport {
|
|
|
6
6
|
value: string
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* The CloudFront distribution to associate with the bucket.
|
|
11
|
+
* When value is configured, the construct will invalidate the distribution after the deployment.
|
|
12
|
+
* Use either domainName or distributionId or domainNameRef or distributionIdRef.
|
|
13
|
+
*/
|
|
14
|
+
export interface StaticCloudFrontDistribution {
|
|
15
|
+
/**
|
|
16
|
+
* @summary The domain name to associate with the bucket.
|
|
17
|
+
*/
|
|
18
|
+
domainName?: string
|
|
19
|
+
/**
|
|
20
|
+
* @summary The distribution ID to associate with the bucket.
|
|
21
|
+
*/
|
|
22
|
+
distributionId?: string
|
|
23
|
+
/**
|
|
24
|
+
* @summary The reference to domain name to associate with the bucket.
|
|
25
|
+
*/
|
|
26
|
+
domainNameRef?: string
|
|
27
|
+
/**
|
|
28
|
+
* @summary The reference to distribution ID to associate with the bucket.
|
|
29
|
+
*/
|
|
30
|
+
distributionIdRef?: string
|
|
31
|
+
/**
|
|
32
|
+
* @summary The paths to invalidate after deployment. Default is ['/*']
|
|
33
|
+
*/
|
|
34
|
+
invalidationPaths: string[]
|
|
35
|
+
}
|
|
36
|
+
|
|
9
37
|
export interface StaticAssetDeploymentProps extends CommonStackProps {
|
|
10
38
|
staticAssetBucket: S3BucketProps
|
|
11
39
|
staticAssetDeployment: BucketDeploymentProps
|
|
12
|
-
staticAssetSources: any[]
|
|
40
|
+
staticAssetSources: any[] | string[]
|
|
13
41
|
staticAssetsForExport?: AssetExport[]
|
|
42
|
+
destinationKeyPrefix?: string
|
|
43
|
+
cloudFrontDistribution?: StaticCloudFrontDistribution
|
|
14
44
|
}
|
|
@@ -2,6 +2,8 @@ import { Duration, Tags } from 'aws-cdk-lib'
|
|
|
2
2
|
import { ICertificate } from 'aws-cdk-lib/aws-certificatemanager'
|
|
3
3
|
import * as cf from 'aws-cdk-lib/aws-cloudfront'
|
|
4
4
|
import {
|
|
5
|
+
IDistribution,
|
|
6
|
+
DistributionAttributes,
|
|
5
7
|
CloudFrontWebDistribution,
|
|
6
8
|
Distribution,
|
|
7
9
|
Function,
|
|
@@ -362,4 +364,8 @@ export class CloudFrontManager {
|
|
|
362
364
|
|
|
363
365
|
return cloudfrontFunction
|
|
364
366
|
}
|
|
367
|
+
|
|
368
|
+
public resolveDistribution(scope: CommonConstruct, props: DistributionAttributes): IDistribution {
|
|
369
|
+
return Distribution.fromDistributionAttributes(scope, `${scope.node.id}-sa-distribution`, props)
|
|
370
|
+
}
|
|
365
371
|
}
|
|
@@ -7,6 +7,7 @@ import { TerraformStack } from 'cdktf'
|
|
|
7
7
|
import { Construct } from 'constructs'
|
|
8
8
|
import _ from 'lodash'
|
|
9
9
|
import { isDevStage } from '../../common'
|
|
10
|
+
import path from 'path'
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* @classdesc Common stack to use as a base for all higher level constructs.
|
|
@@ -72,7 +73,7 @@ export class CommonAzureStack extends TerraformStack {
|
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
_.forEach(extraContexts, (context: string) => {
|
|
75
|
-
const extraContextPath =
|
|
76
|
+
const extraContextPath = path.join(appRoot.path, context)
|
|
76
77
|
|
|
77
78
|
/* scenario where extra context is configured in cdk.json but absent in file system */
|
|
78
79
|
if (!fs.existsSync(extraContextPath)) throw `Extra context properties unavailable in path:${extraContextPath}`
|
|
@@ -99,7 +100,7 @@ export class CommonAzureStack extends TerraformStack {
|
|
|
99
100
|
protected determineStageContexts() {
|
|
100
101
|
const stage = this.node.tryGetContext('stage')
|
|
101
102
|
const stageContextPath = this.node.tryGetContext('stageContextPath') || 'cdkEnv'
|
|
102
|
-
const stageContextFilePath =
|
|
103
|
+
const stageContextFilePath = path.join(appRoot.path, stageContextPath, `${stage}.json`)
|
|
103
104
|
const debug = this.node.tryGetContext('debug')
|
|
104
105
|
|
|
105
106
|
if (isDevStage(stage)) {
|
|
@@ -7,7 +7,7 @@ import { TerraformStack } from 'cdktf'
|
|
|
7
7
|
import { Construct } from 'constructs'
|
|
8
8
|
import _ from 'lodash'
|
|
9
9
|
import { isDevStage } from '../../common'
|
|
10
|
-
import
|
|
10
|
+
import path from 'path'
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* @classdesc Common stack to use as a base for all higher level constructs.
|
|
@@ -72,7 +72,7 @@ export class CommonCloudflareStack extends TerraformStack {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
_.forEach(extraContexts, (context: string) => {
|
|
75
|
-
const extraContextPath =
|
|
75
|
+
const extraContextPath = path.join(appRoot.path, context)
|
|
76
76
|
|
|
77
77
|
/* scenario where extra context is configured in cdk.json but absent in file system */
|
|
78
78
|
if (!fs.existsSync(extraContextPath)) throw `Extra context properties unavailable in path:${extraContextPath}`
|
|
@@ -99,7 +99,7 @@ export class CommonCloudflareStack extends TerraformStack {
|
|
|
99
99
|
protected determineStageContexts() {
|
|
100
100
|
const stage = this.node.tryGetContext('stage')
|
|
101
101
|
const stageContextPath = this.node.tryGetContext('stageContextPath') || 'cdkEnv'
|
|
102
|
-
const stageContextFilePath =
|
|
102
|
+
const stageContextFilePath = path.join(appRoot.path, stageContextPath, `${stage}.json`)
|
|
103
103
|
const debug = this.node.tryGetContext('debug')
|
|
104
104
|
|
|
105
105
|
if (isDevStage(stage)) {
|