@jaypie/constructs 1.1.39 → 1.1.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/JaypieWebDeploymentBucket.d.ts +1 -0
- package/dist/cjs/helpers/__tests__/envHostname.spec.d.ts +1 -0
- package/dist/cjs/helpers/__tests__/jaypieLambdaEnv.spec.d.ts +1 -0
- package/dist/cjs/helpers/addDatadogLayer.d.ts +5 -0
- package/dist/cjs/helpers/addParamsAndSecrets.d.ts +11 -0
- package/dist/cjs/helpers/constructTagger.d.ts +4 -0
- package/dist/cjs/helpers/envHostname.d.ts +6 -0
- package/dist/cjs/helpers/index.d.ts +6 -1
- package/dist/cjs/helpers/jaypieLambdaEnv.d.ts +8 -0
- package/dist/cjs/helpers/resolveHostedZone.d.ts +6 -0
- package/dist/cjs/index.cjs +326 -239
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/JaypieWebDeploymentBucket.d.ts +1 -0
- package/dist/esm/helpers/__tests__/envHostname.spec.d.ts +1 -0
- package/dist/esm/helpers/__tests__/jaypieLambdaEnv.spec.d.ts +1 -0
- package/dist/esm/helpers/addDatadogLayer.d.ts +5 -0
- package/dist/esm/helpers/addParamsAndSecrets.d.ts +11 -0
- package/dist/esm/helpers/constructTagger.d.ts +4 -0
- package/dist/esm/helpers/envHostname.d.ts +6 -0
- package/dist/esm/helpers/index.d.ts +6 -1
- package/dist/esm/helpers/jaypieLambdaEnv.d.ts +8 -0
- package/dist/esm/helpers/resolveHostedZone.d.ts +6 -0
- package/dist/esm/index.js +229 -147
- package/dist/esm/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/cjs/helpers/stackTagger.d.ts +0 -4
- package/dist/esm/helpers/stackTagger.d.ts +0 -4
|
@@ -62,6 +62,7 @@ export declare class JaypieWebDeploymentBucket extends Construct implements s3.I
|
|
|
62
62
|
grantRead(identity: any, objectsKeyPattern?: any): any;
|
|
63
63
|
grantReadWrite(identity: any, objectsKeyPattern?: any): any;
|
|
64
64
|
grantWrite(identity: any, objectsKeyPattern?: any): any;
|
|
65
|
+
grantReplicationPermission(identity: any, props: any): any;
|
|
65
66
|
s3UrlForObject(key?: string): string;
|
|
66
67
|
urlForObject(key?: string): string;
|
|
67
68
|
virtualHostedUrlForObject(key?: string, options?: s3.VirtualHostedStyleUrlOptions): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
2
|
+
export interface AddParamsAndSecretsOptions {
|
|
3
|
+
paramsAndSecrets?: lambda.ParamsAndSecretsLayerVersion | boolean;
|
|
4
|
+
paramsAndSecretsOptions?: {
|
|
5
|
+
cacheSize?: number;
|
|
6
|
+
logLevel?: lambda.ParamsAndSecretsLogLevel;
|
|
7
|
+
parameterStoreTtl?: number;
|
|
8
|
+
secretsManagerTtl?: number;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export declare function addParamsAndSecrets(lambdaFunction: lambda.Function, options?: AddParamsAndSecretsOptions): boolean;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
export { addDatadogLayer } from "./addDatadogLayer";
|
|
2
|
+
export { addParamsAndSecrets } from "./addParamsAndSecrets";
|
|
1
3
|
export { constructEnvName } from "./constructEnvName";
|
|
2
4
|
export { constructStackName } from "./constructStackName";
|
|
5
|
+
export { constructTagger } from "./constructTagger";
|
|
6
|
+
export { envHostname } from "./envHostname";
|
|
3
7
|
export { isEnv, isProductionEnv, isSandboxEnv } from "./isEnv";
|
|
4
|
-
export {
|
|
8
|
+
export { jaypieLambdaEnv } from "./jaypieLambdaEnv";
|
|
9
|
+
export { resolveHostedZone } from "./resolveHostedZone";
|
package/dist/esm/index.js
CHANGED
|
@@ -1,28 +1,121 @@
|
|
|
1
1
|
import { Construct } from 'constructs';
|
|
2
2
|
import * as cdk from 'aws-cdk-lib';
|
|
3
|
-
import {
|
|
3
|
+
import { Stack, Tags, Duration, RemovalPolicy, Fn, CfnOutput, SecretValue } from 'aws-cdk-lib';
|
|
4
4
|
import * as acm from 'aws-cdk-lib/aws-certificatemanager';
|
|
5
5
|
import * as apiGateway from 'aws-cdk-lib/aws-apigateway';
|
|
6
6
|
import * as route53 from 'aws-cdk-lib/aws-route53';
|
|
7
7
|
import { HostedZone } from 'aws-cdk-lib/aws-route53';
|
|
8
8
|
import * as route53Targets from 'aws-cdk-lib/aws-route53-targets';
|
|
9
|
-
import { CDK as CDK$2, mergeDomain, isValidSubdomain,
|
|
9
|
+
import { CDK as CDK$2, ConfigurationError, mergeDomain, isValidSubdomain, isValidHostname } from '@jaypie/cdk';
|
|
10
|
+
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
11
|
+
import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
|
|
10
12
|
import * as s3 from 'aws-cdk-lib/aws-s3';
|
|
11
13
|
import * as s3n from 'aws-cdk-lib/aws-s3-notifications';
|
|
12
|
-
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
13
14
|
import * as sqs from 'aws-cdk-lib/aws-sqs';
|
|
14
15
|
import * as lambdaEventSources from 'aws-cdk-lib/aws-lambda-event-sources';
|
|
15
|
-
import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
|
|
16
16
|
import { ServicePrincipal, Role, FederatedPrincipal, PolicyStatement, Effect } from 'aws-cdk-lib/aws-iam';
|
|
17
17
|
import { LogGroup, RetentionDays, FilterPattern } from 'aws-cdk-lib/aws-logs';
|
|
18
18
|
import * as sso from 'aws-cdk-lib/aws-sso';
|
|
19
19
|
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
|
|
20
20
|
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
|
|
21
21
|
|
|
22
|
+
function addDatadogLayer(lambdaFunction, options = {}) {
|
|
23
|
+
const { datadogApiKeyArn } = options;
|
|
24
|
+
// Resolve the Datadog API key ARN from multiple sources
|
|
25
|
+
const resolvedDatadogApiKeyArn = datadogApiKeyArn ||
|
|
26
|
+
process.env.DATADOG_API_KEY_ARN ||
|
|
27
|
+
process.env.CDK_ENV_DATADOG_API_KEY_ARN;
|
|
28
|
+
// Return false if no API key is found
|
|
29
|
+
if (!resolvedDatadogApiKeyArn) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
const stack = Stack.of(lambdaFunction);
|
|
33
|
+
// Create Datadog Node.js layer
|
|
34
|
+
const datadogNodeLayer = lambda.LayerVersion.fromLayerVersionArn(stack, `DatadogNodeLayer-${lambdaFunction.node.id}`, `arn:aws:lambda:${stack.region}:464622532012:layer:Datadog-Node20-x:${CDK$2.DATADOG.LAYER.NODE}`);
|
|
35
|
+
// Create Datadog Extension layer
|
|
36
|
+
const datadogExtensionLayer = lambda.LayerVersion.fromLayerVersionArn(stack, `DatadogExtensionLayer-${lambdaFunction.node.id}`, `arn:aws:lambda:${stack.region}:464622532012:layer:Datadog-Extension:${CDK$2.DATADOG.LAYER.EXTENSION}`);
|
|
37
|
+
// Add layers to the lambda function
|
|
38
|
+
lambdaFunction.addLayers(datadogNodeLayer, datadogExtensionLayer);
|
|
39
|
+
// Define Datadog environment variables
|
|
40
|
+
const datadogEnvVars = {
|
|
41
|
+
DD_API_KEY_SECRET_ARN: resolvedDatadogApiKeyArn,
|
|
42
|
+
DD_ENHANCED_METRICS: "true",
|
|
43
|
+
DD_ENV: process.env.PROJECT_ENV || "",
|
|
44
|
+
DD_PROFILING_ENABLED: "false",
|
|
45
|
+
DD_SERVERLESS_APPSEC_ENABLED: "false",
|
|
46
|
+
DD_SERVICE: process.env.PROJECT_SERVICE || "",
|
|
47
|
+
DD_SITE: CDK$2.DATADOG.SITE,
|
|
48
|
+
DD_TAGS: `${CDK$2.TAG.SPONSOR}:${process.env.PROJECT_SPONSOR || ""}`,
|
|
49
|
+
DD_TRACE_OTEL_ENABLED: "false",
|
|
50
|
+
};
|
|
51
|
+
// Add environment variables only if they don't already exist
|
|
52
|
+
Object.entries(datadogEnvVars).forEach(([key, value]) => {
|
|
53
|
+
if (lambdaFunction.environment[key] === undefined) {
|
|
54
|
+
lambdaFunction.addEnvironment(key, value);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
// Grant Datadog API key read permission
|
|
58
|
+
const datadogApiKey = secretsmanager.Secret.fromSecretCompleteArn(stack, `DatadogApiKeyGrant-${lambdaFunction.node.id}`, resolvedDatadogApiKeyArn);
|
|
59
|
+
datadogApiKey.grantRead(lambdaFunction);
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function addParamsAndSecrets(lambdaFunction, options = {}) {
|
|
64
|
+
const { paramsAndSecrets, paramsAndSecretsOptions } = options;
|
|
65
|
+
// Return false if explicitly disabled
|
|
66
|
+
if (paramsAndSecrets === false) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
const stack = Stack.of(lambdaFunction);
|
|
70
|
+
let resolvedLayer = undefined;
|
|
71
|
+
if (paramsAndSecrets instanceof lambda.ParamsAndSecretsLayerVersion) {
|
|
72
|
+
// For custom ParamsAndSecretsLayerVersion, we need to extract the ARN
|
|
73
|
+
// This is a workaround since ParamsAndSecretsLayerVersion doesn't implement ILayerVersion
|
|
74
|
+
const layerArn = `arn:aws:lambda:${stack.region}:017000801446:layer:AWSLambdaParametersAndSecrets:${lambda.ParamsAndSecretsVersions.V1_0_103}`;
|
|
75
|
+
resolvedLayer = lambda.LayerVersion.fromLayerVersionArn(stack, `ParamsAndSecretsLayer-${lambdaFunction.node.id}`, layerArn);
|
|
76
|
+
// Set environment variables for configuration
|
|
77
|
+
if (paramsAndSecretsOptions?.cacheSize) {
|
|
78
|
+
lambdaFunction.addEnvironment("PARAMETERS_SECRETS_EXTENSION_CACHE_SIZE", paramsAndSecretsOptions.cacheSize.toString());
|
|
79
|
+
}
|
|
80
|
+
if (paramsAndSecretsOptions?.logLevel) {
|
|
81
|
+
lambdaFunction.addEnvironment("PARAMETERS_SECRETS_EXTENSION_LOG_LEVEL", paramsAndSecretsOptions.logLevel);
|
|
82
|
+
}
|
|
83
|
+
if (paramsAndSecretsOptions?.parameterStoreTtl) {
|
|
84
|
+
lambdaFunction.addEnvironment("PARAMETERS_SECRETS_EXTENSION_PARAMETER_STORE_TTL", paramsAndSecretsOptions.parameterStoreTtl.toString());
|
|
85
|
+
}
|
|
86
|
+
if (paramsAndSecretsOptions?.secretsManagerTtl) {
|
|
87
|
+
lambdaFunction.addEnvironment("PARAMETERS_SECRETS_EXTENSION_SECRETS_MANAGER_TTL", paramsAndSecretsOptions.secretsManagerTtl.toString());
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// Create default ParamsAndSecrets layer using LayerVersion.fromLayerVersionArn
|
|
92
|
+
const layerArn = `arn:aws:lambda:${stack.region}:017000801446:layer:AWSLambdaParametersAndSecrets:${lambda.ParamsAndSecretsVersions.V1_0_103}`;
|
|
93
|
+
resolvedLayer = lambda.LayerVersion.fromLayerVersionArn(stack, `ParamsAndSecretsLayer-${lambdaFunction.node.id}`, layerArn);
|
|
94
|
+
// Set default environment variables
|
|
95
|
+
if (paramsAndSecretsOptions?.cacheSize) {
|
|
96
|
+
lambdaFunction.addEnvironment("PARAMETERS_SECRETS_EXTENSION_CACHE_SIZE", paramsAndSecretsOptions.cacheSize.toString());
|
|
97
|
+
}
|
|
98
|
+
const logLevel = paramsAndSecretsOptions?.logLevel || lambda.ParamsAndSecretsLogLevel.WARN;
|
|
99
|
+
lambdaFunction.addEnvironment("PARAMETERS_SECRETS_EXTENSION_LOG_LEVEL", logLevel);
|
|
100
|
+
if (paramsAndSecretsOptions?.parameterStoreTtl) {
|
|
101
|
+
lambdaFunction.addEnvironment("PARAMETERS_SECRETS_EXTENSION_PARAMETER_STORE_TTL", paramsAndSecretsOptions.parameterStoreTtl.toString());
|
|
102
|
+
}
|
|
103
|
+
if (paramsAndSecretsOptions?.secretsManagerTtl) {
|
|
104
|
+
lambdaFunction.addEnvironment("PARAMETERS_SECRETS_EXTENSION_SECRETS_MANAGER_TTL", paramsAndSecretsOptions.secretsManagerTtl.toString());
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Add the layer to the lambda function
|
|
108
|
+
if (resolvedLayer) {
|
|
109
|
+
lambdaFunction.addLayers(resolvedLayer);
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
|
|
22
115
|
function constructEnvName(name, opts) {
|
|
23
116
|
const env = opts?.env ?? process.env.PROJECT_ENV ?? "build";
|
|
24
117
|
const key = opts?.key ?? process.env.PROJECT_KEY ?? "project";
|
|
25
|
-
const nonce = opts?.nonce ?? process.env.PROJECT_NONCE ?? "cfe2";
|
|
118
|
+
const nonce = opts?.nonce ?? process.env.PROJECT_NONCE ?? "cfe2"; // This default is intentionally short. It is not a special value but should not be changed.
|
|
26
119
|
return `${env}-${key}-${name}-${nonce}`;
|
|
27
120
|
}
|
|
28
121
|
|
|
@@ -35,25 +128,6 @@ function constructStackName(key) {
|
|
|
35
128
|
}
|
|
36
129
|
}
|
|
37
130
|
|
|
38
|
-
/**
|
|
39
|
-
* Check if the current environment matches the given environment
|
|
40
|
-
*/
|
|
41
|
-
function isEnv(env) {
|
|
42
|
-
return process.env.PROJECT_ENV === env;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Check if the current environment is production
|
|
46
|
-
*/
|
|
47
|
-
function isProductionEnv() {
|
|
48
|
-
return isEnv(CDK$2.ENV.PRODUCTION);
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Check if the current environment is sandbox
|
|
52
|
-
*/
|
|
53
|
-
function isSandboxEnv() {
|
|
54
|
-
return isEnv(CDK$2.ENV.SANDBOX);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
131
|
const CDK$1 = {
|
|
58
132
|
CREATION: {
|
|
59
133
|
CDK: "cdk",
|
|
@@ -77,35 +151,137 @@ const CDK$1 = {
|
|
|
77
151
|
VERSION: "version",
|
|
78
152
|
},
|
|
79
153
|
};
|
|
80
|
-
function
|
|
154
|
+
function constructTagger(construct, { name } = {}) {
|
|
81
155
|
const stackName = name || constructStackName();
|
|
82
156
|
const version = process.env.npm_package_version || process.env.PROJECT_VERSION || null;
|
|
83
157
|
if (process.env.PROJECT_COMMIT && process.env.PROJECT_COMMIT.length > 8) {
|
|
84
|
-
Tags.of(
|
|
158
|
+
Tags.of(construct).add(CDK$1.TAG.BUILD_HEX, process.env.PROJECT_COMMIT.slice(0, 8));
|
|
85
159
|
}
|
|
86
|
-
Tags.of(
|
|
87
|
-
Tags.of(
|
|
160
|
+
Tags.of(construct).add(CDK$1.TAG.BUILD_DATE, new Date().toISOString());
|
|
161
|
+
Tags.of(construct).add(CDK$1.TAG.BUILD_TIME, Date.now().toString());
|
|
88
162
|
if (process.env.PROJECT_COMMIT)
|
|
89
|
-
Tags.of(
|
|
90
|
-
Tags.of(
|
|
163
|
+
Tags.of(construct).add(CDK$1.TAG.COMMIT, process.env.PROJECT_COMMIT);
|
|
164
|
+
Tags.of(construct).add(CDK$1.TAG.CREATION, CDK$1.CREATION.CDK);
|
|
91
165
|
if (process.env.PROJECT_ENV)
|
|
92
|
-
Tags.of(
|
|
166
|
+
Tags.of(construct).add(CDK$1.TAG.ENV, process.env.PROJECT_ENV);
|
|
93
167
|
if (process.env.PROJECT_NONCE)
|
|
94
|
-
Tags.of(
|
|
168
|
+
Tags.of(construct).add(CDK$1.TAG.NONCE, process.env.PROJECT_NONCE);
|
|
95
169
|
if (process.env.PROJECT_KEY)
|
|
96
|
-
Tags.of(
|
|
97
|
-
Tags.of(
|
|
170
|
+
Tags.of(construct).add(CDK$1.TAG.PROJECT, process.env.PROJECT_KEY);
|
|
171
|
+
Tags.of(construct).add(CDK$1.TAG.ROLE, CDK$1.ROLE.STACK);
|
|
98
172
|
if (process.env.PROJECT_SERVICE)
|
|
99
|
-
Tags.of(
|
|
173
|
+
Tags.of(construct).add(CDK$1.TAG.SERVICE, process.env.PROJECT_SERVICE);
|
|
100
174
|
if (process.env.PROJECT_SPONSOR)
|
|
101
|
-
Tags.of(
|
|
175
|
+
Tags.of(construct).add(CDK$1.TAG.SPONSOR, process.env.PROJECT_SPONSOR);
|
|
102
176
|
if (stackName)
|
|
103
|
-
Tags.of(
|
|
177
|
+
Tags.of(construct).add(CDK$1.TAG.STACK, stackName);
|
|
104
178
|
if (version)
|
|
105
|
-
Tags.of(
|
|
179
|
+
Tags.of(construct).add(CDK$1.TAG.VERSION, version);
|
|
106
180
|
return true;
|
|
107
181
|
}
|
|
108
182
|
|
|
183
|
+
function envHostname({ component, domain, env, subdomain, }) {
|
|
184
|
+
const resolvedDomain = domain || process.env.CDK_ENV_DOMAIN || process.env.CDK_ENV_HOSTED_ZONE;
|
|
185
|
+
if (!resolvedDomain) {
|
|
186
|
+
throw new ConfigurationError("No hostname `domain` provided. Set CDK_ENV_DOMAIN or CDK_ENV_HOSTED_ZONE to use environment domain");
|
|
187
|
+
}
|
|
188
|
+
const resolvedComponent = component === "@" || component === "" ? undefined : component;
|
|
189
|
+
const resolvedSubdomain = subdomain || process.env.CDK_ENV_SUBDOMAIN;
|
|
190
|
+
const resolvedEnv = env || process.env.PROJECT_ENV;
|
|
191
|
+
const parts = [
|
|
192
|
+
resolvedComponent,
|
|
193
|
+
resolvedSubdomain,
|
|
194
|
+
resolvedEnv,
|
|
195
|
+
resolvedDomain,
|
|
196
|
+
].filter((part) => part);
|
|
197
|
+
return parts.join(".");
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Check if the current environment matches the given environment
|
|
202
|
+
*/
|
|
203
|
+
function isEnv(env) {
|
|
204
|
+
return process.env.PROJECT_ENV === env;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Check if the current environment is production
|
|
208
|
+
*/
|
|
209
|
+
function isProductionEnv() {
|
|
210
|
+
return isEnv(CDK$2.ENV.PRODUCTION);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Check if the current environment is sandbox
|
|
214
|
+
*/
|
|
215
|
+
function isSandboxEnv() {
|
|
216
|
+
return isEnv(CDK$2.ENV.SANDBOX);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function jaypieLambdaEnv(options = {}) {
|
|
220
|
+
const { initialEnvironment = {} } = options;
|
|
221
|
+
// Start with empty environment - we'll only add valid values
|
|
222
|
+
let environment = {};
|
|
223
|
+
// First, add all valid string values from initialEnvironment
|
|
224
|
+
Object.entries(initialEnvironment).forEach(([key, value]) => {
|
|
225
|
+
if (typeof value === "string") {
|
|
226
|
+
environment[key] = value;
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
// Default environment values
|
|
230
|
+
const defaultEnvValues = {
|
|
231
|
+
AWS_LAMBDA_NODEJS_DISABLE_CALLBACK_WARNING: "true",
|
|
232
|
+
};
|
|
233
|
+
// Apply default environment values with user overrides
|
|
234
|
+
Object.entries(defaultEnvValues).forEach(([key, defaultValue]) => {
|
|
235
|
+
if (key in initialEnvironment) {
|
|
236
|
+
const userValue = initialEnvironment[key];
|
|
237
|
+
// If user passes a string, it's already added above
|
|
238
|
+
// If user passes non-string falsy value, omit the key
|
|
239
|
+
if (!userValue) {
|
|
240
|
+
delete environment[key];
|
|
241
|
+
}
|
|
242
|
+
// Ignore non-string truthy values (key not added)
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
// No user override, use default value
|
|
246
|
+
environment[key] = defaultValue;
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
// Default environment variables from process.env if present
|
|
250
|
+
const defaultEnvVars = [
|
|
251
|
+
"DATADOG_API_KEY_ARN",
|
|
252
|
+
"LOG_LEVEL",
|
|
253
|
+
"MODULE_LOGGER",
|
|
254
|
+
"MODULE_LOG_LEVEL",
|
|
255
|
+
"PROJECT_CHAOS",
|
|
256
|
+
"PROJECT_COMMIT",
|
|
257
|
+
"PROJECT_ENV",
|
|
258
|
+
"PROJECT_KEY",
|
|
259
|
+
"PROJECT_SECRET",
|
|
260
|
+
"PROJECT_SERVICE",
|
|
261
|
+
"PROJECT_SPONSOR",
|
|
262
|
+
"PROJECT_VERSION",
|
|
263
|
+
];
|
|
264
|
+
// Add default environment variables if they exist in process.env
|
|
265
|
+
defaultEnvVars.forEach((envVar) => {
|
|
266
|
+
if (process.env[envVar] && !environment[envVar]) {
|
|
267
|
+
environment[envVar] = process.env[envVar];
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
return environment;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function resolveHostedZone(scope, { name = "HostedZone", zone = process.env.CDK_ENV_HOSTED_ZONE, }) {
|
|
274
|
+
if (!zone) {
|
|
275
|
+
throw new ConfigurationError("No `zone` provided. Set CDK_ENV_HOSTED_ZONE to use environment zone");
|
|
276
|
+
}
|
|
277
|
+
if (typeof zone === "string") {
|
|
278
|
+
return route53.HostedZone.fromLookup(scope, name, {
|
|
279
|
+
domainName: zone,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
return zone;
|
|
283
|
+
}
|
|
284
|
+
|
|
109
285
|
class JaypieApiGateway extends Construct {
|
|
110
286
|
constructor(scope, id, props) {
|
|
111
287
|
super(scope, id);
|
|
@@ -132,14 +308,7 @@ class JaypieApiGateway extends Construct {
|
|
|
132
308
|
let hostedZone;
|
|
133
309
|
let certificateToUse;
|
|
134
310
|
if (host && zone) {
|
|
135
|
-
|
|
136
|
-
hostedZone = route53.HostedZone.fromLookup(this, "HostedZone", {
|
|
137
|
-
domainName: zone,
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
hostedZone = zone;
|
|
142
|
-
}
|
|
311
|
+
hostedZone = resolveHostedZone(this, { zone });
|
|
143
312
|
if (certificate === true) {
|
|
144
313
|
certificateToUse = new acm.Certificate(this, certificateName, {
|
|
145
314
|
domainName: host,
|
|
@@ -271,7 +440,7 @@ class JaypieStack extends Stack {
|
|
|
271
440
|
};
|
|
272
441
|
super(scope, id, stackProps);
|
|
273
442
|
// Apply tags
|
|
274
|
-
|
|
443
|
+
constructTagger(this, { name: stackProps.stackName });
|
|
275
444
|
}
|
|
276
445
|
}
|
|
277
446
|
|
|
@@ -290,102 +459,11 @@ class JaypieLambda extends Construct {
|
|
|
290
459
|
constructor(scope, id, props) {
|
|
291
460
|
super(scope, id);
|
|
292
461
|
const { allowAllOutbound, allowPublicSubnet, architecture = lambda.Architecture.X86_64, code, codeSigningConfig, datadogApiKeyArn, deadLetterQueue, deadLetterQueueEnabled, deadLetterTopic, description, environment: initialEnvironment = {}, environmentEncryption, envSecrets = {}, ephemeralStorageSize, filesystem, handler = "index.handler", initialPolicy, layers = [], logRetention = CDK$2.LAMBDA.LOG_RETENTION, logRetentionRole, logRetentionRetryOptions, maxEventAge, memorySize = CDK$2.LAMBDA.MEMORY_SIZE, paramsAndSecrets, paramsAndSecretsOptions, profiling, profilingGroup, provisionedConcurrentExecutions, reservedConcurrentExecutions, retryAttempts, roleTag = CDK$2.ROLE.PROCESSING, runtime = lambda.Runtime.NODEJS_22_X, runtimeManagementMode, secrets = [], securityGroups, timeout = Duration.seconds(CDK$2.DURATION.LAMBDA_WORKER), tracing, vendorTag, vpc, vpcSubnets, } = props;
|
|
293
|
-
//
|
|
294
|
-
|
|
295
|
-
// Default environment values
|
|
296
|
-
const defaultEnvValues = {
|
|
297
|
-
AWS_LAMBDA_NODEJS_DISABLE_CALLBACK_WARNING: "true",
|
|
298
|
-
};
|
|
299
|
-
// Apply default environment values with user overrides
|
|
300
|
-
Object.entries(defaultEnvValues).forEach(([key, defaultValue]) => {
|
|
301
|
-
if (key in initialEnvironment) {
|
|
302
|
-
const userValue = initialEnvironment[key];
|
|
303
|
-
// If user passes a string, use that value
|
|
304
|
-
if (typeof userValue === "string") {
|
|
305
|
-
environment[key] = userValue;
|
|
306
|
-
}
|
|
307
|
-
// If user passes non-string falsy value, omit the key
|
|
308
|
-
else if (!userValue) {
|
|
309
|
-
delete environment[key];
|
|
310
|
-
}
|
|
311
|
-
// Ignore non-string truthy values (key already not present)
|
|
312
|
-
}
|
|
313
|
-
else {
|
|
314
|
-
// No user override, use default value
|
|
315
|
-
environment[key] = defaultValue;
|
|
316
|
-
}
|
|
317
|
-
});
|
|
318
|
-
// Default environment variables from process.env if present
|
|
319
|
-
const defaultEnvVars = [
|
|
320
|
-
"DATADOG_API_KEY_ARN",
|
|
321
|
-
"LOG_LEVEL",
|
|
322
|
-
"MODULE_LOGGER",
|
|
323
|
-
"MODULE_LOG_LEVEL",
|
|
324
|
-
"PROJECT_COMMIT",
|
|
325
|
-
"PROJECT_ENV",
|
|
326
|
-
"PROJECT_KEY",
|
|
327
|
-
"PROJECT_SECRET",
|
|
328
|
-
"PROJECT_SERVICE",
|
|
329
|
-
"PROJECT_SPONSOR",
|
|
330
|
-
"PROJECT_VERSION",
|
|
331
|
-
];
|
|
332
|
-
// Add default environment variables if they exist in process.env
|
|
333
|
-
defaultEnvVars.forEach((envVar) => {
|
|
334
|
-
if (process.env[envVar] && !environment[envVar]) {
|
|
335
|
-
environment[envVar] = process.env[envVar];
|
|
336
|
-
}
|
|
337
|
-
});
|
|
462
|
+
// Get base environment with defaults
|
|
463
|
+
const environment = jaypieLambdaEnv({ initialEnvironment });
|
|
338
464
|
const codeAsset = typeof code === "string" ? lambda.Code.fromAsset(code) : code;
|
|
339
465
|
// Create a working copy of layers
|
|
340
466
|
const resolvedLayers = [...layers];
|
|
341
|
-
// Determine if we should add Datadog integration
|
|
342
|
-
// Check for datadog API key ARN in different sources
|
|
343
|
-
const resolvedDatadogApiKeyArn = datadogApiKeyArn ||
|
|
344
|
-
process.env.DATADOG_API_KEY_ARN ||
|
|
345
|
-
process.env.CDK_ENV_DATADOG_API_KEY_ARN;
|
|
346
|
-
// Add Datadog integration if API key is available
|
|
347
|
-
if (resolvedDatadogApiKeyArn) {
|
|
348
|
-
// Add Datadog Node.js layer
|
|
349
|
-
const datadogNodeLayer = lambda.LayerVersion.fromLayerVersionArn(this, "DatadogNodeLayer", `arn:aws:lambda:${Stack.of(this).region}:464622532012:layer:Datadog-Node20-x:${CDK$2.DATADOG.LAYER.NODE}`);
|
|
350
|
-
resolvedLayers.push(datadogNodeLayer);
|
|
351
|
-
// Add Datadog Extension layer
|
|
352
|
-
const datadogExtensionLayer = lambda.LayerVersion.fromLayerVersionArn(this, "DatadogExtensionLayer", `arn:aws:lambda:${Stack.of(this).region}:464622532012:layer:Datadog-Extension:${CDK$2.DATADOG.LAYER.EXTENSION}`);
|
|
353
|
-
resolvedLayers.push(datadogExtensionLayer);
|
|
354
|
-
// Set Datadog environment variables
|
|
355
|
-
Object.assign(environment, {
|
|
356
|
-
DD_API_KEY_SECRET_ARN: resolvedDatadogApiKeyArn,
|
|
357
|
-
DD_ENHANCED_METRICS: "true",
|
|
358
|
-
DD_ENV: process.env.PROJECT_ENV || "",
|
|
359
|
-
DD_PROFILING_ENABLED: "false",
|
|
360
|
-
DD_SERVERLESS_APPSEC_ENABLED: "false",
|
|
361
|
-
DD_SERVICE: process.env.PROJECT_SERVICE || "",
|
|
362
|
-
DD_SITE: CDK$2.DATADOG.SITE,
|
|
363
|
-
DD_TAGS: `${CDK$2.TAG.SPONSOR}:${process.env.PROJECT_SPONSOR || ""}`,
|
|
364
|
-
DD_TRACE_OTEL_ENABLED: "false",
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
// Configure ParamsAndSecrets layer
|
|
368
|
-
let resolvedParamsAndSecrets = undefined;
|
|
369
|
-
if (paramsAndSecrets !== false) {
|
|
370
|
-
if (paramsAndSecrets instanceof lambda.ParamsAndSecretsLayerVersion) {
|
|
371
|
-
resolvedParamsAndSecrets = paramsAndSecrets;
|
|
372
|
-
}
|
|
373
|
-
else {
|
|
374
|
-
// Create default ParamsAndSecrets layer
|
|
375
|
-
resolvedParamsAndSecrets =
|
|
376
|
-
lambda.ParamsAndSecretsLayerVersion.fromVersion(lambda.ParamsAndSecretsVersions.V1_0_103, {
|
|
377
|
-
cacheSize: paramsAndSecretsOptions?.cacheSize,
|
|
378
|
-
logLevel: paramsAndSecretsOptions?.logLevel ||
|
|
379
|
-
lambda.ParamsAndSecretsLogLevel.WARN,
|
|
380
|
-
parameterStoreTtl: paramsAndSecretsOptions?.parameterStoreTtl
|
|
381
|
-
? Duration.seconds(paramsAndSecretsOptions.parameterStoreTtl)
|
|
382
|
-
: undefined,
|
|
383
|
-
secretsManagerTtl: paramsAndSecretsOptions?.secretsManagerTtl
|
|
384
|
-
? Duration.seconds(paramsAndSecretsOptions.secretsManagerTtl)
|
|
385
|
-
: undefined,
|
|
386
|
-
});
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
467
|
// Process secrets environment variables
|
|
390
468
|
const secretsEnvironment = Object.entries(envSecrets).reduce((acc, [key, secret]) => ({
|
|
391
469
|
...acc,
|
|
@@ -428,7 +506,6 @@ class JaypieLambda extends Construct {
|
|
|
428
506
|
logRetentionRetryOptions,
|
|
429
507
|
maxEventAge,
|
|
430
508
|
memorySize,
|
|
431
|
-
paramsAndSecrets: resolvedParamsAndSecrets,
|
|
432
509
|
profiling,
|
|
433
510
|
profilingGroup,
|
|
434
511
|
reservedConcurrentExecutions,
|
|
@@ -449,6 +526,13 @@ class JaypieLambda extends Construct {
|
|
|
449
526
|
}
|
|
450
527
|
: undefined,
|
|
451
528
|
});
|
|
529
|
+
// Add ParamsAndSecrets layer if configured
|
|
530
|
+
addParamsAndSecrets(this._lambda, {
|
|
531
|
+
paramsAndSecrets,
|
|
532
|
+
paramsAndSecretsOptions,
|
|
533
|
+
});
|
|
534
|
+
// Add Datadog layers and environment variables if configured
|
|
535
|
+
addDatadogLayer(this._lambda, { datadogApiKeyArn });
|
|
452
536
|
// Grant secret read permissions
|
|
453
537
|
Object.values(envSecrets).forEach((secret) => {
|
|
454
538
|
secret.grantRead(this._lambda);
|
|
@@ -457,11 +541,6 @@ class JaypieLambda extends Construct {
|
|
|
457
541
|
secrets.forEach((secret) => {
|
|
458
542
|
secret.grantRead(this._lambda);
|
|
459
543
|
});
|
|
460
|
-
// Grant Datadog API key read permission if applicable
|
|
461
|
-
if (resolvedDatadogApiKeyArn) {
|
|
462
|
-
const datadogApiKey = secretsmanager.Secret.fromSecretCompleteArn(this, "DatadogApiKeyGrant", resolvedDatadogApiKeyArn);
|
|
463
|
-
datadogApiKey.grantRead(this._lambda);
|
|
464
|
-
}
|
|
465
544
|
// Configure provisioned concurrency if specified
|
|
466
545
|
if (provisionedConcurrentExecutions !== undefined) {
|
|
467
546
|
// Use currentVersion which is auto-published with proper configuration
|
|
@@ -1702,6 +1781,9 @@ class JaypieWebDeploymentBucket extends Construct {
|
|
|
1702
1781
|
grantWrite(identity, objectsKeyPattern) {
|
|
1703
1782
|
return this.bucket.grantWrite(identity, objectsKeyPattern);
|
|
1704
1783
|
}
|
|
1784
|
+
grantReplicationPermission(identity, props) {
|
|
1785
|
+
return this.bucket.grantReplicationPermission(identity, props);
|
|
1786
|
+
}
|
|
1705
1787
|
s3UrlForObject(key) {
|
|
1706
1788
|
return this.bucket.s3UrlForObject(key);
|
|
1707
1789
|
}
|
|
@@ -1752,5 +1834,5 @@ class JaypieWebDeploymentBucket extends Construct {
|
|
|
1752
1834
|
}
|
|
1753
1835
|
}
|
|
1754
1836
|
|
|
1755
|
-
export { JaypieApiGateway, JaypieAppStack, JaypieBucketQueuedLambda, JaypieDatadogSecret, JaypieEnvSecret, JaypieExpressLambda, JaypieHostedZone, JaypieInfrastructureStack, JaypieLambda, JaypieMongoDbSecret, JaypieOpenAiSecret, JaypieQueuedLambda, JaypieSsoGroups, JaypieStack, JaypieTraceSigningKeySecret, JaypieWebDeploymentBucket, PermissionSetType, constructEnvName, constructStackName, isEnv, isProductionEnv, isSandboxEnv,
|
|
1837
|
+
export { JaypieApiGateway, JaypieAppStack, JaypieBucketQueuedLambda, JaypieDatadogSecret, JaypieEnvSecret, JaypieExpressLambda, JaypieHostedZone, JaypieInfrastructureStack, JaypieLambda, JaypieMongoDbSecret, JaypieOpenAiSecret, JaypieQueuedLambda, JaypieSsoGroups, JaypieStack, JaypieTraceSigningKeySecret, JaypieWebDeploymentBucket, PermissionSetType, addDatadogLayer, addParamsAndSecrets, constructEnvName, constructStackName, constructTagger, envHostname, isEnv, isProductionEnv, isSandboxEnv, jaypieLambdaEnv, resolveHostedZone };
|
|
1756
1838
|
//# sourceMappingURL=index.js.map
|