経緯
起こった問題
CDKでLambdaを構築していて、その際に必要なパッケージはrequirements.txtなどにまとめてローカルでzip化してレイヤーとして渡していた。
しかしpandasなどの一部のライブラリはOSによる環境依存の影響を受ける。
例えば私はMacOSを利用しているが、Macでpandasをインストールしても実際にそれを使いたいLambdaはAmazon LinuxをOSとしているため、互換性がなく動作しない。pandasみたいなこういうライブラリがたまにあるので対応が必要。
解決方法
解決方法としてはいくつかあり、
- Dockerを使ってLambda環境を立ち上げ、その中でライブラリをインストールしてレイヤーとして渡す
- すでに公開されているレイヤーを利用する
などが思いつく。
信頼できるレイヤーがすでに存在しているのであればこれを使うのが一番楽なので、今回は後者の方法でレイヤーを定義する。マネコンで設定する方法は記事がすでにいくつ公開されていたので、CDKで実装する方法を紹介する。
動作環境
- CDK 2.93.0
- Python 3.10
LambdaレイヤーのARNを取得
今回は良く使われているKlayersのレイヤーを使わせていただきます。
GitHubで公開されているのでこちらにアクセスして、使いたいライブラリが入っているレイヤーのARNがあるかを確認する。
CDKで定義
import * as lambda from "aws-cdk-lib/aws-lambda";
...
// Lambdaの定義
const sampleFunction = new lambda.Function(this, "sampleFunction", {
runtime: lambda.Runtime.PYTHON_3_10,
code: lambda.Code.fromAsset(path.join(__dirname, "../lambda")),
handler: "app.handler",
layers: [
customLayer, // ←他に定義するレイヤーがあれば
// pandas2.1.1のレイヤーを追加 ここから
lambda.LayerVersion.fromLayerVersionArn(
this, "KlayersPandasLayer", "arn:aws:lambda:ap-northeast-1:xxxxxxxx:layer:Klayers-p310-pandas:6"
)
// ここまで
],
vpc: props.vpc,
securityGroups: [props.securityGroup],
timeout: Duration.seconds(300),
memorySize: props.envConfig.lambdaMemorySize,
});
fromLayerVersionArnの第3引数に先ほど確認したARNを入れるだけ。
上記のようにFunctionメソッドのlayersパラメーターの配列の中に直接入れてもいいし、先に定義してから追加してもいい。後者の方がスッキリして見やすいかも?
結論
Klayersありがとうございます