AWS Lambda では自作のDockerイメージを動かすことができます。
しかし動かしてみたところ以下のエラーが発生しました。
INIT_REPORT Init Duration: 48.73 ms Phase: init Status: error Error Type: Runtime.ExitError
INIT_REPORT Init Duration: 19.69 ms Phase: invoke Status: error Error Type: Runtime.ExitError
START RequestId: 12345678-abcd-1234-abcd-123456789012 Version: $LATEST
RequestId: 12345678-abcd-1234-abcd-123456789012 Error: Runtime exited without providing a reasonRuntime.ExitError
END RequestId: 12345678-abcd-1234-abcd-123456789012
REPORT RequestId: 12345678-abcd-1234-abcd-123456789012 Duration: 21.27 ms Billed Duration: 22 ms Memory Size: 2048 MB Max Memory Used: 6 MB
問題の詳細
エラータイプが Runtime.ExitError
、メッセージは Error: Runtime exited without providing a reasonRuntime.ExitError
となっています。
調べてみるとAWS re:Post(AWSの公式フォーラム)で以下の原因を疑えとあります。
- 関数のコードに、process.exit(0)、exit()、quit()、os.Exit()、Environment.Exit() などの構文を明示的に呼び出す終了コードがある
- メモリが足りない
- DB接続数が多すぎる
- アイドル状態の接続を再利用しようとしている
- ファイルディスクリプションやスレッド数の上限に引っかかっている
要は実行時エラーが発生していないかということですね(エラーメッセージからそれはその通りなのですが)。ただ、私の環境ではこれらに特に問題はありませんでした。
原因
実際の原因はコンテナイメージを保存したECRへLambdaからアクセスできていないことでした。手順は最初に載せた公式ドキュメントにもちゃんと書いてありました(Amazon ECR のアクセス許可)。特にECRリポジトリポリシーというものがあるというのは盲点でした。しかしエラーが Runtime.ExitError
というのはちょっと分かりづらいですね。せめて Permission Error 的なものを出してほしかったです。
ということで、以下のECRリポジトリポリシーを設定したところ上手く行きました。
{
"Sid": "LambdaECRImageRetrievalPolicy",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": [
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer"
]
}
ただちょっと注意点として、ポリシーを設定してすぐに上手くいったわけではありませんでした。キャッシュの問題なのかわかりませんが、関数をデプロイしなおしても同じエラーが出てしまい、私はそこで関数自体を作り直してしまいました。もしかしたら時間を置けば大丈夫だった可能性もあります。
まとめ
Lambdaでカスタムコンテナイメージを使って Runtime.ExitError
が出た場合、コード上の原因による実行時エラー以外にも、イメージをECRから取得する際の権限エラーでこれが発生している可能性がある、ということでした。実行時エラーと言われるけどコードに問題が無いように見えるときは、LambdaからECRにアクセスできるかどうかも疑ってみてください(そしてちゃんと公式ドキュメントを隅々まで読みましょう)。