【AWS】lambdaでparamikoを使ってSFTP通信する
投稿日:
環境
- MacBook Air M1チップ
- AWS SAM version 1.99.0
- python 3.9
手順
他サーバーよりSFTPでファイルを取得する処理を作るためにparamikoを利用します。
AWS lambdaでparamikoを利用するためにレイヤーを利用します。
lambdaのレイヤーはDockerなどを使って構築する方法もありますが
簡易に作成したかったのでAWS SAMを利用してレイヤーの作成をしました。
①AWS SAMをインストールする
Macにて以下コマンドを実行してAWS SAMをインストールします。
$ brew tap aws/tap
$ brew install aws-sam-cli
この記事を書いている時点でインストールできたのはバージョン1.99.0でした。
$ sam --version
SAM CLI, version 1.99.0
②AWS SAM用のファイルを作成する。
以下構成でファイルを作成します。
paramiko-layer
ディレクトリは変えても良いです。
(current dir)
├── paramiko-layer
│ └── requirements.txt
└── template.yaml
各ファイルの中身は以下です。
【requirements.txt】
インストールするライブラリを記載します
paramiko
【template.yaml】
ここで記載するContentUri
はrequirements.txtを配置しているディレクトリにします。
またpython3.9
、x86_64
の部分は作成するlambdaに合わせて読み替えてください。
Resources:
ParamikoLayer:
Type: AWS::Serverless::LayerVersion
Properties:
ContentUri: 'paramiko-layer/'
CompatibleRuntimes:
- python3.9
CompatibleArchitectures:
- x86_64
Metadata:
BuildMethod: python3.9
③レイヤーをビルドする
template.yamlがあるディレクトリにて以下コマンドを実行します。
ParamikoLayer
は変えても良いです。
sam build ParamikoLayer
これにより現在のディレクトリ配下に.aws-sam
ディレクトリが作成され、ビルドされたファイルができあがります。
これをCLI上のコマンドでlambdaのレイヤーにデプロイすることもできますが、今回はZIPをアップする方法でデプロイしてみます。
生成されたpythonディレクトリ配下にあるファイルを以下コマンドで圧縮します。
cd .aws-sam/build/ParamikoLayer/
zip -r paramiko-layer.zip python/*
作成したparamiko-layer.zipをAWSマネジメントコンソールでアップロードします。
lambdaのレイヤーページを開き、『レイヤーの作成』をクリックします。
以下入力して『作成』をクリックする。
項目 | 内容 |
---|---|
名前 | 任意のレイヤーの名前 |
説明 | 空で良いです。必要ならレイヤーの説明を記載してください。 |
アップロード | ラジオで『.zipファイルをアップロード』を選択し、『アップロード』よりさきほど生成したzipを選択する。 |
互換性のあるアーキテクチャ | template.yamlに記載したものと合わせてください。 |
互換性のあるランタイム | template.yamlに記載したものと合わせてください。 |
ライセンス | 空で良いです。何かしらレイヤーにライセンスをつける場合は記載してください。 |
あとはlambda関数で上記レイヤーを設定し、paramikoを利用するだけです。
実装サンプルとしては以下のようになります。
import paramiko
def lambda_handler(event, context):
sshClinet = paramiko.SSHClient()
policy = paramiko.client.MissingHostKeyPolicy()
sshClinet.set_missing_host_key_policy(policy)
sshClinet.set_missing_host_key_policy(paramiko.AutoAddPolicy())
sshClinet.connect('接続先ホスト名', '接続先ポート', '接続先ユーザー名', '接続先パスワード')
sftpClient = sshClinet.open_sftp()
sftpClient.get('取得するファイルのパスとファイル名', '接続元(lambda)の配置先パスとファイル名')
〜後続処理を記載〜