AWS Lambdaのレイヤーとは?
概要
AWS Lambdaを利用しているといろいろなライブラリを使いたいと思うことがあると思います。しかしLambdaはデフォルトのままではLambdaのランタイムにインストールされているライブラリしか用いることができません。その問題を解決するのがAWS Lambdaのレイヤーです。レイヤーはLambda関数で利用できる共有ライブラリや依存関係、カスタムランタイムなどを提供するための機能です。
レイヤーを使用することで、共通のコードや依存関係を一元化し、Lambda関数の構造をシンプルにし、開発と運用の効率を向上させることができます。例えばPythonでデータ操作を共通化したいと考えたとき、「NumPy」や「Pandas」などの標準外のライブラリをレイヤーとして作成し複数のLambda関数で共有することができます。これによりLambda関数ごとにライブラリをパッケージ化する手間を省け、簡単に標準外ライブラリを利用できます。
このレイヤーを作成するには、LinuxやDockerを利用してzipを作成する方法があります。しかしこの方法ではレイヤーの作成が複雑で、バージョン管理やメンテナンスもしづらくなってしまいがちです。公式ドキュメントにレイヤー作成手順が掲載されていますが、なにやら面倒そうですよね。
そこで本記事ではAWS SAMを利用します。SAMの詳細は下記の記事で説明していますが、ざっくり言うとSAMはLambdaを効率よく開発する機能でレイヤーの作成も気軽にできます。本記事ではSAMを利用したレイヤーの作成を解説します。
レイヤーの追加方法
レイヤーを追加する方法はインストールしたい関連のファイル群(パッケージやバイナリなど)をzipにして配置する方法(配置先はS3、SAMプロジェクト、Lambdaのマネジメントコンソール)とrequirements.txtを利用する方法の2つがあります。前者は依存関係を正しく理解してzipファイルを作成する必要があり、難易度は高めです。そこで今回は後者のrequirements.txtを利用する方法を紹介します!
レイヤーの構造
レイヤーを正しく動作させる上でLambdaランタイムのレイヤーパスを正しく理解することが重要です。公式ドキュメントを確認するとPythonの場合は下記がレイヤーパスとして指定されています。なおAWS SAMを利用したライブラリを追加した場合、2つ目の/opt/python/lib/python3.8/site-packages
に配置されることになります。
- /opt/python:
- 主にカスタムモジュールやスクリプトを配置します。
- Pythonの標準モジュールパスに追加されるため、import時にモジュール名だけで参照できます。
- /opt/python/lib/python3.x/site-packages:
- python3.xはLambda作成時のPythonのバージョンになります。
- サードパーティライブラリや標準パッケージを配置します。
- Pythonの標準ライブラリパスに配置されるため、通常のPythonのライブラリと同じ方法でimportできます。
AWS SAMによるレイヤー設定
前提
Cloud9(OSはubuntu 22.04 LTS、インスタンスタイプはt2.micro、dockerがインストール済)
Lambdaランタイム(Python3.12)
プロジェクトの初期化
Cloud9でsam init
よりhello worldをテンプレートとしたsam-app
プロジェクトを作成し、template.yamlからEventsとOutputsエントリに関わる記述を削除します。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for sam-app
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 3
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.12
Architectures:
- x86_64
詳細については過去記事にAWS SAMのプロジェクト初期化の方法を解説していますので参考にしてください。こちらの記事のLambda関数とyamlの編集
まで構築が終わりましたら次の手順に進んでください。
ディレクトリとrequirements.txtの作成
さっそくレイヤーを作成していきましょう。今回はデータ分析でよく利用されるNumpyを追加していきます。
まずはレイヤーを管理するディレクトリとファイルを作成します。下のコマンドの1行目から4行目を参考にnumpy_layerディレクトリとrequirements.txtを作成します。正常に作成できると16行目、17行目のようにディレクトリとその直下にrequirements.txtが作成されます。
cd sam-app
mkdir numpy_layer
cd numpy_layer
touch requirements.txt
tree sam-app
sam-app/
├── README.md
├── __init__.py
├── events
│ └── event.json
├── hello_world
│ ├── __init__.py
│ ├── app.py
│ └── requirements.txt
├── numpy_layer
│ └── requirements.txt
├── samconfig.toml
├── template.yaml
└── tests
├── __init__.py
├── integration
│ ├── __init__.py
│ └── test_api_gateway.py
├── requirements.txt
└── unit
├── __init__.py
└── test_handler.py
続いてpythonでインストールするライブラリを管理するためのファイルであるrequirements.txtを編集します。17行目のファイルを開き、numpy
と記述するだけです。ちなみに15行目にもrequirements.txtがありますが、間違えないようにしてくださいね。15行目のrequirements.txtはLambda関数のランタイムに直接ライブラリをインストールしたい場合に利用します。
vi requirements.txt
numpy
app.pyの編集
続いてapp.pyの編集をしてnumpyの動作を確かめるコードを記述します。2行目にnumpyのインポート文を、9~10行目にnumpyを利用した行列の定義とその表示処理を記述します。
import json
import numpy as np
def lambda_handler(event, context):
print('hello sam')
print(json.dumps(event))
# 行列の定義と表示
mat = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(mat)
template.ymlの編集
最後にtemplate.ymlを編集します。ここでは11行目で念のためにTimeoutを60秒に修正、22~23行目でLambdaとLayerの対応付けを追記、25~32行目でLayer自体の設定を追記します。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for sam-app
Globals:
Function:
Timeout: 60
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.12
Architectures:
- x86_64
Layers:
- !Ref NumpyLayer
NumpyLayer:
Type: AWS::Serverless::LayerVersion
Properties:
ContentUri: 'numpy_layer/'
CompatibleRuntimes:
- python3.12
Metadata:
BuildMethod: python3.12
動作確認
ここまで記述の修正は完了したので最後にビルド&デプロイでLambda関数を作成していきます。まずは下記のコマンドを実行します。
sam build -u
sam deploy
Deploy this changeset? [y/N]: y
Lambdaのコンソールマネジメントを確認すると下図のようにsam-appで作られたLambdaが存在していることがわかります。さらにLayerをクリックすると今回作成したNumpyLayerが設定されていることもわかります。
そしてこの関数をテスト実行すると下図のように出力結果に行列の表示が確認できます。ここまでできると後は好きなライブラリrequirements.txtに追記するだけで外部ライブラリを簡単に追加することができます!
最後に作成したLambda関数を削除したい場合は下記のコマンドで削除ください。
sam delete
Are you sure you want to delete the stack sam-app in the region us-east-1 ? [y/N]: y
Do you want to delete the template file 1919fadd17425ffb833b1e2a25aacea1.template in S3? [y/N]: y
まとめ
今回の記事ではAWS SAMを利用したレイヤーの追加について解説しました。今までzipを作成して設定していた方からするととても簡単に感じたのではないかと思います。AWS SAMの少ない学習コストでLambda開発効率がアップしますのでぜひ試してみてくださいね!