๐ CDK Docker Lambda Builds: Multi-Architecture to the Rescue
If you've ever run into this Docker build error while deploying an AWS Lambda with CDK via codebuild:
ERROR: failed to solve: process "/bin/sh -c pip3 install --target \"${LAMBDA_TASK_ROOT}\" -r requirements.txt --no-cache-dir" did not complete successfully: exit code: 255
Failed to build asset EtlAuroraPostgresConstruct/ETLTaskProcessorlambdaFn/AssetImage
...and scratched your head over what was wrong, you're not alone.
After digging in, I found the culprit:
โ AWS CodeBuild only supports
x86_64
(amd64) architecture, but I was building a Lambda targetingarm64
.
In this post, Iโll walk through how I fixed it using:
- Dockerโs
${BUILDPLATFORM}
variable - CDK environment config switching
- Multi-platform Dockerfile magic
๐ฅ The Problem
If you're building Lambda functions using Docker bundling in CDK and targeting arm64
, but your build infrastructure (e.g., CodeBuild) only supports x86_64
, youโll hit architecture mismatches.
Symptoms:
- CDK build fails with cryptic Docker errors.
- Exit code
255
frompip install
. - It works locally on M1/M2 Macs or with arm64 runtimes โ but fails in CI/CD.
๐ ๏ธ The Solution
โ
Step 1: Use BUILDPLATFORM
in Your Dockerfile
To avoid architecture mismatch, set the platform explicitly in your Dockerfile:
# syntax=docker/dockerfile:1
FROM --platform=${BUILDPLATFORM} public.ecr.aws/lambda/python:3.12
RUN echo "Build platform: ${BUILDPLATFORM}" && echo "Target architecture: ${TARGETARCH}"
WORKDIR ${LAMBDA_TASK_ROOT}
COPY requirements.txt .
RUN pip3 install -r requirements.txt --no-cache-dir
COPY . .
CMD ["index.lambda_handler"]
๐ก
${BUILDPLATFORM}
is automatically injected by Docker when using BuildKit and--platform
.
โ Step 2: Add a CDK Architecture Config Switcher
Create a utility to determine platform & architecture based on an environment variable (CDK_LAMBDA_ARCHITECTURE
):
// get-architecture-config.ts
import * as cdk from "aws-cdk-lib";
import * as dotenv from "dotenv";
dotenv.config();
export const getArchitectureConfig = () => {
const arch = process.env.CDK_LAMBDA_ARCHITECTURE || "arm64";
switch (arch.toLowerCase()) {
case "arm64":
return {
architecture: cdk.aws_lambda.Architecture.ARM_64,
platform: cdk.aws_ecr_assets.Platform.LINUX_ARM64,
};
case "x86_64":
case "amd64":
return {
architecture: cdk.aws_lambda.Architecture.X86_64,
platform: cdk.aws_ecr_assets.Platform.LINUX_AMD64,
};
default:
throw new Error(`Unsupported architecture: ${arch}`);
}
};
This allows you to dynamically select the right platform during bundling.
โ Step 3: Use It in Your CDK Lambda Definition
In your CDK Stack
, integrate the platform and architecture selection into the Lambda function:
const { architecture, platform } = getArchitectureConfig();
code: lambda.Code.fromAsset(lambdaFnPath, {
bundling: {
image: targetRuntime.bundlingImage,
command: [
"bash",
"-c",
"pip install --no-cache-dir -r requirements.txt --only-binary=:all: --target /asset-output/python",
],
user: "root",
platform: platform.platform,
},
}),
architecture,
โ Step 4: Deploy with the Right Architecture
To switch architectures on demand, pass an env variable when deploying:
DOCKER_BUILDKIT=1 BUILDX_NO_DEFAULT_ATTESTATIONS=1 CDK_LAMBDA_ARCHITECTURE="amd64" cdk deploy
โ This forces CDK to build for
x86_64
, which works inside AWS CodeBuild or otheramd64
-only systems.
โ Final Tips
-
Default to
arm64
if youโre developing on an Apple Silicon machine and only override in CI/CD. - Add a
.env
file or use CI/CD variables to switch easily. - If you want reproducible builds, pin the base image version and dependencies tightly.
.env
export CDK_LAMBDA_ARCHITECTURE="amd64"
export DOCKER_BUILDKIT=1
export BUILDX_NO_DEFAULT_ATTESTATIONS=1
๐งช Conclusion
By using BUILDPLATFORM
, environment-based architecture switching, and a bit of CDK magic, you can seamlessly build Docker-based Lambda functions for both arm64
and x86_64
, even if your CI/CD platform only supports one.
This approach lets you:
- Build natively for your development machine
- Deploy reliably from CI/CD
- Avoid architecture mismatch errors like
exit code 255
Top comments (0)