【AWS】AWS Lambdaで外部モジュール(ライブラリ)を含むPythonをzipデブロイする方法

背景

  • AWS LambdaPythonを実行する際、pandasなどの外部ライブラリはLambdaに事前にinstallされていないため、いずれかの方法でLambdaに外部ライブラリ等をinstallさせる必要があります。
  • 私が知る限りでは、AWS LambdaPythonを実行する際に、外部ライブラリを使用できるようにする方法は以下の3つです。
    1. Lambda レイヤーを使用する方法。
    2. zip デブロイを用いる方法。
    3. コンテナイメージデブロイを用いる方法。
  • それぞれの方法にメリット・デメリットがありますが、今回は、最もよく使用されているであろう「 2. zip デブロイを用いる方法。」についてご紹介します。

目標

  • 外部ライブラリを含むPython codezipデブロイ方式によって、AWS Lambdaで関数を実行できるようになる。

AWS Lambdaとは

  • 本題に入る前に、AWS Lambdaというサービスについて少しご紹介します。
  • なお、ここの解説は私の脳みその記憶ベースで記載していることにご留意ください。
  • AWS LambdaはAWSの代表的なサーバーレスサービスの一つで、サーバーを構築することなく手軽にプログラムを動かすことができるサービスとして知られています。
  • 様々な用途に使用できるサービスですが、よく使用される方法の一つとしては、Amazon API GatewayをトリガーとしてAPIサービスを構築するのに使用されたりします。
  • APIなどの必要な時にちょっことプログラムが動けば良いようなサービスの場合は、AWS Lambdaを使用することにより、Amazon EC2などを使用してずっとサーバーを起動させているよりサーバーコストが安くなるなどのメリットがあります。
  • また、今回の内容につながりますが、AWS Lambdaを支える裏側の技術はコンテナ仮想化技術を使用しています。
  • そのため、実行時におそらくAmazon linuxをベースとしたイメージを用いたコンテナで処理が実行されているため、外部ライブラリを使用する際は何かしらの方法で外部ライブラリデータをAWS Lambdaに渡す必要があります。
  • 今回ご紹介する方法は、zipファイルに外部ライブラリのデータも含ませておくことにより、Python関数で外部ライブラリ等もimportして使用できるようにする方法になります。

デブロイするzipファイルを作成するDocker環境の構築

  • 今回のデブロイ方法は、AWSのLambda公式ページでは.zip ファイルアーカイブで Python Lambda 関数をデプロイするのページの「依存関係のあるデプロイパッケージ」の項目に該当します。
  • 公式ページでは、ローカル環境でzipファイルを作成していましたが、私はDocker信者(Dockerならどんな環境でも動くから安心と信じてるマン、私の造語です。)ですので、今回はDockerzipファイルを作成する環境作成からご紹介します。
  • 下記のgithubリポジトリをクーロンもしくはDLしていただき、$docker-compose up --buildPythonを実行できるコンテナを立ち上げます。
GitHub - takuma-competition/docker-python-lambda-zip-use
Contribute to takuma-competition/docker-python-lambda-zip-use development by creating an account on GitHub.

VS Codeを使用してDocker環境でデブロイ用のzipファイルを作成する方法

  • コンテナに接続したVS Codeでターミナルを開きます。

01_0047_lambda_zip.png

  • $cd workdirworkdirディレクトリに移動します。

02_0047_lambda_zip.png

  • $mkdirコマンドで、新しいディレクトリを作成します。
$mkdir zip_lambda_deploy
  • $cdコマンドで、新しいディレクトリに移動します。
$cd zip_lambda_deploy
  • $touchコマンドで新しいpyファイルを作成します。
$touch lambda_function.py
  • $touchコマンドで新しいtxtファイルを作成します。
$touch requirements.txt
  • lambda_function.pyに以下のcodeを記載します。
#はじめにimportの検索pathを追加するcodeを記載する。
import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), './packages'))

import requests
def lambda_handler(event, context):   
    response = requests.get("https://www.example.com/")
    print(response.text)
    return response.text
  • ここまでのコマンドとlambda_function.pyを記載したVS Code画面
    03_0047_lambda_zip.png

  • requirements.txtに必要な外部ライブラリ名を記載します。<br>
    ここでは、requestsが必要なので、requestsを記載しています。

