public note

AWS Lambda カスタムイメージと Runtime Interface Clients

AWS Lambda に乗せるコンテナのベースイメージを自分でつくりたいときは、”Runtime Interface Clients” をイメージにインストールするとできます、というお話です。

AWSが提供しているベースイメージ

docs.aws.amazon.com

2021年5月時点で、6言語のイメージが提供されています。

これらのイメージを使う場合は、必要なライブラリが最初から入っているので、User Guide や sam init で出力されるサンプルを真似すればやりたいことはできると思います。以前書いた記事では、Ruby イメージのひとつである public.ecr.aws/lambda/ruby:2.7 を使用しました。

カスタムイメージ

一般のイメージをベースとして使いたい場合、Lambda サービスとやり取りできるようにします。

Lambda サービスとの通信は、Runtime API を介して行われます。Zip 型 Lambda や AWS が提供しているコンテナイメージの場合、API へのリクエスト処理は隠蔽されているので、意識することはありません。

このAPI とやり取りしてくれるライブラリとして、Runtime Interface Clients (以下、RIC) が提供されています。それをインストールしてコンテナのエントリポイントに指定すれば、AWS が提供するイメージと同じふるまいになるようです。

RIC は、上述した言語に対応した6種類が公開されています。

docs.aws.amazon.com

Ruby 版 RIC をお試し

Ruby 版 RIC は、https://rubygems.org/gems/aws_lambda_ric で公開されています。画面右下 Documentation のリンク先に、gem のインポートや Dockerfile の記述方法が紹介されています。

File: README — Documentation for aws_lambda_ric (1.0.2)

例として記載されている Dockerfile では、ベースイメージを amazonlinux:latest、エントリポイントを /usr/local/bin/aws_lambda_ric に指定しています。この Dockerfile は問題なく動作するのですが、ベースイメージを ruby:2.7-slim に変更したところ、Lambda 実行時にエラーが起きました。

{
  "errorMessage": "RequestId: xxxxxxxx-xxxx-0000-xxxx-xxxxxxxxxxxx Error: fork/exec /usr/local/bin/aws_lambda_ric: no such file or directory",
  "errorType": "Runtime.InvalidEntrypoint"
}

ruby:2.7-slimの場合は、指定するパスを /usr/local/bundle/bin/aws_lambda_ric にするのが正しいので、以下のようにエントリポイントを指定することで解決しました。

# ENTRYPOINT ["/usr/local/bin/aws_lambda_ric"]
ENTRYPOINT ["/usr/local/bundle/bin/aws_lambda_ric"]

似たようなところでつまづいた人が GitHub に Issue をあげていたので、調べた結果を踏まえ、コメントをしてみました。

Docs - Wrong ENTRYPOINT in the Dockerfile example · Issue #13 · aws/aws-lambda-ruby-runtime-interface-client · GitHub

その他の注意点として、WORKDIR を設定し忘れると同じく実行時にエラーが起きます。Lambda が出力するメッセージを見ると原因は明らかですね。

{
  "errorMessage": "RequestId: xxxxxxxx-xxxx-0000-xxxx-xxxxxxxxxxxx Error: the working directory '' is invalid, it needs to be an absolute path",
  "errorType": "Runtime.InvalidWorkingDir"
}