なになれ

IT系のことを記録していきます

AWS Lambdaのコンテナイメージサポートを前提としたローカルでの環境構築・テストを考えた

データエンジニアリングの文脈で、AWS Lambdaを使ってデータ処理を実装することが最近多くなってきました。
Lambdaでは、コンテナイメージサポートを利用することで、ローカルでのテストがやりやすくなっています。
これを踏まえて、Lambdaのローカルでの環境構築・テストについて考えました。

なお、本内容のソースコードは以下にあります。

github.com

概要

Pythonでデータ処理を行う前提としています。
以下が今回のポイントになります。

  • Lambdaのデプロイには、コンテナイメージを利用する
  • VSCode Remote Containerを利用してコンテナで開発環境をセットアップする
  • Lambdaの環境に依存しないユニットテストを実行する
  • コンテナの環境でLambda関数を実行する

Lambdaでコンテナイメージが利用できるので、開発環境もコンテナで完結させます。
各個人で行う開発環境セットアップの手間を極力少なくすることが狙いです。

実現方法

本内容では、以下をインストールする前提です。

Lambdaのコンテナイメージ

Lambdaのコンテナイメージを用意します。
Lambdaランタイムのベースイメージを利用したDockerfileを以下のように作成します。

Dockerfile

FROM public.ecr.aws/lambda/python:3.8
COPY . .
RUN pip install --no-cache-dir -r requirements.txt
CMD ["app.handler"]

public.ecr.aws/lambda/pythonPythonのLambdaランタイムのベースイメージです。
CMDのapp.handlerapp.pyhandler関数を実行する記述になります。

VSCode Remote Container向けのセットアップ

VSCodeRemote-Containers: Open Folder in Containerコマンドを実行すると、コンテナ上にVSCodeの開発環境を用意できます。
その元ネタになるdocker-compose.ymlを用意します。

docker-compose.yml

version: '3'

services:
  development:
    build:
      context: ./
      dockerfile: Dockerfile.dev
    volumes:
      - ./:/work
    depends_on:
      - lambda
  lambda:
    build: ./
...

developmentが開発環境として動作するコンテナです。Dockerfile.devで開発に必要なモジュールをインストールします。
lambdaが先程の手順で用意したLambdaのコンテナイメージです。

Dockerfile.devの内容です。

Dockerfile.dev

FROM python:3.8
RUN pip install pipenv autopep8 flake8
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" \
&& unzip awscliv2.zip \
&& ./aws/install
WORKDIR /work

Pythonやその他、Pythonのプログラムを実行するのに必要なモジュールをインストールしています。

テスト実行・動作確認

VSCodeを起動し、Remote-Containers: Open Folder in Containerで該当のディレクトリを開きます。
VSCode上では、これまでの手順でセットアップした環境が用意されるはずです。

今回試した環境では、PipenvでPythonの環境をセットアップし、pytestでユニットテストを実行しています。

以下のコマンドでユニットテストを実行します。

pipenv install -d
pipenv run test

testのコマンドでpytestが実行されるように設定しています。

Pipfile

...
[scripts]
test = "pytest -v"

Lambdaのコンテナが起動しているため、以下のコマンドでLambda関数を呼び出し、動作を確認できます。

curl -XPOST "http://lambda:8080/2015-03-31/functions/function/invocations" -d @./tests/data/s3_event.json 

まとめ

VSCode Remote Containerの設定が若干面倒ですが、環境構築とテストを実行するまでができました。
また、Lambdaのコンテナイメージを使ってローカルでLambdaの実行ができました。
今までもSAMなどを使えばできたのですが、コンテナを使って環境をセットアップできるのでコンテナを普段使いしている場合には馴染みやすいのではないかと思います。
Pipenvを入れるかどうかはお好みで。Pipenvで環境が複雑になっている気がしています。

参考

Pythonのコードは以下を参考にさせて頂きました
tf-serverless/aws at main · tosh223/tf-serverless · GitHub