requests==2.28.2
  • 必要なライブラリをpipinstallします。
#requirements.txtを使用して一気にinstall
$pip install --target ./packages -r requirements.txt

#補足:ライブラリ名を個別に指定してinstallする方法
$pip install --target ./packages requests
  • zipコマンドでライブラリごとzip化します。
$zip -r ../zip_lambda_deploy .

04_0047_lambda_zip.png

Lmabdaにzipデブロイを行う方法

  • 最後に作成したzipファイルをLmabdaにデブロイします。

AWSのコンソール画面から「Lmabda」のコンソール画面に移動します。

05_0047_lambda_zip.png

サイドバーから「関数」をクリックしてから、「関数の作成」をクリックします。

  • 「関数」ボタンが表示されていない場合は、左側の3本のバーをクリックしてくるとサイドバーが表示されます。
    06_0047_lambda_zip.png

Lmabda関数を「一から作成」で作成します。

  1. ここでは、「関数名」はzip_lambdaとします。
  2. 「ランタイム」はPython3.9を選択します。
  3. 「アーキテクチャ」はzipファイルを作成した環境に合わせて選択してください。<br>
    なお、docker-python-lambda-zip-useからクローンしたdockerfileを用いて、ここまで解説通りに進めてきた方はx86_64を選択して進めてください。
    07_0047_lambda_zip.png

「アップロード元」をクリックし、選択肢から「.zipファイル」を選択します。

08_0047_lambda_zip.png

「アップロード」をクリックし、先ほど作成したzip_lambda_deploy.zipを選択し「保存」をクリックしてzipファイルをLambdaにアップロードします。

09_0047_lambda_zip.png

「テスト」タブをクリックします。

10_0047_lambda_zip.png

「テスト」をクリックしLmabda関数を実行します。

11_0047_lambda_zip.png

「詳細」を開き、ログにHTMLが記載されていれば成功です。

12_0047_lambda_zip.png

参考資料

AWS Lambda(イベント発生時にコードを実行)| AWS
AWS Lambda を使用すれば、サーバーのプロビジョニングや管理なしでコードを実行できます。課金は実際に使用したコンピューティング時間に対してのみ発生し、コードが実行されていないときには料金も発生しません。
pandas - Python Data Analysis Library
AWS Lambda(イベント発生時にコードを実行)| AWS
AWS Lambda を使用すれば、サーバーのプロビジョニングや管理なしでコードを実行できます。課金は実際に使用したコンピューティング時間に対してのみ発生し、コードが実行されていないときには料金も発生しません。
Lambda 関数でのレイヤーの使用 - AWS Lambda
Lambda レイヤーを使用してデプロイパッケージのサイズを縮小し、関数間でコードを共有します。
.zip ファイルアーカイブで Python Lambda 関数をデプロイする - AWS Lambda
.zip ファイルデプロイパッケージを使用して Python Lambda 関数コードをデプロイする方法を学びます。
コンテナイメージで Python Lambda 関数をデプロイする - AWS Lambda
AWS から提供されたベースイメージまたはランタイムインターフェイスクライアントを使用して、Python Lambda 関数コードをコンテナーイメージとしてデプロイします。
Amazon API Gateway(規模に応じた API の作成、維持、保護)| AWS
Amazon API Gateway は、数回クリックするだけで、簡単に API の作成、配布、保守、監視、保護が行えるフルマネージドなサービスです。どのようなスケールにも対応するパフォーマンスを低コストでご利用いただけます。
Amazon EC2(安全でスケーラブルなクラウド上の仮想サーバー)| AWS
サーバーのサイズ変更を安価かつ柔軟に行うことができる Amazon Elastic Compute Cloud (EC) は、クラウド上で仮想サーバーを提供し、幅広い性能のコンピューティング環境を実現します。

Qiita記事

【Python】PandasのDataFrameで、周波数(Hz)から時系列のindexを作る方法(pandas.date_range) - Qiita
背景加速度センサーなど、物理データの測定機器などでは測定間隔が周波数(Hz)で定義されていることが多くあります。センサーにもよるが、出力データに時系列のindexがついていない場合もままあります。…