背景
Lambda関数でS3のファイルをSFTPサーバへ転送したいです。調べたところ、paramikoライブラリーの利用を決めたより、Lambdaのparamikoレイヤーを作成する必要があります。
現象
requestsライブラリーなどのレイヤーを作成した方法のように、「pip install paramiko .
」コマンドを使って、ライブラリーをインストールして、Zipファイルを圧縮して、レイヤーを作成しても、関数でparamikoを使う時にエラーになります。
原因を推測すると、paramiko自分自身の依頼が複雑で依頼しているライブラリーはLambdaの後ろに存在するEC2サーバ上にはインストールしてないかと思っていますね。なせならば、コマンドを実行する端末環境はLambda後ろのEC2サーバと違うでしょう。
解決方法
1、ローカルにDocker をインストールする
Docker Download and installを参照してください
2、適切なディレクトリ構造を作成する
①下記のフォルダ構成を作る
もし複数なランタイムの互換性が必要であればpython3.6
などのフォルダーも作成して、ライブラリーのインストールコマンドを実行してください
├── requirements.txt
└── python/
└── lib/
##├── python3.6/
##│ └── site-packages/
└── python3.9/
└── site-packages/
②requirements.txtにライブラリーを記入する
バージョンをしてしないままであればランタイムにてサポートしている最新のバージョンをインストールされます。もしバージョンをしていた場合 Requirements File Format を参照してください
paramiko
3、ライブラリインストールコマンドを実行する
①ライブラリーをインストールする
下記のコマンドを実行すると、PythonランタイムバージョンによりDockerイマージがダウンロードして起動します、そしてparamiko
ライブラリーをフォルダーインストールされます。
docker run -v "$PWD":/var/task "public.ecr.aws/sam/build-python3.9" /bin/sh -c "pip install -r requirements.txt -t python/lib/python3.9/site-packages/; exit"
②Zipファイルを作成する
zip -r paramiko-layer.zip python > /dev/null
4、Lambdaレイヤーを作成する
マネージメントコンソール或いはCLIでLambdaレイヤーを作成します。
aws lambda publish-layer-version --layer-name paramiko-layer --description "Paramiko layer libs." --zip-file fileb://paramiko-layer.zip --compatible-architectures "arm64" --compatible-runtimes "python3.9" #"python3.6"
注意点
自分がM1チップのMacbookPro端末しか持っていません、なので「Mac with Apple chip」のDockerしかインストールできません。
paramikoレイヤーを作成した時、アーキテクチャはx86_64
に指定すると関数を実行したらエラーになりました。レイヤーをarm64
に指定しても関数をx86_64
に指定したらエラーになりました。
要は、Dockerのアーキテクチャ、Lambdaレイヤーのアーキテクチャ、関数のアーキテクチャがイコールの必要があります。
他の方法
上記の方法がおすすめなんですが、AWSオフィシャルではAWS CLIコマンドでレイヤーを作成する方法もあります。カスタマイズなどが上記の方法よりは弱いと言われますが、一旦試て作成ができました。
1、AWS SAMをインストールする
①aws samをインストールする
brew tap aws/tap
brew install aws-sam-cli
②インストールを検証する
sam --version
SAM CLI, version 1.46.0
2、適切なディレクトリ構造を作成する
①下記のフォルダー構成を作成してrequirements.txt
に上記と同じ方法でライブラリー名を記入する。
├── paramiko-layer
│ └── requirements.txt
└── template.yaml
②templateファイルを下記の内容を記入する
Resources:
ParamikoLayer:
Type: AWS::Serverless::LayerVersion
Properties:
ContentUri: 'my_layer/'
CompatibleRuntimes:
- python3.9
CompatibleArchitectures:
- arm64
Metadata:
BuildMethod: python3.9
3、レイヤー作成コマンドを実行する
sam build ParamikoLayer
下記のようなアウトプットがあれば作成成功です。
Building layer 'ParamikoLayer'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch
[*] Deploy: sam deploy --guided
Zipファイルの作りや、Lambdaレイヤーの作成などは上記と同じです。