Skip to content

Commit

Permalink
chore: Make helpers take one, not multiple Lambda functions (2/x) (#323)
Browse files Browse the repository at this point in the history
  • Loading branch information
lym953 authored Nov 21, 2024
1 parent cd9a525 commit 07abcbc
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 82 deletions.
24 changes: 12 additions & 12 deletions src/datadog-lambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,19 +84,19 @@ export class DatadogLambda extends Construct {
log.debug("Granting read access to the provided Secret ARN for all your lambda functions.");
grantReadLambdaFromSecretArn(construct, this.props.apiKeySecretArn, lambdaFunction);
}
}

if (baseProps.addLayers) {
applyLayers(
this.scope,
region,
extractedLambdaFunctions,
this.props.pythonLayerVersion,
this.props.nodeLayerVersion,
this.props.javaLayerVersion,
this.props.dotnetLayerVersion,
this.props.useLayersFromAccount,
);
if (baseProps.addLayers) {
applyLayers(
this.scope,
region,
lambdaFunction,
this.props.pythonLayerVersion,
this.props.nodeLayerVersion,
this.props.javaLayerVersion,
this.props.dotnetLayerVersion,
this.props.useLayersFromAccount,
);
}
}

if (baseProps.extensionLayerVersion !== undefined) {
Expand Down
106 changes: 54 additions & 52 deletions src/layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const layers: Map<string, lambda.ILayerVersion> = new Map();
export function applyLayers(
scope: Construct,
region: string,
lambdas: lambda.Function[],
lam: lambda.Function,
pythonLayerVersion?: number,
nodeLayerVersion?: number,
javaLayerVersion?: number,
Expand All @@ -37,59 +37,61 @@ export function applyLayers(
// TODO: check region availability
const errors: string[] = [];
log.debug("Applying layers to Lambda functions...");
lambdas.forEach((lam) => {
const runtime: string = lam.runtime.name;
const lambdaRuntimeType: RuntimeType = runtimeLookup[runtime];
const isARM = lam.architecture?.dockerPlatform === Architecture.ARM_64.dockerPlatform;
const runtime: string = lam.runtime.name;
const lambdaRuntimeType: RuntimeType = runtimeLookup[runtime];
const isARM = lam.architecture?.dockerPlatform === Architecture.ARM_64.dockerPlatform;

if (lambdaRuntimeType === undefined || lambdaRuntimeType === RuntimeType.UNSUPPORTED) {
log.debug(`Unsupported runtime: ${runtime}`);
return;
}
if (lambdaRuntimeType === undefined || lambdaRuntimeType === RuntimeType.UNSUPPORTED) {
log.debug(`Unsupported runtime: ${runtime}`);
return errors;
}

const accountId = useLayersFromAccount;
let lambdaLayerArn;
switch (lambdaRuntimeType) {
case RuntimeType.PYTHON:
if (pythonLayerVersion === undefined) {
return handleLayerError(errors, lam.node.id, "Python", "python");
}
lambdaLayerArn = getLambdaLayerArn(region, pythonLayerVersion, runtime, isARM, accountId);
log.debug(`Using Python Lambda layer: ${lambdaLayerArn}`);
addLayer(lambdaLayerArn, false, scope, lam, runtime);
break;

case RuntimeType.NODE:
if (nodeLayerVersion === undefined) {
return handleLayerError(errors, lam.node.id, "Node.js", "node");
}
lambdaLayerArn = getLambdaLayerArn(region, nodeLayerVersion, runtime, false, accountId); // Node has no ARM layer
log.debug(`Using Node Lambda layer: ${lambdaLayerArn}`);
addLayer(lambdaLayerArn, false, scope, lam, runtime);
break;

case RuntimeType.JAVA:
if (javaLayerVersion === undefined) {
return handleLayerError(errors, lam.node.id, "Java", "java");
}
lambdaLayerArn = getLambdaLayerArn(region, javaLayerVersion, runtime, false, accountId); //Java has no ARM layer
log.debug(`Using dd-trace-java layer: ${lambdaLayerArn}`);
addLayer(lambdaLayerArn, false, scope, lam, runtime);
break;

case RuntimeType.DOTNET:
if (dotnetLayerVersion === undefined) {
return handleLayerError(errors, lam.node.id, ".NET", "dotnet");
}
lambdaLayerArn = getLambdaLayerArn(region, dotnetLayerVersion, runtime, isARM, accountId);
log.debug(`Using dd-trace-dotnet layer: ${lambdaLayerArn}`);
addLayer(lambdaLayerArn, false, scope, lam, runtime);
break;

case RuntimeType.CUSTOM:
break;
}
});
const accountId = useLayersFromAccount;
let lambdaLayerArn;
switch (lambdaRuntimeType) {
case RuntimeType.PYTHON:
if (pythonLayerVersion === undefined) {
handleLayerError(errors, lam.node.id, "Python", "python");
return errors;
}
lambdaLayerArn = getLambdaLayerArn(region, pythonLayerVersion, runtime, isARM, accountId);
log.debug(`Using Python Lambda layer: ${lambdaLayerArn}`);
addLayer(lambdaLayerArn, false, scope, lam, runtime);
break;

case RuntimeType.NODE:
if (nodeLayerVersion === undefined) {
handleLayerError(errors, lam.node.id, "Node.js", "node");
return errors;
}
lambdaLayerArn = getLambdaLayerArn(region, nodeLayerVersion, runtime, false, accountId); // Node has no ARM layer
log.debug(`Using Node Lambda layer: ${lambdaLayerArn}`);
addLayer(lambdaLayerArn, false, scope, lam, runtime);
break;

case RuntimeType.JAVA:
if (javaLayerVersion === undefined) {
handleLayerError(errors, lam.node.id, "Java", "java");
return errors;
}
lambdaLayerArn = getLambdaLayerArn(region, javaLayerVersion, runtime, false, accountId); //Java has no ARM layer
log.debug(`Using dd-trace-java layer: ${lambdaLayerArn}`);
addLayer(lambdaLayerArn, false, scope, lam, runtime);
break;

case RuntimeType.DOTNET:
if (dotnetLayerVersion === undefined) {
handleLayerError(errors, lam.node.id, ".NET", "dotnet");
return errors;
}
lambdaLayerArn = getLambdaLayerArn(region, dotnetLayerVersion, runtime, isARM, accountId);
log.debug(`Using dd-trace-dotnet layer: ${lambdaLayerArn}`);
addLayer(lambdaLayerArn, false, scope, lam, runtime);
break;

case RuntimeType.CUSTOM:
break;
}
return errors;
}

Expand Down
35 changes: 17 additions & 18 deletions test/layer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe("applyLayers", () => {
code: lambda.Code.fromAsset("test/lambda"),
handler: "example-lambda.handler",
});
const errors = applyLayers(stack, stack.region, [hello], PYTHON_LAYER_VERSION, NODE_LAYER_VERSION);
const errors = applyLayers(stack, stack.region, hello, PYTHON_LAYER_VERSION, NODE_LAYER_VERSION);
Template.fromStack(stack).hasResourceProperties("AWS::Lambda::Function", {
Layers: [`arn:aws:lambda:${stack.region}:${DD_ACCOUNT_ID}:layer:Datadog-Node16-x:${NODE_LAYER_VERSION}`],
});
Expand Down Expand Up @@ -200,7 +200,7 @@ describe("applyLayers", () => {
handler: "example-lambda.handler",
});
(hello as any).architecture = undefined;
const errors = applyLayers(stack, stack.region, [hello], PYTHON_LAYER_VERSION, NODE_LAYER_VERSION);
const errors = applyLayers(stack, stack.region, hello, PYTHON_LAYER_VERSION, NODE_LAYER_VERSION);
Template.fromStack(stack).hasResourceProperties("AWS::Lambda::Function", {
Layers: [`arn:aws:lambda:${stack.region}:${DD_ACCOUNT_ID}:layer:Datadog-Node16-x:${NODE_LAYER_VERSION}`],
});
Expand Down Expand Up @@ -230,9 +230,13 @@ describe("applyLayers", () => {
handler: "example-lambda.handler",
});

const errors = applyLayers(stack, stack.region, [hello1, hello2, hello3], PYTHON_LAYER_VERSION, NODE_LAYER_VERSION);
const errors1 = applyLayers(stack, stack.region, hello1, PYTHON_LAYER_VERSION, NODE_LAYER_VERSION);
const errors2 = applyLayers(stack, stack.region, hello2, PYTHON_LAYER_VERSION, NODE_LAYER_VERSION);
const errors3 = applyLayers(stack, stack.region, hello3, PYTHON_LAYER_VERSION, NODE_LAYER_VERSION);

expect(errors.length).toEqual(0);
expect(errors1.length).toEqual(0);
expect(errors2.length).toEqual(0);
expect(errors3.length).toEqual(0);
Template.fromStack(stack).hasResourceProperties("AWS::Lambda::Function", {
Layers: [`arn:aws:lambda:${stack.region}:${DD_ACCOUNT_ID}:layer:Datadog-Node16-x:${NODE_LAYER_VERSION}`],
});
Expand All @@ -256,7 +260,7 @@ describe("applyLayers", () => {
code: lambda.Code.fromAsset("test"),
handler: "hello.handler",
});
const errors = applyLayers(stack, stack.region, [hello], PYTHON_LAYER_VERSION, NODE_LAYER_VERSION);
const errors = applyLayers(stack, stack.region, hello, PYTHON_LAYER_VERSION, NODE_LAYER_VERSION);
Template.fromStack(stack).hasResourceProperties("AWS::Lambda::Function", {
Layers: Match.absent(),
});
Expand Down Expand Up @@ -394,14 +398,13 @@ describe("applyLayers", () => {
code: lambda.Code.fromAsset("test/lambda"),
handler: "example-lambda.handler",
});
const errors = applyLayers(stack, stack.region, [hello1, hello2]);
const errors1 = applyLayers(stack, stack.region, hello1);
const errors2 = applyLayers(stack, stack.region, hello2);
Template.fromStack(stack).hasResourceProperties("AWS::Lambda::Function", {
Layers: Match.absent(),
});
expect(errors).toEqual([
getMissingLayerVersionErrorMsg("NodeHandler", "Node.js", "node"),
getMissingLayerVersionErrorMsg("PythonHandler", "Python", "python"),
]);
expect(errors1).toEqual([getMissingLayerVersionErrorMsg("NodeHandler", "Node.js", "node")]);
expect(errors2).toEqual([getMissingLayerVersionErrorMsg("PythonHandler", "Python", "python")]);
expect(logSpy).toHaveBeenCalledTimes(2);
logSpy.mockRestore();
});
Expand All @@ -426,15 +429,11 @@ describe("isGovCloud", () => {
code: lambda.Code.fromAsset("test/lambda"),
handler: "example-lambda.handler",
});
const errors = applyLayers(
stack,
stack.region,
[pythonLambda, nodeLambda],
PYTHON_LAYER_VERSION,
NODE_LAYER_VERSION,
);
const errorsPython = applyLayers(stack, stack.region, pythonLambda, PYTHON_LAYER_VERSION, NODE_LAYER_VERSION);
const errorsNode = applyLayers(stack, stack.region, nodeLambda, PYTHON_LAYER_VERSION, NODE_LAYER_VERSION);

expect(errors.length).toEqual(0);
expect(errorsPython.length).toEqual(0);
expect(errorsNode.length).toEqual(0);
Template.fromStack(stack).hasResourceProperties("AWS::Lambda::Function", {
Layers: [
`arn:aws-us-gov:lambda:us-gov-east-1:${DD_GOV_ACCOUNT_ID}:layer:Datadog-Python39:${PYTHON_LAYER_VERSION}`,
Expand Down

0 comments on commit 07abcbc

Please sign in to comment.