Lambda ARM64:ProcessSpawnFailedエラーの解決法
はじめに
AWS CDKを使ってLambda関数をデプロイしたところ、突然 ProcessSpawnFailed や InvalidEntrypoint というエラーが発生して困った経験はありませんか。ローカルでは正常に動作するのに、デプロイ後のLambdaで起動に失敗するという状況は、特にApple Silicon搭載のMacを使用している開発者にとって陥りやすい罠です。
この記事では、実際にこの問題に遭遇し解決した経験を基に、原因の特定方法から具体的な修正手順までをご紹介します。同様の問題で悩んでいる方の参考になれば幸いです。
発生したエラーの詳細と症状
エラーメッセージの内容
CDKでLambda関数をデプロイした後、関数を実行すると以下のようなエラーが返されました。
{
"errorType": "Runtime.InvalidEntrypoint",
"errorMessage": "RequestId: xxx Error: ProcessSpawnFailed"
}
このエラーは、Lambdaランタイムがハンドラー関数を起動できないことを示しています。ProcessSpawnFailedは、プロセスの生成自体が失敗していることを意味します。
ローカルでの動作確認結果
興味深いことに、Docker環境でローカルテストを実行すると正常に動作しました。
# ローカルでのDockerビルド
docker build -t test-lambda .
# Lambda Runtime Interface Emulatorでテスト
docker run --rm -p 9000:8080 test-lambda
# リクエスト送信 → 正常なレスポンスが返る
curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" \
-d '{"body": "{...}"}'
ローカルでは動くのにAWS上で動かないという状況から、環境依存の問題であることが推測できました。
根本原因:アーキテクチャの不一致
問題の本質
原因は、DockerイメージのビルドアーキテクチャとLambdaの実行アーキテクチャの不一致でした。
flowchart TD
A["Apple Silicon Mac
ARM64アーキテクチャ"] --> B["Docker build"]
B --> C["ARM64用イメージ生成
numpy/scipy等がARM64バイナリ"]
C --> D["ECRにプッシュ"]
D --> E["Lambda関数更新"]
E --> F{"Lambdaアーキテクチャ"}
F -->|"デフォルト: x86_64"| G["x86_64環境で
ARM64バイナリを実行"]
G --> H["ProcessSpawnFailed
バイナリ互換性エラー"]
Apple Silicon搭載のMac(M1、M2、M3など)はARM64アーキテクチャを採用しています。Dockerでイメージをビルドする際、デフォルトではホストマシンのアーキテクチャに合わせてビルドされます。
一方、AWS Lambdaはデフォルトでx86_64アーキテクチャで動作します。ARM64用にビルドされたバイナリ(特にnumpyやscipyなどのコンパイル済みライブラリ)は、x86_64環境では実行できません。
なぜnumpyやscipyが問題になるのか
Pythonのpure Python(純粋なPythonコード)のみで構成されるライブラリであれば、アーキテクチャの違いは問題になりません。しかし、numpyやscipyはパフォーマンスのためにC言語で書かれた拡張モジュールを含んでいます。
これらの拡張モジュールは、pip installの際にターゲットアーキテクチャ向けにコンパイルされます。ARM64環境でインストールされたバイナリは、x86_64環境では実行できないのです。
CDKでの解決方法
修正前のコード
問題のあるCDKスタックの実装は以下のようになっていました。
// cdk/lib/weight-estimation-stack.ts
const function = new lambda.DockerImageFunction(
this,
'function',
{
functionName: config.functionName,
code: lambda.DockerImageCode.fromImageAsset(
path.join(__dirname, '../../lambda'),
{
file: 'Dockerfile'
// platform指定なし → ホストのアーキテクチャでビルド
}
),
// architecture指定なし → デフォルトでx86_64
memorySize: 1024,
timeout: cdk.Duration.seconds(30),
// ...
}
);
修正後のコード
以下のように、platformとarchitectureを明示的に指定することで問題を解決できます。
// cdk/lib/weight-estimation-stack.ts
import { Platform } from 'aws-cdk-lib/aws-ecr-assets';
const function = new lambda.DockerImageFunction(
this,
'function',
{
functionName: config.functionName,
code: lambda.DockerImageCode.fromImageAsset(
path.join(__dirname, '../../lambda'),
{
file: 'Dockerfile',
platform: Platform.LINUX_AMD64 // x86_64用にビルド
}
),
architecture: lambda.Architecture.X86_64, // Lambda実行環境も明示
memorySize: 1024,
timeout: cdk.Duration.seconds(30),
// ...
}
);
修正のポイント
修正には2つの変更があります。
1つ目は、DockerImageCode.fromImageAssetのplatformオプションです。Platform.LINUX_AMD64を指定することで、Docker BuildxがクロスプラットフォームビルドでLinux/amd64(x86_64)用のイメージを生成します。
2つ目は、DockerImageFunctionのarchitectureオプションです。lambda.Architecture.X86_64を指定することで、Lambda関数がx86_64アーキテクチャで実行されることを明示します。
両方を指定することで、ビルド時と実行時のアーキテクチャが一致し、問題が解消されます。
修正後の確認方法
CDK synthでの検証
修正後、cdk synthコマンドでCloudFormationテンプレートを生成し、アーキテクチャが正しく設定されているか確認できます。
cd cdk
cdk synth --context environment=development
出力されるテンプレートに以下のような記述が含まれていれば成功です。
Resources:
WeightEstimationFunction:
Type: AWS::Lambda::Function
Properties:
Architectures:
- x86_64
# ...
デプロイと動作確認
アーキテクチャが正しく設定されていることを確認したら、デプロイを実行します。
cdk deploy --context environment=development --require-approval never
デプロイ完了後、Lambda関数を実行して正常にレスポンスが返ることを確認してください。
終わりに
Apple Silicon MacでCDKを使ってLambda Dockerイメージをデプロイする際は、アーキテクチャの明示的な指定が必須です。この問題は、ローカルでは正常に動作するため原因の特定に時間がかかりがちです。
実際にこの問題に遭遇した際、エラーメッセージだけでは原因が分かりづらく、ローカルとAWS環境の差分を一つずつ確認していく必要がありました。同様の環境で開発されている方は、最初からplatformとarchitectureを明示的に指定しておくことをお勧めします。
2025年12月時点の情報です。AWS CDK v2、Python 3.13ベースのLambda Dockerイメージで検証しています。
参考リンク
AWS Lambda Architectures
AWS CDK DockerImageCode
Docker Buildx Multi-platform builds
コメントを残す