Lambda Layers用のawswranglerをpipでインストールする他のモジュールと同じLayersに含めてデプロイする

2023.08.25

データアナリティクス事業本部のueharaです。

今回は、Lambda Layer用のawswranglerをpipでインストールする他のモジュールと同じLayersに含めてデプロイしてみたいと思います。

はじめに

以下の記事でも紹介されている通り、awswranglerはpipでインストールすると容量が大きいため、githubのreleaseページでLambda Layersに登録するためのzipファイルが公開されています。

一旦上記でカスタムレイヤーを作成・追加し、別途pipにより用意したカスタムレイヤーを追加することもできるのですが、1つのレイヤーにまとめた方が都合が良いシーンもあるかと思いますので、今回はそれを簡単に実行できる方法をご紹介したいと思います。

前提

今回はdockerを用いてLambda Layersを構築します。

要所の処理についてはこちらの記事を参考に作成させて頂いております。

Lambdaは Python 3.9 で実行することを想定します。

やってみた

フォルダ構成

今回作成するフォルダの構成は以下の通りです。

.
├ build_deploy_layer.sh
├ Dockerfile
├ entrypoint.sh
└ requirements.txt

各ファイルの記述

build_deploy_layer.sh は以下の通りです。

build_deploy_layer.sh

#!/bin/bash -eu
if [ $# -ne 1 ]; then
  echo "指定された引数は$#個です。" 1>&2
  echo "実行するには1個の引数が必要です。" 1>&2
  echo "$0 [AWS CLI Profile]"
  exit 1
fi
Profile=$1
export AWS_PAGER=""
export AWS_PROFILE=$Profile
rm -rf layer.zip
docker build . -t bundle-pip-modules-for-aws-lambda-layers:python3.9
docker run --rm \
    -v $(pwd)/requirements.txt:/requirements.txt \
    -v $(pwd):/dist \
    bundle-pip-modules-for-aws-lambda-layers:python3.9 \
        -r requirements.txt
aws s3 cp ./layer.zip s3://cm-da-uehara/layer/test-python-layer.zip
aws lambda publish-layer-version \
    --layer-name test-python-layer \
    --compatible-runtimes python3.9 \
    --content S3Bucket=cm-da-uehara,S3Key=layer/test-python-layer.zip \

実行内容を簡単に説明すると、dockerをビルドした後、実行フォルダをマウント・Lambda Layers用のzipファイルを作成し、それをS3にアップロード、その後Lambda Layersを作成するという流れになっています。

上記では、バケット名は cm-da-uehara, オブジェクトキーは layer/test-python-layer.zip, Layer名は test-python-layer に設定していますが、こちらはご自身の環境に合わせて変更下さい。

次に Dockerfile は以下の通りです。

Dockerfile

FROM amazonlinux:2

ARG PYTHON_VERSION=3.9.12

RUN yum update -y && yum install -y tar gzip make gcc openssl-devel bzip2-devel libffi-devel wget unzip \
  && curl https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tgz | tar xz \
  && cd Python-${PYTHON_VERSION} && ./configure && make && make install \
  && cd - && rm -rf Python-${PYTHON_VERSION}

ADD entrypoint.sh /

RUN yum install -y zip \
  && mkdir /python \
  && chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]

イメージは amazonlinux:2 で、内容としてはPythonのビルドに必要なモジュールをインストールした後、Pythonの実行環境を用意しています。

その後、後述する entrypoint.sh を実行します。

entrypoint.sh

#!/bin/bash -eu

SRC=/python
DIST=/dist/layer.zip

wget https://github.com/aws/aws-sdk-pandas/releases/download/3.3.0/awswrangler-layer-3.3.0-py3.9.zip                                               
unzip awswrangler-layer-3.3.0-py3.9.zip

pip3 install -t ${SRC} $@
rm -f ${DIST}
zip -q -r ${DIST} ${SRC}

entrypoint.sh では、Lambda Layers用のawswranglerモジュールのダウンロード・解凍をし(./python配下に展開される)、 requirements.txt に記載されたモジュールをpipでインストールした後、再度zipで圧縮しています。

最後に、 requirements.txt になりますが、こちらはLambda Layersに含めたいawswrangler以外のモジュールを記載します。

requirements.txt

pyyaml==6.0.1
sqlparse==0.4.4

※展開したawswrangler-layer-3.3.0-py3.9.zipには pandasnumpy 等の主要モジュールは既に含まれています。

実行方法

上記のファイルの用意ができたら、以下のコマンドでLambda Layersを作成します。

bash build_deploy_layer.sh <AWSプロファイル名>

実行はこれで以上です。

確認

実行が成功していると、 test-python-layer というLambda Layersが作成されていると思うので、そちらを設定したLambda関数を用意し、以下を実行してみます。

import awswrangler as wr
import yaml


def lambda_handler(event, context):
    print("wr version:", wr.__version__)
    print("pyyaml version:", yaml.__version__)
    
    return {
        'statusCode': 200
    }

実行結果は以下の通りで、awswranglerとpipでインストールしたモジュール共に正常に読み込めていることが分かります。

最後に

今回は、Lambda Layers用のawswranglerをpipでインストールする他のモジュールと同じLayersに含めてデプロイしてみました。

参考になりましたら幸いです。

参考文献