LayerにGemを格納してAWS Lambda関数を成功させる方法(3)Ruby 3.3版

はじめに

先日、Rubyで実装したAWS Lambda関数にてpg gemを使う方法を記しました。

miyohide.hatenablog.com

上記の記事では、Ruby 3.2のバージョンで実装したのですが、この記事を記したのちにRuby 3.3版がリリースされました。

aws.amazon.com

Ruby 3.3版においてはベースとなるOSもAmazon Linux 2023に変わっているので、上記記事で記したDockerfileなどの記述も変更が必要になると考えられます。ここでは、Ruby 3.3版でpg gemを使う方法を記します。

Layerを作るためのコンテナイメージを作る

Layerを作るためのコンテナイメージを作ります。以下のようなDockerfileを用意します。

FROM public.ecr.aws/sam/build-ruby3.3:latest-x86_64

WORKDIR /var/task

RUN dnf install -y postgresql15 libpq-devel
RUN gem update bundler
CMD ["bash", "make_layer.sh"]

Base ImageをRuby 3.3のものにし、インストールするPostgreSQL関連ライブラリを若干変えています。

pg gemを使うために必要なライブラリ等をコピーするshell scriptであるmake_layer.shを以下の中身で用意します。

bundle config --local silence_root_warning true
bundle config set clean true
bundle config set path '/var/task'

bundle install

mkdir -p /var/task/lib

cp -a /usr/lib64/libpq.so.5.15 /var/task/lib/libpq.so.5
cp -a /usr/lib64/liblber-2.4.so.2.11.5 /var/task/lib/liblber-2.4.so.2
cp -a /usr/lib64/libldap_r-2.4.so.2.11.5 /var/task/lib/libldap_r-2.4.so.2
cp -a /usr/lib64/libsasl2.so.3.0.0 /var/task/lib/libsasl2.so.3
cp -a /usr/lib64/libssl3.so /var/task/lib/libssl3.so
cp -a /usr/lib64/libsmime3.so /var/task/lib/libsmime3.so
cp -a /usr/lib64/libnss3.so /var/task/lib/libnss3.so
cp -a /usr/lib64/libnssutil3.so /var/task/lib/libnssutil3.so

cd /var/task
zip -r layer.zip .

Ruby 3.2版と比べて幾つかのライブラリのバージョンが微妙に変わっています。

あとは、docker build -t ruby-lambda-layer .を実行してコンテナイメージを作成し、docker run --rm -it -v $PWD:/var/task ruby-lambda-layerを実行するとzipファイルが作成されます。

環境変数の設定

Lambdaの環境変数としてGEM_HOME.opt/ruby/3.3.0を設定しておきます。Ruby 3.2版で必要だったLD_PRELOADは必要ありませんでした。

実行

単純にrequire 'pg'としただけの以下のプログラムで動作確認をします。

無事、正常終了しました。

考察

先日の記事にも記した通り、動作にはLambdaの動作環境に強く依存したライブラリのコピーが必要となり、動作環境の変更が発生すると微妙なバージョン番号が変わっているのは地味に大変です。

RubyにおいてはLambdaで動くコンテナイメージを作っておいた方が考えることが少なくて良いと思われます。

コンテナイメージのつくり方は以下を参照すると良いかなと思います。

miyohide.hatenablog.com