14
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Lambda Layersで自作モジュールを共通ライブラリ化する [Python,Node.js]

Last updated at Posted at 2022-01-30

はじめに

Lambda Layersを用いることで、モジュールを共通ライブラリとして、複数のLambdaで使用できるようなので、PythonとNode.jsのパターンで方法をまとめます。

メリットとして、Lambdaのソースコードの量を減らすことができること、各Lambdaごとにモジュールをアップする手間がなくなることがあげられます。

Lambda Layersについて

Lambda レイヤーは、追加のコードやデータを含めることができる .zip ファイルアーカイブです。レイヤーには、ライブラリ、 カスタムランタイム 、データ、または設定ファイルを含めることができます。レイヤーを使用すると、コードの共有と責任の分離を促進し、ビジネスロジックの記述をより迅速に繰り返すことができます。

自作モジュールのディレクトリ構造

Lambda Layersにアップロードされたモジュールは、/optの領域に展開されます。
そのため、指定されたディレクトリ(下記の表参照)にPythonモジュールを格納してアップロードすることでLambdaを実行した際にモジュールとして自動的に読み込むことができます。

各 Lambda ランタイムのレイヤーパス

言語 パス
Node.js nodejs/node_modules
nodejs/node14/node_modules (NODE_PATH)
Python python
python/lib/python3.9/site-packages (サイトディレクトリ)

モジュールを作成 [Node.js]

today.js
module.exports = () => {
  const dateUTC = new Date();

  // JSTに変更後、タイムスタンプに変える
  const dateJST = new Date(dateUTC.getTime() + 32400000);

  // タイムスタンプを日付の年月日に変える。時間は切り捨て
  let year = dateJST.getFullYear();
  let month = dateJST.getMonth() + 1;
  let day = dateJST.getDate();

  // 値が1桁であれば '0'を追加
  if (month < 10) month = '0' + month;
  if (day < 10) day = '0' + day;

  //"2022-01-16"
  const result = year + '-' + month + '-' + day;

  return result;
};
day_after
module.exports = (days_after_number) => {
  const dateUTC = new Date();
  // days_after_number日分、進める
  const days_after_UTC = new Date().setDate(
    dateUTC.getDate() + days_after_number
  );

  const days_after_JST = new Date(days_after_UTC + 32400000);

  let days_after_year = days_after_JST.getFullYear();
  let days_after_month = days_after_JST.getMonth() + 1;
  let days_after_day = days_after_JST.getDate();

  if (days_after_month < 10) days_after_month = '0' + days_after_month;
  if (days_after_day < 10) days_after_day = '0' + days_after_day;

  const result =
    days_after_year + '-' + days_after_month + '-' + days_after_day;

  return result;
};

上記の2つのファイルを自作モジュールとして使用します。
ローカルで、ディレクトリを作成し、モジュールファイルを入れて、zip化します。

$ mkdir nodejs             
$ cd nodejs 
$ mkdir node_modules
$ cd node_modules 
$ pwd
/nodejs/node_modules

node_modulesディレクトリ内に、today.jsdays_after.jsを入れます。

nodejs
└── node_modules
    ├── days_after.js
    └── today.js

zip化します。zip名は何でも良いですが今回は、nodejs_layerという名前でzip化します。

$ zip -r nodejs_layer nodejs

モジュールを作成 [Python]

pythonの方は、複数のロジックを1つのファイルにまとめることができます。

python_layer.py
from datetime import datetime, timedelta
import boto3

# Method

def today():
    # 2022-01-16 20:54:05.134159
    dateJST = datetime.today() + timedelta(hours=9)
    # 2022-01-16
    return dateJST.strftime("%F")

def days_after(days_after_number):
    dateJST = datetime.today() + timedelta(hours=9)
    days_after_JST = dateJST + timedelta(days=days_after_number)

    return days_after_JST.strftime("%F")

# Table
dynamodb = boto3.resource('dynamodb')
dynamodb_table = dynamodb.Table("users")

# Constant
TYPE = 'all'

$ mkdir python             
python
└── python_layer.py

zip化します。python_layerという名前でzip化します。

$ zip -r python_layer python

Lambda Layerにアップロード[Python,Node.js共通]

レイヤーの作成をクリックします。
スクリーンショット 2022-01-30 10.10.04.png
互換性のあるランタイムは、作成したLayerと同じ言語を指定します。
zip化したファイルをアップロードし、作成をクリックします

スクリーンショット 2022-01-30 10.16.13.png

Lambdaの最下部のレイヤーを追加をクリックします。
スクリーンショット 2022-01-30 10.17.42.png
カスタムレイヤーから選択し、追加します。
スクリーンショット 2022-01-30 10.19.55.png

Lambda Layerの呼び出し方法[Node.js]

メソッド

lambda
exports.handler = async (event) => {
  // Layerを使って共通ライブラリ化
  const today = require("today");
  const days_after = require("days_after");
  
  console.log("本日:" + today());
  console.log("3日後:" + days_after(3));
};

require("ファイル名")で呼び出せます。
実行します。

INFO	本日:2022-01-30
INFO	3日後:2022-02-02

Lambda Layerの呼び出し方法[Python]

メソッド

lambda
#python_layer.pyからLayerを使って共通ライブラリ化
from python_layer import today,days_after
# from python_layer import *

def lambda_handler(event, context):
  return (today() + "" + days_after(3))

from ファイル名 import メソッド名で呼び出せます。
また、from ファイル名 import * ファイル内のすべてのメソッドが呼び出せます。
実行します。

Response
"2022-01-30と2022-02-02"

定数

lambda
#python_layer.pyからLayerを使って共通ライブラリ化
from python_layer import TYPE

def lambda_handler(event, context):
  return TYPE
Response
"all"

Pythonの方がファイルが1つにまとめられて、よいですね。

Python外部ライブラリのLayerを使用したい場合

下記のGitHubにすでに作成されている場合、自分でモジュールをインストールしてLayerにアップする必要がありません。
記事を参考にしてください。

スクリーンショット 2022-02-19 19.41.06.png

14
13
0

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
14
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?