🗂️

AWS上でLambdaを使ってLambda Layerを作成する

2024/10/24に公開

AWS Lambda関数を開発する際、外部ライブラリを利用する場合はLambda Layerを作成して管理する必要があります。しかし、ローカル環境でLayerを作成する場合、ネットワークの状況や環境の違いによって時間がかかったり、エラーが発生することがあります。そこで、AWS上でLambdaを使って直接Layerを作成したところ、AWSの高速なネットワークにより素早く環境に左右されずにLayerを構築できました。

なぜAWS上でLayerを作成するのか

  • 高速性:AWSのインフラを利用することで、ネットワークの影響を受けずに高速にLayerを作成できます。
  • 安定性:ローカル環境の依存関係や設定に左右されず、常に一定の環境でLayerを作成できます。

全体の流れ

  1. S3バケットの作成:LayerのZIPファイルを保存するためのS3バケットを作成します。
  2. Layer作成用のLambda関数をデプロイ:指定したパッケージをインストールし、Layerを作成するLambda関数をデプロイします。
  3. Lambda関数の実行:必要なパッケージを指定してLambda関数を実行し、Layerを作成します。

プロジェクト構成

レポジトリとしてGithubにアップしています。
AWS CDK(TypeScript)を使用しており、以下のような構成になっています。

https://github.com/takoyaki-3/create-lambda-layer-on-lambda

.
├── bin
│   └── create-lambda-layer.ts
├── lambda
│   └── create_layer.py
├── lib
│   └── create-lambda-layer-stack.ts
├── cdk.json
├── package.json
└── tsconfig.json

主要なファイル

  • bin/create-lambda-layer.ts:CDKアプリのエントリーポイント。
  • lib/create-lambda-layer-stack.ts:スタックの定義。S3バケットとLambda関数を作成します。
  • lambda/create_layer.py:Layerを作成するためのLambda関数のコード。

実装のポイント

1. S3バケットの作成

const bucket = new s3.Bucket(this, 'LambdaLayerBucket', {
  removalPolicy: cdk.RemovalPolicy.DESTROY,
  autoDeleteObjects: true,
});

LayerのZIPファイルを一時的に保存するためのS3バケットを作成します。

2. Layer作成用のLambda関数

const lambdaFunction = new lambda.Function(this, 'CreateAndUploadLayerLambda', {
  runtime: lambda.Runtime.PYTHON_3_12,
  handler: 'create_layer.lambda_handler',
  code: lambda.Code.fromAsset('lambda'),
  timeout: cdk.Duration.minutes(15),
  environment: {
    BUCKET_NAME: bucket.bucketName,
  },
  memorySize: 1024,
});
  • runtime:Lambda関数の実行ランタイムを指定します。
  • handler:Lambda関数のハンドラを指定します。
  • code:関数コードの場所を指定します。
  • environment:環境変数としてS3バケット名を渡します。

3. Lambda関数の実装(create_layer.py)

def lambda_handler(event, context):
    packages = event.get("packages", [])
    if not packages:
        return {"statusCode": 400, "body": "No packages specified"}

    # パッケージのインストール
    subprocess.check_call(["pip", "install"] + packages + ["-t", site_packages_dir])

    # ZIPファイルの作成
    with zipfile.ZipFile(zip_file_path, "w") as zipf:
        # ファイルをZIPに追加
        # ...

    # S3にアップロード
    s3.upload_file(zip_file_path, bucket_name, key_name)

    # Lambda Layerの作成
    lambda_client.publish_layer_version(
        LayerName=event.get("layer_name", "custom_layer"),
        Content={"S3Bucket": bucket_name, "S3Key": key_name},
        CompatibleRuntimes=["python3.9"],
    )

    return {"statusCode": 200, "body": "Layer created successfully"}
  • パッケージのインストール:指定されたパッケージをpipでインストールします。
  • ZIPファイルの作成:インストールしたパッケージをZIPファイルにまとめます。
  • S3にアップロード:ZIPファイルをS3バケットにアップロードします。
  • Lambda Layerの作成:アップロードしたZIPファイルからLambda Layerを作成します。

手順

1. リポジトリのクローンと依存関係のインストール

git clone https://github.com/your-repo/create-lambda-layer
cd create-lambda-layer
npm install

2. CDKスタックのデプロイ

npx cdk deploy

3. Lambda関数の実行

AWSマネジメントコンソールやAWS CLIを使用して、以下のようなイベントを渡してLambda関数を実行します。

{
  "packages": ["requests", "numpy"],
  "layer_name": "custom-layer",
  "description": "Custom Lambda Layer"
}

4. 作成されたLayerの確認

Lambda関数の実行が成功すると、新しいLambda Layerが作成され、そのARNが出力されます。

{
  "statusCode": 200,
  "body": "{\"message\": \"Successfully uploaded layer.zip to createlambdalayerstack-lambdalayerbucket3217ab23-cr22zh1gux72\", \"layerVersionArn\": \"arn:aws:lambda:ap-northeast-1:211125380625:layer:gtfsrt:1\"}"
}

まとめ

AWS上でLambdaを使ってLambda Layerを作成することで、ネットワークやローカル環境に依存せずに高速かつ安定的にLayerを作成できます。

参考

詳しいコードや設定については、takoyaki-3/create-lambda-layer-on-lambdaを参照してください。

Discussion