Lambda Tips
AWS Lambdas can be frustrating to work with at times, be it due to outdated code or their hard to debug nature. To help with this, below are some tips:
- Debugging flags —
verboseanddryfor detailed output and side-effect-free runs - Health check action — respond to
action: "health"to report version and verify connections - Scripted health checks — automate verification as part of your deploy process
- Centralized health check — a single lambda that pings all others and compares versions
Debugging Flags
Every lambda should accept:
verbose: Have the lambda return averbosefield revealing the inner workings. A good logging strategy can make this redundant.dry: Simulate execution without side effects. This is particularly useful for lambdas that only run under certain circumstances, helping us determine if they have been met.
Admin Pages
Build admin pages that can invoke any lambda with these flags. This makes production debugging straightforward — you can test a lambda’s behavior without side effects, or get detailed output on what it’s doing.
Health Check Action
Every lambda should respond to an action: "health" message, reporting its version and optionally verifying its connections (DB, S3, etc.):
import { LambdaVersions } from "../shared/lambdaVersions";
const LAMBDA_NAME = "ProcessGeneration";
export const handler = async (event) => {
if (event.action === "health") {
return {
statusCode: 200,
body: JSON.stringify({
lambdaName: LAMBDA_NAME,
version: LambdaVersions[LAMBDA_NAME],
isHealthy: true,
}),
};
}
// normal Lambda logic...
};
Centralized Version Numbers
In the above code, we pull the version from a shared version map:
// shared/lambdaVersions.ts
export const LambdaVersions = {
CreateRequest: 3,
ProcessGeneration: 12,
GetStatus: 4,
} as const;
By moving to a shared package, both the backend and frontend can import allowing us to easily check whether the lambda is up-to-date.
Increment the version when you deploy changes. This lets you verify that the deployed code matches what you expect.
Scripted Health Checks
With health checks in place, you can automate verification as part of your LocalStack deploy. A script that hits each lambda and exits non-zero on failure:
#!/bin/bash
LAMBDAS=("CreateRequest" "ProcessGeneration" "GetStatus")
FAILED=0
for NAME in "${LAMBDAS[@]}"; do
URL=$(awslocal lambda get-function-url-config \
--function-name "$NAME" --query 'FunctionUrl' --output text 2>/dev/null)
if [[ -z "$URL" || "$URL" == "None" ]]; then
echo "❌ $NAME: could not resolve Function URL"
FAILED=1
continue
fi
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "$URL" \
-H "Content-Type: application/json" \
-d '{"action":"health"}' --max-time 15)
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | sed '$d')
STATUS=$(echo "$BODY" | jq -r '.isHealthy // empty' 2>/dev/null)
if [[ "$HTTP_CODE" == "200" && "$STATUS" == "true" ]]; then
echo "✅ $NAME"
else
echo "❌ $NAME (HTTP $HTTP_CODE)"
FAILED=1
fi
done
exit $FAILED
Call it at the end of your deploy script so broken deploys fail fast:
./test-lambda-health.sh
if [ $? -ne 0 ]; then
exit 1
fi
This catches misconfigured environment variables, missing dependencies, and bundling issues before you start manually testing.
Centralized Health Check
To make it easier to determine the overall health of the system, including any private lambdas, create a single lambda that pings all others and aggregates their status:
import { LambdaClient, InvokeCommand } from "@aws-sdk/client-lambda";
import { LambdaVersions } from "@myMono/shared/lambdaVersions";
const lambda = new LambdaClient({});
const lambdaNames = Object.keys(LambdaVersions);
async function check(functionName) {
const res = await lambda.send(
new InvokeCommand({
FunctionName: functionName,
Payload: JSON.stringify({ action: "health" }),
}),
);
return JSON.parse(new TextDecoder().decode(res.Payload)).body;
}
export const handler = async () => {
const results = await Promise.all(lambdaNames.map(check));
return {
statusCode: 200,
body: JSON.stringify({ lambdas: results }),
};
};
Admin UI
Call the health check from your admin UI and compare reported versions against expected:
import { LambdaVersions } from "@myMono/shared/lambdaVersions";
function VersionRow({ name, reported }) {
const expected = LambdaVersions[name];
const mismatch = expected !== reported;
return (
<div className={mismatch ? "warning" : "ok"}>
{name}: {reported} {mismatch && `(expected ${expected})`}
</div>
);
}