Lambda関数をコンテナイメージで動かしてみた


はじめに

この記事は BeeX Advent Calendar 2020 の12/6の記事です。

==

今年のre:InventでLambdaがコンテナイメージをサポートしたと発表がありました。

前に以下の記事で書きましたが、Lambdaで外部ライブラリを使用したい場合はLambda Layerに別途アップロードが必要でした。
今回発表されたコンテナを使うことで、その部分が簡略化できないか試してみます。
Lambda Layerに外部のライブラリをアップロードする

尚、Dockerはほとんど使ったことないので初心者レベルです。

環境

PC:Windows 10
Docker:Docker version 19.03.13, build 4484c46d9d

前提

  • Dockerの初期設定は完了済み
  • Python3はインストール済み(Lambdaランタイムと同じかそれ以上)
  • AWSアカウントは作成済み
  • Amazon ECRリポジトリは未作成

実際の操作

requirements.txtファイルの作成

ローカルで以下のコマンドを実行し、requirements.txtファイルを作成します。

$ pip install dataclasses==0.6
$ pip install dataclasses_json==0.5.2
$ pip freeze > requirements.txt

lambda functionの作成

作成済みのLambdaからコードをコピーし、ローカルに作成します。

lambda_function.py
import json
from dataclasses import dataclass
from dataclasses_json import dataclass_json

@dataclass_json
@dataclass
class TestColumns:
    column1: str = None
    column2: str = None
    column3: str = None

def exec_function(event):
    column_list = TestColumns()
    column_list.column1 = "hoge"
    column_list.column2 = "huga"
    column_list.column3 = "hogehuga"

    print(column_list)
    column_list_json = column_list.to_json(indent=4)
    print(column_list_json)

def lambda_handler(event, context):
    exec_function(event)

DockerFileの作成

次にDockerFileを作成します。
イメージは公式が提供しているものを使用しています。
※DockerfileのFが大文字になってて地味に引っかかりました

FROM amazon/aws-lambda-python:3.7

COPY requirements.txt lambda_function.py ./
RUN pip install --no-cache-dir -r requirements.txt

CMD [ "lambda_function.lambda_handler" ]

イメージをBuildする

以下のコマンドを実行して、イメージをビルドします。

$ cd [DockerFile格納先DIR]
$ docker build -t lambda-container-dataclass .

イメージが作成されたことを確認します。

$ docker images
REPOSITORY                                     TAG                 IMAGE ID            CREATED             SIZE
lambda-container-dataclass                     latest              0655a0bf775a        40 seconds ago      892MB

ECRリポジトリへのPush

AWSコンソールからECRリポジトリを作成します。

以下のコマンドで作成したECRリポジトリにイメージをPushします。

$ docker tag lambda-container-dataclass:latest XXXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-container-dataclass
$ docker images
REPOSITORY                                                                     TAG                 IMAGE ID            CREATED             SIZE
XXXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-container-dataclass   latest              0655a0bf775a        41 minutes ago      892MB
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin XXXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com
Login Succeeded
$ docker push XXXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-container-dataclass:latest
The push refers to repository [XXXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-container-dataclass]
2cbe32b34b1c: Pushed
1f6657a679d9: Pushed
069cd8bd11dd: Pushed
6e191121f7ea: Pushed
d6fa53d6caa6: Pushed
1fb474cee41c: Pushed
b1754cf6954d: Pushed
464c816a7003: Pushed
latest: digest: sha256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX size: 1997

無事にアップロードできました。

Lambda作成・実行

Lambda関数の作成からコンテナイメージを選択します。

先ほどPushしたECRのイメージを選択します。

今回は実行ロールを新しく作成するように選択して、関数の作成を実行します。

Lambdaが作成されました。

今までコードが表示されていた部分はイメージに変わっています。それ以外は特に変更なさそうです。

実行結果確認

コンソールから実行したところ、問題なく正常終了しました。

出力内容も問題なさそうです。

START RequestId: 62d1c78f-b14a-4358-babc-e24a1ededcab Version: $LATEST
TestColumns(column1='hoge', column2='huga', column3='hogehuga')
{
    "column1": "hoge",
    "column2": "huga",
    "column3": "hogehuga"
}
END RequestId: 62d1c78f-b14a-4358-babc-e24a1ededcab
REPORT RequestId: 62d1c78f-b14a-4358-babc-e24a1ededcab  Duration: 18.50 ms  Billed Duration: 1007 ms    Memory Size: 128 MB Max Memory Used: 52 MB  Init Duration: 987.64 ms    

元々のLambda関数で出力した内容と見比べても特に差分はないので大丈夫そうです。

START RequestId: 6054e059-68ca-451f-a4f1-13804f24b8d8 Version: $LATEST
TestColumns(column1='hoge', column2='huga', column3='hogehuga')
{
    "column1": "hoge",
    "column2": "huga",
    "column3": "hogehuga"
}
END RequestId: 6054e059-68ca-451f-a4f1-13804f24b8d8
REPORT RequestId: 6054e059-68ca-451f-a4f1-13804f24b8d8  Duration: 1.72 ms   Billed Duration: 2 ms   Memory Size: 128 MB Max Memory Used: 54 MB  Init Duration: 194.92 ms    

さいごに

ということで、今まで外部レイヤー追加したりSAMで設定したりしていましたが、今回のコンテナを活用することでデプロイをシンプルにLambdaを実行することができました。

ローカルでの開発もしやすくなると思いますし、今後どんどん使われる機能ではないかと思います。

参考