@gradientedge/cdk-utils 8.114.0 → 8.116.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.
@@ -0,0 +1,3 @@
1
+ export * from './main';
2
+ export * from './target';
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("./main"), exports);
18
+ __exportStar(require("./target"), exports);
19
+ __exportStar(require("./types"), exports);
@@ -0,0 +1,48 @@
1
+ import { Resource } from 'aws-cdk-lib/aws-apigateway';
2
+ import { ISecret } from 'aws-cdk-lib/aws-secretsmanager';
3
+ import { Construct } from 'constructs';
4
+ import { CommonConstruct } from '../../common';
5
+ import { ApiToAnyTargetProps, ApiToAnyTargetRestApiResource, ApiToAnyTargetRestApiType } from './types';
6
+ /**
7
+ * @classdesc Provides a construct to create and deploy a shallow API Gateway
8
+ * @example
9
+ * import { ApiToAnyTarget, ApiToAnyTargetProps } '@gradientedge/cdk-utils'
10
+ * import { Construct } from 'constructs'
11
+ *
12
+ * class CustomConstruct extends ApiToAnyTarget {
13
+ * constructor(parent: Construct, id: string, props: ApiToAnyTargetProps) {
14
+ * super(parent, id, props)
15
+ * this.props = props
16
+ * this.id = id
17
+ * this.initResources()
18
+ * }
19
+ * }
20
+ */
21
+ export declare class ApiToAnyTarget extends CommonConstruct {
22
+ props: ApiToAnyTargetProps;
23
+ id: string;
24
+ applicationSecrets: ISecret[];
25
+ apiToAnyTargetRestApi: ApiToAnyTargetRestApiType;
26
+ apiResource: string;
27
+ constructor(parent: Construct, id: string, props: ApiToAnyTargetProps);
28
+ protected initResources(): void;
29
+ /**
30
+ * @summary Method to resolve secrets from SecretsManager
31
+ * - To be implemented in the overriding method in the implementation class
32
+ */
33
+ protected resolveSecrets(): void;
34
+ /**
35
+ * @summary Method to resolve a hosted zone based on domain attributes
36
+ */
37
+ protected resolveHostedZone(): void;
38
+ /**
39
+ * @summary Method to resolve a certificate based on attributes
40
+ */
41
+ protected resolveCertificate(): void;
42
+ protected createApiToAnyTargetRestApiLogGroup(): void;
43
+ protected createApiToAnyTargetRestApi(): void;
44
+ protected createApiToAnyTargetResource(apiResourceProps: ApiToAnyTargetRestApiResource): Resource | undefined;
45
+ protected createApiDomain(): void;
46
+ protected createApiBasePathMapping(): void;
47
+ protected createApiRouteAssets(): void;
48
+ }
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApiToAnyTarget = void 0;
4
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
5
+ const aws_apigateway_1 = require("aws-cdk-lib/aws-apigateway");
6
+ const common_1 = require("../../common");
7
+ const target_1 = require("./target");
8
+ /**
9
+ * @classdesc Provides a construct to create and deploy a shallow API Gateway
10
+ * @example
11
+ * import { ApiToAnyTarget, ApiToAnyTargetProps } '@gradientedge/cdk-utils'
12
+ * import { Construct } from 'constructs'
13
+ *
14
+ * class CustomConstruct extends ApiToAnyTarget {
15
+ * constructor(parent: Construct, id: string, props: ApiToAnyTargetProps) {
16
+ * super(parent, id, props)
17
+ * this.props = props
18
+ * this.id = id
19
+ * this.initResources()
20
+ * }
21
+ * }
22
+ */
23
+ class ApiToAnyTarget extends common_1.CommonConstruct {
24
+ props;
25
+ id;
26
+ /* application related resources */
27
+ applicationSecrets;
28
+ /* rest restApi related resources */
29
+ apiToAnyTargetRestApi;
30
+ apiResource;
31
+ constructor(parent, id, props) {
32
+ super(parent, id, props);
33
+ this.props = props;
34
+ this.id = id;
35
+ this.apiToAnyTargetRestApi = new target_1.ApiToAnyTargetRestApi();
36
+ }
37
+ initResources() {
38
+ /* application related resources */
39
+ this.resolveSecrets();
40
+ /* core resources */
41
+ this.resolveHostedZone();
42
+ this.resolveCertificate();
43
+ /* restApi related resources */
44
+ this.createApiToAnyTargetRestApiLogGroup();
45
+ this.createApiToAnyTargetRestApi();
46
+ this.createApiDomain();
47
+ this.createApiBasePathMapping();
48
+ this.createApiRouteAssets();
49
+ }
50
+ /**
51
+ * @summary Method to resolve secrets from SecretsManager
52
+ * - To be implemented in the overriding method in the implementation class
53
+ */
54
+ resolveSecrets() {
55
+ this.applicationSecrets = [];
56
+ }
57
+ /**
58
+ * @summary Method to resolve a hosted zone based on domain attributes
59
+ */
60
+ resolveHostedZone() {
61
+ this.apiToAnyTargetRestApi.hostedZone = this.route53Manager.withHostedZoneFromFullyQualifiedDomainName(`${this.id}-hosted-zone`, this, this.props.useExistingHostedZone);
62
+ }
63
+ /**
64
+ * @summary Method to resolve a certificate based on attributes
65
+ */
66
+ resolveCertificate() {
67
+ if (this.props.api.useExisting)
68
+ return;
69
+ if (this.props.api.certificate.useExistingCertificate &&
70
+ this.props.api.certificate.certificateSsmName &&
71
+ this.props.api.certificate.certificateRegion) {
72
+ this.props.api.certificate.certificateArn = this.ssmManager.readStringParameterFromRegion(`${this.id}-certificate-param`, this, this.props.api.certificate.certificateSsmName, this.props.api.certificate.certificateRegion);
73
+ }
74
+ this.apiToAnyTargetRestApi.certificate = this.acmManager.resolveCertificate(`${this.id}-certificate`, this, this.props.api.certificate);
75
+ }
76
+ createApiToAnyTargetRestApiLogGroup() {
77
+ this.apiToAnyTargetRestApi.accessLogGroup = this.logManager.createLogGroup(`${this.id}-rest-api-access-log`, this, {
78
+ logGroupName: `/custom/api/${this.id}-rest-api-access`,
79
+ removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY,
80
+ });
81
+ }
82
+ createApiToAnyTargetRestApi() {
83
+ if (this.props.api.useExisting && this.props.api.importedRestApiRef) {
84
+ this.apiToAnyTargetRestApi.api = aws_apigateway_1.RestApi.fromRestApiId(this, `${this.id}-rest-api`, aws_cdk_lib_1.Fn.importValue(this.props.api.importedRestApiRef));
85
+ return;
86
+ }
87
+ this.apiToAnyTargetRestApi.api = new aws_apigateway_1.RestApi(this, `${this.id}-rest-api`, {
88
+ ...{
89
+ cloudWatchRole: this.props.api.restApi?.cloudWatchRole ?? true,
90
+ defaultCorsPreflightOptions: {
91
+ allowHeaders: aws_apigateway_1.Cors.DEFAULT_HEADERS,
92
+ allowMethods: aws_apigateway_1.Cors.ALL_METHODS,
93
+ allowOrigins: aws_apigateway_1.Cors.ALL_ORIGINS,
94
+ },
95
+ defaultIntegration: this.apiToAnyTargetRestApi.integration,
96
+ defaultMethodOptions: {
97
+ methodResponses: [this.apiToAnyTargetRestApi.methodResponse, this.apiToAnyTargetRestApi.methodErrorResponse],
98
+ },
99
+ deploy: this.props.api.restApi?.deploy ?? true,
100
+ deployOptions: {
101
+ accessLogDestination: new aws_apigateway_1.LogGroupLogDestination(this.apiToAnyTargetRestApi.accessLogGroup),
102
+ accessLogFormat: aws_apigateway_1.AccessLogFormat.jsonWithStandardFields(),
103
+ dataTraceEnabled: this.props.api.restApi?.deployOptions?.dataTraceEnabled,
104
+ description: `${this.id} - ${this.props.stage} stage`,
105
+ loggingLevel: aws_apigateway_1.MethodLoggingLevel.INFO,
106
+ metricsEnabled: true,
107
+ stageName: this.props.stage,
108
+ tracingEnabled: this.props.api.restApi?.deployOptions?.tracingEnabled,
109
+ },
110
+ endpointConfiguration: {
111
+ types: [this.isProductionStage() ? aws_apigateway_1.EndpointType.EDGE : aws_apigateway_1.EndpointType.REGIONAL],
112
+ },
113
+ restApiName: `${this.id}-rest-api-${this.props.stage}`,
114
+ },
115
+ ...this.props.api.restApi,
116
+ });
117
+ this.addCfnOutput(`${this.id}-restApiId`, this.apiToAnyTargetRestApi.api.restApiId);
118
+ this.addCfnOutput(`${this.id}-restApiRootResourceId`, this.apiToAnyTargetRestApi.api.root.resourceId);
119
+ }
120
+ createApiToAnyTargetResource(apiResourceProps) {
121
+ if (!this.props.api.withResource)
122
+ return;
123
+ let rootResource;
124
+ if (this.props.api.withResource && this.props.api.importedRestApiRootResourceRef) {
125
+ rootResource = aws_apigateway_1.Resource.fromResourceAttributes(this, `${this.id}-root-resource-for-${apiResourceProps.path}`, {
126
+ path: '/',
127
+ resourceId: aws_cdk_lib_1.Fn.importValue(this.props.api.importedRestApiRootResourceRef),
128
+ restApi: this.apiToAnyTargetRestApi.api,
129
+ });
130
+ }
131
+ else {
132
+ rootResource = this.apiToAnyTargetRestApi.api.root;
133
+ }
134
+ return this.apiManager.createApiResource(`${this.id}-resource-${apiResourceProps.path}}`, this, apiResourceProps.parent ?? rootResource, apiResourceProps.path, apiResourceProps.integration, apiResourceProps.addProxy, apiResourceProps.authorizer, apiResourceProps.allowedOrigins, apiResourceProps.allowedMethods, apiResourceProps.allowedHeaders, apiResourceProps.methodRequestParameters, apiResourceProps.proxyIntegration);
135
+ }
136
+ createApiDomain() {
137
+ if (this.props.api.useExisting)
138
+ return;
139
+ this.apiToAnyTargetRestApi.domain = this.apiManager.createApiDomain(`${this.id}-api-domain`, this, this.isProductionStage() || this.props.skipStageForARecords
140
+ ? `${this.props.apiSubDomain}.${this.fullyQualifiedDomainName}`
141
+ : `${this.props.apiSubDomain}-${this.props.stage}.${this.fullyQualifiedDomainName}`, this.apiToAnyTargetRestApi.certificate);
142
+ }
143
+ createApiBasePathMapping() {
144
+ if (this.props.api.useExisting)
145
+ return;
146
+ new aws_apigateway_1.BasePathMapping(this, `${this.id}-base-bath-mapping`, {
147
+ basePath: '',
148
+ domainName: this.apiToAnyTargetRestApi.domain,
149
+ restApi: this.apiToAnyTargetRestApi.api,
150
+ stage: this.apiToAnyTargetRestApi.api.deploymentStage,
151
+ });
152
+ }
153
+ createApiRouteAssets() {
154
+ if (this.props.api.useExisting)
155
+ return;
156
+ this.route53Manager.createApiGatewayARecord(`${this.id}-custom-domain-a-record`, this, this.props.apiSubDomain, this.apiToAnyTargetRestApi.domain, this.apiToAnyTargetRestApi.hostedZone, this.props.skipStageForARecords);
157
+ }
158
+ }
159
+ exports.ApiToAnyTarget = ApiToAnyTarget;
@@ -0,0 +1,23 @@
1
+ import { IRestApi, IAuthorizer, BasePathMapping, DomainName, Integration, Method, MethodResponse, Resource } from 'aws-cdk-lib/aws-apigateway';
2
+ import { ICertificate } from 'aws-cdk-lib/aws-certificatemanager';
3
+ import { LogGroup } from 'aws-cdk-lib/aws-logs';
4
+ import { IHostedZone } from 'aws-cdk-lib/aws-route53';
5
+ import { ApiToAnyTargetRestApiType } from './types';
6
+ export declare class ApiToAnyTargetRestApi implements ApiToAnyTargetRestApiType {
7
+ accessLogGroup: LogGroup;
8
+ api: IRestApi;
9
+ authoriser?: IAuthorizer;
10
+ basePathMappings: BasePathMapping[];
11
+ certificate: ICertificate;
12
+ domain: DomainName;
13
+ hostedZone: IHostedZone;
14
+ integration: Integration;
15
+ method: {
16
+ [httpMethod: string]: Method;
17
+ };
18
+ methodErrorResponse: MethodResponse;
19
+ methodResponse: MethodResponse;
20
+ resource: {
21
+ [path: string]: Resource;
22
+ };
23
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApiToAnyTargetRestApi = void 0;
4
+ class ApiToAnyTargetRestApi {
5
+ accessLogGroup;
6
+ api;
7
+ authoriser;
8
+ basePathMappings;
9
+ certificate;
10
+ domain;
11
+ hostedZone;
12
+ integration;
13
+ method;
14
+ methodErrorResponse;
15
+ methodResponse;
16
+ resource;
17
+ }
18
+ exports.ApiToAnyTargetRestApi = ApiToAnyTargetRestApi;
@@ -0,0 +1,57 @@
1
+ import { BasePathMapping, DomainName, IAuthorizer, IResource, IRestApi, Integration, Method, MethodResponse, Resource, RestApiProps } from 'aws-cdk-lib/aws-apigateway';
2
+ import { ICertificate } from 'aws-cdk-lib/aws-certificatemanager';
3
+ import { LogGroup } from 'aws-cdk-lib/aws-logs';
4
+ import { IHostedZone } from 'aws-cdk-lib/aws-route53';
5
+ import { CommonStackProps } from '../../common';
6
+ import { AcmProps } from '../../services';
7
+ export interface ApiToAnyTargetRestApiType {
8
+ accessLogGroup: LogGroup;
9
+ api: IRestApi;
10
+ authoriser?: IAuthorizer;
11
+ basePathMappings: BasePathMapping[];
12
+ certificate: ICertificate;
13
+ domain: DomainName;
14
+ hostedZone: IHostedZone;
15
+ integration: Integration;
16
+ method: {
17
+ [httpMethod: string]: Method;
18
+ };
19
+ methodErrorResponse: MethodResponse;
20
+ methodResponse: MethodResponse;
21
+ resource: {
22
+ [path: string]: Resource;
23
+ };
24
+ }
25
+ export interface ApiToAnyTargetRestApiResource {
26
+ addProxy: boolean;
27
+ authorizer?: IAuthorizer;
28
+ allowedOrigins?: string[];
29
+ allowedMethods?: string[];
30
+ allowedHeaders?: string[];
31
+ integration: Integration;
32
+ methodRequestParameters?: {
33
+ [param: string]: boolean;
34
+ };
35
+ path: string;
36
+ parent?: IResource;
37
+ proxyIntegration?: Integration;
38
+ }
39
+ export interface ApiToAnyTargetRestApiProps {
40
+ certificate: AcmProps;
41
+ importedRestApiRef?: string;
42
+ importedRestApiRootResourceRef?: string;
43
+ methodErrorResponse: MethodResponse;
44
+ methodResponse: MethodResponse;
45
+ restApi: RestApiProps;
46
+ useExisting: boolean;
47
+ withResource?: boolean;
48
+ }
49
+ export interface ApiToAnyTargetProps extends CommonStackProps {
50
+ api: ApiToAnyTargetRestApiProps;
51
+ apiRootPaths?: string[];
52
+ apiSubDomain: string;
53
+ logLevel: string;
54
+ nodeEnv: string;
55
+ timezone: string;
56
+ useExistingHostedZone: boolean;
57
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,4 @@
1
+ export * from './api-to-any-target';
1
2
  export * from './api-to-eventbridge-target';
2
3
  export * from './api-to-eventbridge-target-with-sns';
3
4
  export * from './api-to-lambda-target';
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./api-to-any-target"), exports);
17
18
  __exportStar(require("./api-to-eventbridge-target"), exports);
18
19
  __exportStar(require("./api-to-eventbridge-target-with-sns"), exports);
19
20
  __exportStar(require("./api-to-lambda-target"), exports);
@@ -1,10 +1,11 @@
1
- import { CommonConstruct } from '../../common';
2
- import { Construct } from 'constructs';
3
- import { LambdaWithIamAccessEnvironment, LambdaWithIamAccessProps } from './types';
1
+ import * as ec2 from 'aws-cdk-lib/aws-ec2';
2
+ import * as efs from 'aws-cdk-lib/aws-efs';
4
3
  import * as iam from 'aws-cdk-lib/aws-iam';
5
4
  import * as lambda from 'aws-cdk-lib/aws-lambda';
6
5
  import * as secretsManager from 'aws-cdk-lib/aws-secretsmanager';
7
- import * as ec2 from 'aws-cdk-lib/aws-ec2';
6
+ import { Construct } from 'constructs';
7
+ import { CommonConstruct } from '../../common';
8
+ import { LambdaWithIamAccessEnvironment, LambdaWithIamAccessProps } from './types';
8
9
  /**
9
10
  * @classdesc Provides a construct to create a lambda function with IAM access
10
11
  * @example
@@ -32,12 +33,20 @@ export declare class LambdaWithIamAccess extends CommonConstruct {
32
33
  lambdaUserAccessKey: iam.CfnAccessKey;
33
34
  lambdaUserAccessSecret: secretsManager.Secret;
34
35
  lambdaVpc: ec2.IVpc;
35
- lambdaSecurityGroup: ec2.ISecurityGroup;
36
+ lambdaSecurityGroups: ec2.ISecurityGroup[];
37
+ lambdaAccessPoint: efs.IAccessPoint;
38
+ lambdaMountPath: string;
39
+ lambdaVpcSubnets: ec2.SubnetSelection;
36
40
  constructor(parent: Construct, id: string, props: LambdaWithIamAccessProps);
37
41
  /**
38
42
  * @summary Initialise and provision resources
39
43
  */
40
44
  initResources(): void;
45
+ protected resolveVpc(): void;
46
+ protected resolveSecurityGroups(): void;
47
+ protected resolveAccessPoint(): void;
48
+ protected resolveMountPath(): void;
49
+ protected resolveVpcSubnets(): void;
41
50
  /**
42
51
  * @summary Method to create iam policy for Lambda function
43
52
  */
@@ -24,9 +24,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.LambdaWithIamAccess = void 0;
27
- const common_1 = require("../../common");
28
27
  const iam = __importStar(require("aws-cdk-lib/aws-iam"));
29
28
  const secretsManager = __importStar(require("aws-cdk-lib/aws-secretsmanager"));
29
+ const common_1 = require("../../common");
30
30
  /**
31
31
  * @classdesc Provides a construct to create a lambda function with IAM access
32
32
  * @example
@@ -56,7 +56,10 @@ class LambdaWithIamAccess extends common_1.CommonConstruct {
56
56
  lambdaUserAccessKey;
57
57
  lambdaUserAccessSecret;
58
58
  lambdaVpc;
59
- lambdaSecurityGroup;
59
+ lambdaSecurityGroups;
60
+ lambdaAccessPoint;
61
+ lambdaMountPath;
62
+ lambdaVpcSubnets;
60
63
  constructor(parent, id, props) {
61
64
  super(parent, id, props);
62
65
  this.props = props;
@@ -66,6 +69,11 @@ class LambdaWithIamAccess extends common_1.CommonConstruct {
66
69
  * @summary Initialise and provision resources
67
70
  */
68
71
  initResources() {
72
+ this.resolveVpc();
73
+ this.resolveSecurityGroups();
74
+ this.resolveAccessPoint();
75
+ this.resolveMountPath();
76
+ this.resolveVpcSubnets();
69
77
  this.createLambdaPolicy();
70
78
  this.createLambdaRole();
71
79
  this.createLambdaEnvironment();
@@ -74,6 +82,11 @@ class LambdaWithIamAccess extends common_1.CommonConstruct {
74
82
  this.createIamUserForLambdaFunction();
75
83
  this.createIamSecretForLambdaFunction();
76
84
  }
85
+ resolveVpc() { }
86
+ resolveSecurityGroups() { }
87
+ resolveAccessPoint() { }
88
+ resolveMountPath() { }
89
+ resolveVpcSubnets() { }
77
90
  /**
78
91
  * @summary Method to create iam policy for Lambda function
79
92
  */
@@ -114,7 +127,7 @@ class LambdaWithIamAccess extends common_1.CommonConstruct {
114
127
  * @summary Method to create lambda function
115
128
  */
116
129
  createLambdaFunction() {
117
- this.lambdaFunction = this.lambdaManager.createLambdaFunction(`${this.id}-lambda`, this, this.props.lambda, this.lambdaRole, this.lambdaLayers, this.props.lambdaSource, this.props.lambdaHandler || 'index.handler', this.lambdaEnvironment, this.lambdaVpc, [this.lambdaSecurityGroup], undefined, undefined, this.lambdaVpc);
130
+ this.lambdaFunction = this.lambdaManager.createLambdaFunction(`${this.id}-lambda`, this, this.props.lambda, this.lambdaRole, this.lambdaLayers, this.props.lambdaSource, this.props.lambdaHandler || 'index.handler', this.lambdaEnvironment, this.lambdaVpc, this.lambdaSecurityGroups, this.lambdaAccessPoint, this.lambdaMountPath, this.lambdaVpcSubnets);
118
131
  }
119
132
  /**
120
133
  * @summary Method to create iam user for the lambda function
@@ -52,7 +52,9 @@ export declare class ApiManager {
52
52
  * @param methodRequestParameters
53
53
  * @param proxyIntegration
54
54
  */
55
- createApiResource(id: string, scope: CommonConstruct, parent: apig.IResource, path: string, integration: apig.Integration, addProxy: boolean, authorizer?: apig.IAuthorizer, allowedOrigins?: string[], allowedMethods?: string[], allowedHeaders?: string[], methodRequestParameters?: any, proxyIntegration?: apig.Integration): apig.Resource;
55
+ createApiResource(id: string, scope: CommonConstruct, parent: apig.IResource, path: string, integration: apig.Integration, addProxy: boolean, authorizer?: apig.IAuthorizer, allowedOrigins?: string[], allowedMethods?: string[], allowedHeaders?: string[], methodRequestParameters?: {
56
+ [param: string]: boolean;
57
+ }, proxyIntegration?: apig.Integration): apig.Resource;
56
58
  /**
57
59
  * @summary Method to create an api deployment
58
60
  * @param id
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradientedge/cdk-utils",
3
- "version": "8.114.0",
3
+ "version": "8.116.0",
4
4
  "description": "Utilities for AWS CDK provisioning",
5
5
  "main": "dist/index.js",
6
6
  "engines": {
@@ -0,0 +1,3 @@
1
+ export * from './main'
2
+ export * from './target'
3
+ export * from './types'
@@ -0,0 +1,225 @@
1
+ import { Fn, RemovalPolicy } from 'aws-cdk-lib'
2
+ import {
3
+ AccessLogFormat,
4
+ BasePathMapping,
5
+ Cors,
6
+ EndpointType,
7
+ LogGroupLogDestination,
8
+ MethodLoggingLevel,
9
+ Resource,
10
+ RestApi,
11
+ } from 'aws-cdk-lib/aws-apigateway'
12
+ import { ISecret } from 'aws-cdk-lib/aws-secretsmanager'
13
+ import { Construct } from 'constructs'
14
+ import { CommonConstruct } from '../../common'
15
+ import { ApiToAnyTargetProps, ApiToAnyTargetRestApiResource, ApiToAnyTargetRestApiType } from './types'
16
+ import { ApiToAnyTargetRestApi } from './target'
17
+
18
+ /**
19
+ * @classdesc Provides a construct to create and deploy a shallow API Gateway
20
+ * @example
21
+ * import { ApiToAnyTarget, ApiToAnyTargetProps } '@gradientedge/cdk-utils'
22
+ * import { Construct } from 'constructs'
23
+ *
24
+ * class CustomConstruct extends ApiToAnyTarget {
25
+ * constructor(parent: Construct, id: string, props: ApiToAnyTargetProps) {
26
+ * super(parent, id, props)
27
+ * this.props = props
28
+ * this.id = id
29
+ * this.initResources()
30
+ * }
31
+ * }
32
+ */
33
+ export class ApiToAnyTarget extends CommonConstruct {
34
+ props: ApiToAnyTargetProps
35
+ id: string
36
+
37
+ /* application related resources */
38
+ applicationSecrets: ISecret[]
39
+
40
+ /* rest restApi related resources */
41
+ apiToAnyTargetRestApi: ApiToAnyTargetRestApiType
42
+ apiResource: string
43
+
44
+ constructor(parent: Construct, id: string, props: ApiToAnyTargetProps) {
45
+ super(parent, id, props)
46
+ this.props = props
47
+ this.id = id
48
+
49
+ this.apiToAnyTargetRestApi = new ApiToAnyTargetRestApi()
50
+ }
51
+
52
+ protected initResources() {
53
+ /* application related resources */
54
+ this.resolveSecrets()
55
+
56
+ /* core resources */
57
+ this.resolveHostedZone()
58
+ this.resolveCertificate()
59
+
60
+ /* restApi related resources */
61
+ this.createApiToAnyTargetRestApiLogGroup()
62
+ this.createApiToAnyTargetRestApi()
63
+ this.createApiDomain()
64
+ this.createApiBasePathMapping()
65
+ this.createApiRouteAssets()
66
+ }
67
+
68
+ /**
69
+ * @summary Method to resolve secrets from SecretsManager
70
+ * - To be implemented in the overriding method in the implementation class
71
+ */
72
+ protected resolveSecrets() {
73
+ this.applicationSecrets = []
74
+ }
75
+
76
+ /**
77
+ * @summary Method to resolve a hosted zone based on domain attributes
78
+ */
79
+ protected resolveHostedZone() {
80
+ this.apiToAnyTargetRestApi.hostedZone = this.route53Manager.withHostedZoneFromFullyQualifiedDomainName(
81
+ `${this.id}-hosted-zone`,
82
+ this,
83
+ this.props.useExistingHostedZone
84
+ )
85
+ }
86
+
87
+ /**
88
+ * @summary Method to resolve a certificate based on attributes
89
+ */
90
+ protected resolveCertificate() {
91
+ if (this.props.api.useExisting) return
92
+ if (
93
+ this.props.api.certificate.useExistingCertificate &&
94
+ this.props.api.certificate.certificateSsmName &&
95
+ this.props.api.certificate.certificateRegion
96
+ ) {
97
+ this.props.api.certificate.certificateArn = this.ssmManager.readStringParameterFromRegion(
98
+ `${this.id}-certificate-param`,
99
+ this,
100
+ this.props.api.certificate.certificateSsmName,
101
+ this.props.api.certificate.certificateRegion
102
+ )
103
+ }
104
+
105
+ this.apiToAnyTargetRestApi.certificate = this.acmManager.resolveCertificate(
106
+ `${this.id}-certificate`,
107
+ this,
108
+ this.props.api.certificate
109
+ )
110
+ }
111
+
112
+ protected createApiToAnyTargetRestApiLogGroup() {
113
+ this.apiToAnyTargetRestApi.accessLogGroup = this.logManager.createLogGroup(`${this.id}-rest-api-access-log`, this, {
114
+ logGroupName: `/custom/api/${this.id}-rest-api-access`,
115
+ removalPolicy: RemovalPolicy.DESTROY,
116
+ })
117
+ }
118
+
119
+ protected createApiToAnyTargetRestApi() {
120
+ if (this.props.api.useExisting && this.props.api.importedRestApiRef) {
121
+ this.apiToAnyTargetRestApi.api = RestApi.fromRestApiId(
122
+ this,
123
+ `${this.id}-rest-api`,
124
+ Fn.importValue(this.props.api.importedRestApiRef)
125
+ )
126
+ return
127
+ }
128
+
129
+ this.apiToAnyTargetRestApi.api = new RestApi(this, `${this.id}-rest-api`, {
130
+ ...{
131
+ cloudWatchRole: this.props.api.restApi?.cloudWatchRole ?? true,
132
+ defaultCorsPreflightOptions: {
133
+ allowHeaders: Cors.DEFAULT_HEADERS,
134
+ allowMethods: Cors.ALL_METHODS,
135
+ allowOrigins: Cors.ALL_ORIGINS,
136
+ },
137
+ defaultIntegration: this.apiToAnyTargetRestApi.integration,
138
+ defaultMethodOptions: {
139
+ methodResponses: [this.apiToAnyTargetRestApi.methodResponse, this.apiToAnyTargetRestApi.methodErrorResponse],
140
+ },
141
+ deploy: this.props.api.restApi?.deploy ?? true,
142
+ deployOptions: {
143
+ accessLogDestination: new LogGroupLogDestination(this.apiToAnyTargetRestApi.accessLogGroup),
144
+ accessLogFormat: AccessLogFormat.jsonWithStandardFields(),
145
+ dataTraceEnabled: this.props.api.restApi?.deployOptions?.dataTraceEnabled,
146
+ description: `${this.id} - ${this.props.stage} stage`,
147
+ loggingLevel: MethodLoggingLevel.INFO,
148
+ metricsEnabled: true,
149
+ stageName: this.props.stage,
150
+ tracingEnabled: this.props.api.restApi?.deployOptions?.tracingEnabled,
151
+ },
152
+ endpointConfiguration: {
153
+ types: [this.isProductionStage() ? EndpointType.EDGE : EndpointType.REGIONAL],
154
+ },
155
+ restApiName: `${this.id}-rest-api-${this.props.stage}`,
156
+ },
157
+ ...this.props.api.restApi,
158
+ })
159
+ this.addCfnOutput(`${this.id}-restApiId`, this.apiToAnyTargetRestApi.api.restApiId)
160
+ this.addCfnOutput(`${this.id}-restApiRootResourceId`, this.apiToAnyTargetRestApi.api.root.resourceId)
161
+ }
162
+
163
+ protected createApiToAnyTargetResource(apiResourceProps: ApiToAnyTargetRestApiResource) {
164
+ if (!this.props.api.withResource) return
165
+ let rootResource
166
+ if (this.props.api.withResource && this.props.api.importedRestApiRootResourceRef) {
167
+ rootResource = Resource.fromResourceAttributes(this, `${this.id}-root-resource-for-${apiResourceProps.path}`, {
168
+ path: '/',
169
+ resourceId: Fn.importValue(this.props.api.importedRestApiRootResourceRef),
170
+ restApi: this.apiToAnyTargetRestApi.api,
171
+ })
172
+ } else {
173
+ rootResource = this.apiToAnyTargetRestApi.api.root
174
+ }
175
+
176
+ return this.apiManager.createApiResource(
177
+ `${this.id}-resource-${apiResourceProps.path}}`,
178
+ this,
179
+ apiResourceProps.parent ?? rootResource,
180
+ apiResourceProps.path,
181
+ apiResourceProps.integration,
182
+ apiResourceProps.addProxy,
183
+ apiResourceProps.authorizer,
184
+ apiResourceProps.allowedOrigins,
185
+ apiResourceProps.allowedMethods,
186
+ apiResourceProps.allowedHeaders,
187
+ apiResourceProps.methodRequestParameters,
188
+ apiResourceProps.proxyIntegration
189
+ )
190
+ }
191
+
192
+ protected createApiDomain() {
193
+ if (this.props.api.useExisting) return
194
+ this.apiToAnyTargetRestApi.domain = this.apiManager.createApiDomain(
195
+ `${this.id}-api-domain`,
196
+ this,
197
+ this.isProductionStage() || this.props.skipStageForARecords
198
+ ? `${this.props.apiSubDomain}.${this.fullyQualifiedDomainName}`
199
+ : `${this.props.apiSubDomain}-${this.props.stage}.${this.fullyQualifiedDomainName}`,
200
+ this.apiToAnyTargetRestApi.certificate
201
+ )
202
+ }
203
+
204
+ protected createApiBasePathMapping() {
205
+ if (this.props.api.useExisting) return
206
+ new BasePathMapping(this, `${this.id}-base-bath-mapping`, {
207
+ basePath: '',
208
+ domainName: this.apiToAnyTargetRestApi.domain,
209
+ restApi: this.apiToAnyTargetRestApi.api,
210
+ stage: this.apiToAnyTargetRestApi.api.deploymentStage,
211
+ })
212
+ }
213
+
214
+ protected createApiRouteAssets() {
215
+ if (this.props.api.useExisting) return
216
+ this.route53Manager.createApiGatewayARecord(
217
+ `${this.id}-custom-domain-a-record`,
218
+ this,
219
+ this.props.apiSubDomain,
220
+ this.apiToAnyTargetRestApi.domain,
221
+ this.apiToAnyTargetRestApi.hostedZone,
222
+ this.props.skipStageForARecords
223
+ )
224
+ }
225
+ }
@@ -0,0 +1,29 @@
1
+ import {
2
+ IRestApi,
3
+ IAuthorizer,
4
+ BasePathMapping,
5
+ DomainName,
6
+ Integration,
7
+ Method,
8
+ MethodResponse,
9
+ Resource,
10
+ } from 'aws-cdk-lib/aws-apigateway'
11
+ import { ICertificate } from 'aws-cdk-lib/aws-certificatemanager'
12
+ import { LogGroup } from 'aws-cdk-lib/aws-logs'
13
+ import { IHostedZone } from 'aws-cdk-lib/aws-route53'
14
+ import { ApiToAnyTargetRestApiType } from './types'
15
+
16
+ export class ApiToAnyTargetRestApi implements ApiToAnyTargetRestApiType {
17
+ accessLogGroup: LogGroup
18
+ api: IRestApi
19
+ authoriser?: IAuthorizer
20
+ basePathMappings: BasePathMapping[]
21
+ certificate: ICertificate
22
+ domain: DomainName
23
+ hostedZone: IHostedZone
24
+ integration: Integration
25
+ method: { [httpMethod: string]: Method }
26
+ methodErrorResponse: MethodResponse
27
+ methodResponse: MethodResponse
28
+ resource: { [path: string]: Resource }
29
+ }
@@ -0,0 +1,66 @@
1
+ import {
2
+ BasePathMapping,
3
+ DomainName,
4
+ IAuthorizer,
5
+ IResource,
6
+ IRestApi,
7
+ Integration,
8
+ Method,
9
+ MethodResponse,
10
+ Resource,
11
+ RestApiProps,
12
+ } from 'aws-cdk-lib/aws-apigateway'
13
+ import { ICertificate } from 'aws-cdk-lib/aws-certificatemanager'
14
+ import { LogGroup } from 'aws-cdk-lib/aws-logs'
15
+ import { IHostedZone } from 'aws-cdk-lib/aws-route53'
16
+ import { CommonStackProps } from '../../common'
17
+ import { AcmProps } from '../../services'
18
+
19
+ export interface ApiToAnyTargetRestApiType {
20
+ accessLogGroup: LogGroup
21
+ api: IRestApi
22
+ authoriser?: IAuthorizer
23
+ basePathMappings: BasePathMapping[]
24
+ certificate: ICertificate
25
+ domain: DomainName
26
+ hostedZone: IHostedZone
27
+ integration: Integration
28
+ method: { [httpMethod: string]: Method }
29
+ methodErrorResponse: MethodResponse
30
+ methodResponse: MethodResponse
31
+ resource: { [path: string]: Resource }
32
+ }
33
+
34
+ export interface ApiToAnyTargetRestApiResource {
35
+ addProxy: boolean
36
+ authorizer?: IAuthorizer
37
+ allowedOrigins?: string[]
38
+ allowedMethods?: string[]
39
+ allowedHeaders?: string[]
40
+ integration: Integration
41
+ methodRequestParameters?: { [param: string]: boolean }
42
+ path: string
43
+ parent?: IResource
44
+ proxyIntegration?: Integration
45
+ }
46
+
47
+ export interface ApiToAnyTargetRestApiProps {
48
+ certificate: AcmProps
49
+ importedRestApiRef?: string
50
+ importedRestApiRootResourceRef?: string
51
+ methodErrorResponse: MethodResponse
52
+ methodResponse: MethodResponse
53
+ restApi: RestApiProps
54
+ useExisting: boolean
55
+ withResource?: boolean
56
+ }
57
+
58
+ export interface ApiToAnyTargetProps extends CommonStackProps {
59
+ api: ApiToAnyTargetRestApiProps
60
+ apiRootPaths?: string[]
61
+ apiSubDomain: string
62
+ logLevel: string
63
+ nodeEnv: string
64
+ timezone: string
65
+ useExistingHostedZone: boolean
66
+ }
@@ -1,3 +1,4 @@
1
+ export * from './api-to-any-target'
1
2
  export * from './api-to-eventbridge-target'
2
3
  export * from './api-to-eventbridge-target-with-sns'
3
4
  export * from './api-to-lambda-target'
@@ -1,10 +1,11 @@
1
- import { CommonConstruct } from '../../common'
2
- import { Construct } from 'constructs'
3
- import { LambdaWithIamAccessEnvironment, LambdaWithIamAccessProps } from './types'
1
+ import * as ec2 from 'aws-cdk-lib/aws-ec2'
2
+ import * as efs from 'aws-cdk-lib/aws-efs'
4
3
  import * as iam from 'aws-cdk-lib/aws-iam'
5
4
  import * as lambda from 'aws-cdk-lib/aws-lambda'
6
5
  import * as secretsManager from 'aws-cdk-lib/aws-secretsmanager'
7
- import * as ec2 from 'aws-cdk-lib/aws-ec2'
6
+ import { Construct } from 'constructs'
7
+ import { CommonConstruct } from '../../common'
8
+ import { LambdaWithIamAccessEnvironment, LambdaWithIamAccessProps } from './types'
8
9
 
9
10
  /**
10
11
  * @classdesc Provides a construct to create a lambda function with IAM access
@@ -36,7 +37,10 @@ export class LambdaWithIamAccess extends CommonConstruct {
36
37
  lambdaUserAccessKey: iam.CfnAccessKey
37
38
  lambdaUserAccessSecret: secretsManager.Secret
38
39
  lambdaVpc: ec2.IVpc
39
- lambdaSecurityGroup: ec2.ISecurityGroup
40
+ lambdaSecurityGroups: ec2.ISecurityGroup[]
41
+ lambdaAccessPoint: efs.IAccessPoint
42
+ lambdaMountPath: string
43
+ lambdaVpcSubnets: ec2.SubnetSelection
40
44
 
41
45
  constructor(parent: Construct, id: string, props: LambdaWithIamAccessProps) {
42
46
  super(parent, id, props)
@@ -49,6 +53,11 @@ export class LambdaWithIamAccess extends CommonConstruct {
49
53
  * @summary Initialise and provision resources
50
54
  */
51
55
  public initResources() {
56
+ this.resolveVpc()
57
+ this.resolveSecurityGroups()
58
+ this.resolveAccessPoint()
59
+ this.resolveMountPath()
60
+ this.resolveVpcSubnets()
52
61
  this.createLambdaPolicy()
53
62
  this.createLambdaRole()
54
63
  this.createLambdaEnvironment()
@@ -58,6 +67,16 @@ export class LambdaWithIamAccess extends CommonConstruct {
58
67
  this.createIamSecretForLambdaFunction()
59
68
  }
60
69
 
70
+ protected resolveVpc() {}
71
+
72
+ protected resolveSecurityGroups() {}
73
+
74
+ protected resolveAccessPoint() {}
75
+
76
+ protected resolveMountPath() {}
77
+
78
+ protected resolveVpcSubnets() {}
79
+
61
80
  /**
62
81
  * @summary Method to create iam policy for Lambda function
63
82
  */
@@ -114,10 +133,10 @@ export class LambdaWithIamAccess extends CommonConstruct {
114
133
  this.props.lambdaHandler || 'index.handler',
115
134
  this.lambdaEnvironment,
116
135
  this.lambdaVpc,
117
- [this.lambdaSecurityGroup],
118
- undefined,
119
- undefined,
120
- this.lambdaVpc
136
+ this.lambdaSecurityGroups,
137
+ this.lambdaAccessPoint,
138
+ this.lambdaMountPath,
139
+ this.lambdaVpcSubnets
121
140
  )
122
141
  }
123
142
 
@@ -135,7 +135,7 @@ export class ApiManager {
135
135
  allowedOrigins?: string[],
136
136
  allowedMethods?: string[],
137
137
  allowedHeaders?: string[],
138
- methodRequestParameters?: any,
138
+ methodRequestParameters?: { [param: string]: boolean },
139
139
  proxyIntegration?: apig.Integration
140
140
  ) {
141
141
  const methods = allowedMethods ?? apig.Cors.ALL_METHODS