LoginSignup
111
90

More than 3 years have passed since last update.

AWS Lambda x Pythonでのローカル開発環境の再現について

Last updated at Posted at 2018-10-30

AWS Lambdaを使ってなにかを作るとき(Python)についての考察です。

■ Overview

  • AWS LambdaとPythonを使って開発するときにローカル環境をどう作っていくかについて。
  • AWS Lambdaをローカルで再現する手段

■ 問題点

  • AWS LambdaとPythonで開発する際に、モジュールなどのインポートする際に依存関係があるとLambdaのGUI上ではそのまま実行できないため、一度他の場所で依存関係をインストールしてzip化してアップロードするケースが多い。
  • スクリーンショット 2018-10-30 17.18.41.png

ただ、その都度変更があるためにzip化してアップロードするのは大変。すぐに反映を確認できないと開発効率がさがってしまう。
image.png

■ 解決策

主に2つあります。

① EC2 or AmazonLinux for Dockerを使い開発する

Lambdaは、AmazonLinuxで動いているためローカルPCでローカル開発環境を準備して開発し、それをzip化アップロードしても失敗するケースがあります。
なので、他に環境を用意する必要があります。方法は2つあり
- EC2インスタンスを立ててその中で開発する。
- AmazonLinuxの公式Dockerイメージの中で開発を行う。

image.png

前者のEC2を立てるのは、あまりスマートではなくコストもかかるのでおすすめできません。
AmazonLinuxの公式Dockerについては、その中で開発を行え常にクリーンな環境を保てます。

$ docker pull amazonlinux

② docker-lambdaを利用する

個人的には、こちらが一番良いかと思います。

https://github.com/lambci/docker-lambda

docker-lambdaを文字通り、AWS Lambdaの環境を再現したDockerイメージです。
これを使い、Dockerfileをビルドしてアップロードすればかなりよい環境ができあがります。AmazonLinuxのDockerイメージでもよいのですが、こちらのdocker-lambdaのほうがはじめからLambdaを再現できているので余計なことをせずに簡単です。
image.png

■ docker-lambdaを触ってみる

簡単ではありますが、サンプルをbuildするまで行ってみます。

まずは、DockerfileをビルドするのではなくCLIからイメージをrunして動作確認してみます。

公式のlambci/docker-lambdaリポジトリを参考にしていきます。

lambda_function.pyを用意する。

AWS Lambdaではデフォールトでlambda_function.pyのlambda_handlerを呼び出すようになっているので今回も従っていきます・

lambda_function.py
import json

def lambda_handler(event, context):
    return event

docker-lambdaを実行していきます。

$ docker run -v "$PWD":/var/task lambci/lambda:python3.6 lambda_function.lambda_handler '{"Hello":"World"}'
Unable to find image 'lambci/lambda:python3.6' locally
python3.6: Pulling from lambci/lambda
5be106c3813f: Pull complete 
e240967675e1: Pull complete 
4ec29390cd9b: Pull complete 
fc6ba7ddc407: Pull complete 
492c7fb9ab78: Pull complete 
Digest: sha256:6a5cddcf16942a7a3ddc209f140a8d4105a87ce95cd374ffc6d953dd0b593d01
Status: Downloaded newer image for lambci/lambda:python3.6
START RequestId: 3f39da27-a241-4fd2-ad77-e92ec63ffada Version: $LATEST
END RequestId: 3f39da27-a241-4fd2-ad77-e92ec63ffada
REPORT RequestId: 3f39da27-a241-4fd2-ad77-e92ec63ffada Duration: 12 ms Billed Duration: 100 ms Memory Size: 1536 MB Max Memory Used: 19 MB

{"Hello": "World"}

単純にJSONも文字列を渡して出力しているだけですが、無事に『{"Hello": "World"}』がでました。

ビルドイメージをDockerfileに書いていく。

では、ここでビルド用のDockerfileを書いていきます。
内容としては、上記のlambda_function.pyと依存関係をzip化し、デプロイパッケージを作成していきます。
デプロイパッケージの作成

ビルド準備として、requirements.txtというテキストを用意しそこに依存するインポート群を書いていきます。

requirements.txt
requests

再度、requestsモジュールを使ったlambda_function.pyを用意します。DMM.comにアクセスしてstatus_code : 200を返すスクリプトです。

lambda_function.py
import requests

def lambda_handler(event, context):
    res = requests.get('https://www.dmm.com/')
    return res.status_code 

では、ビルドしていきます。

Dockerfile
FROM lambci/lambda:build-python3.6
ENV AWS_DEFAULT_REGION ap-northeast-1

ADD . .

CMD pip3 install -r requirements.txt -t /var/task && \
  zip -9 deploy_package.zip lambda_function.py && \
  zip -r9 deploy_package.zip *

まずは、イメージを作成します。

$ docker build -t mylambda .
イメージ確認
$ docker images 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mylambda            latest              14a0a97cd00a        5 minutes ago       1.8GB
lambci/lambda       build-python3.6     0f6150a9635c        7 days ago          1.8GB

ではZipに固めていきます。

build
$ docker run -v "$PWD":/var/task mylambda
Collecting requests (from -r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/f1/ca/10332a30cb25b627192b4ea272c351bce3ca1091e541245cccbace6051d8/requests-2.20.0-py2.py3-none-any.whl (60kB)

~中略~

結果として、以下のようなディレクト構造ができます。deploy_package.zipがアップロード対象のフォルダーです。

ls -a
.               certifi             deploy_package.zip      requests            urllib3-1.24.dist-info
..              certifi-2018.10.15.dist-info    idna                requests-2.20.0.dist-info
Dockerfile          chardet             idna-2.7.dist-info      requirements.txt
bin             chardet-3.0.4.dist-info     lambda_function.py      urllib3

結果
Lambda上で、deploy_package.zipをzipアップロードすると結果として200が返ってきており、正しく動作していることがわかります。
スクリーンショット 2018-10-30 18.25.13.png

基本的にアップロードをローカルで検証できたらで良くて、普段はコンテナ内や引数でpythonを実行して動作確認するのがよさそうです。

以上です。

111
90
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
111
90