【AWS】Lambda関数でEFSにCSVファイルを生成する
※下記の内容に不備がありましたら、コメント頂けると幸いです。また、下記の内容をご使用頂ける場合は自己責任でお願いします。
概要
今年の6月にLambda関数がEFSをマウントできるようになったのは、既に皆さんは知られているかと思います。
自分は恥ずかしながらつい先日知りました←
AWSブログを参考にしてハンズオンしていたのですが、少々詰まりましたので、CSVファイル生成方法と合わせてブログにまとめます。
LambdaでEFSにCSVファイルを生成する
セキュリティグループ作成
EFSやLambda関数を作成する前に、以下のURLからセキュリティグループを作成しておきます。
https://ap-northeast-1.console.aws.amazon.com/vpc/home?region=ap-northeast-1#securityGroups:
セキュリティグループはEFS用とLambda関数用を作成します。
設定は以下の表を参考にしてください。
名前,説明,タグ | VPC | インバウンドルール | アウトバウンドルール | |
---|---|---|---|---|
Lambda関数用セキュルティグループ | 任意 | デフォルト | なし | 全てのトラフィック |
EFS用セキュリティグループ | 任意 | デフォルト | タイプ:NFS,プロトコル:TSP,ポート範囲:2049,ソース:上記Lambda用デキュリティグループ | 全てのトラフィック |
EFSファイル作成
以下のURLからEFSファイルを作成します。
https://ap-northeast-1.console.aws.amazon.com/efs/home?region=ap-northeast-1#/file-systems
設定は以下の表を参考にしてください。
カテゴリー | 値 |
---|---|
名前 | 任意 |
VPC | デフォルト |
ルートディレクトリパ | /file |
ユーザーID | 1001 |
グループID | 1001 |
所有者ユーザーID | 1001 |
所有者グループID | 1001 |
アクセス許可 | 755 |
タグ | 任意 |
マウントターゲット | 全てのアベイラビリティーゾーンのセキュリティグループを上記で作成したEFS用セキュリティグループに変更 |
Lambda関数作成
以下のURLからLambda関数を作成する。
ランタイムですが、今回はPython3.8を選択します。
https://ap-northeast-1.console.aws.amazon.com/lambda/home?region=ap-northeast-1#/functions
IAMロールにポリシーをアタッチする
Lambda関数作成時に自動的に生成されるIAMロールに、ポリシーをアタッチします。
先ほど作成したLambda関数コンソールでアクセス権限タブを選択し、実行ロールカテゴリーからIAMロールのページに移動します。
移動後のベージのアクセス権限から以下のポリシーをアタッチします。
- AmazonElasticFileSystemClientReadWriteAccess
- AWSLambdaVPCAccessExecutionRole
Lambda関数のVPCを編集
Lambda関数のコンソールからVPCを編集します。
設定は以下の表を参考にしてください。
カテゴリー | 値 |
---|---|
VPC | デフォルト |
サブネット | EFSのネットワークのサブネットを全て選択 |
セキュリティグループ | Lambda関数用のセキュリティグループを選択 |
Lambda関数にファイルシステムを追加
Lambda関数のコンソールからファイルシステムを追加します(EFSをマウントします)。
設定は以下の表を参考にしてください。
カテゴリー | 値 |
---|---|
EFSファイルシステム | 上記で作成したEFSを選択 |
アクセスポイント | 上記で作成したEFSのアクセスポイントを選択 |
マウントパス | /mnt/file |
Lambda関数をデプロイ
Lambda関数のコンソールで以下のコードの入力が終われば、デプロイをしてください。
EFSにCSVファイルを作成するコード
import os import fcntl import csv # 変数にLambda関数でマウントしたパスを格納する FILE_PATH = '/mnt/file' def lambda_handler(event, context): method = event['requestContext']['http']['method'] name = event['body'] file_path = u'%s/%s' % (FILE_PATH, name) csv_path_name = u'%s/%s.csv' % (file_path, name) try: if method == 'POST': message = add_csv(file_path, csv_path_name) elif method == 'GET': message = get_text(csv_path_name) else: message = 'not method' except: message = 'error handler' return message def add_csv(filepath, csvname): os.makedirs(filepath, exist_ok=True) try: with open(csvname, 'w') as f: fcntl.flock(f, fcntl.LOCK_EX) writer = csv.writer(f) writer.writerow(['aa', 'aa']) message = 'create csv file ' fcntl.flock(f, fcntl.LOCK_UN) except: message = 'error add_csv' return message def get_text(csvname): try: with open(csvname) as f: fcntl.flock(f, fcntl.LOCK_SH) text = f.read() fcntl.flock(f, fcntl.LOCK_UN) except: text = 'error get_text' return text
トリガーを追加
Lamda関数のコンソールでAPI Gatewayのトリガーを追加します。
「トリガーを追加」をクリックしたら、API Gatewayを選択します。
その他の設定は以下の表を参考にしてください。
カテゴリー | 値 |
---|---|
API | APIを作成する |
APタイプ | HTTP API |
セキュリティ | オープン |
ターミナルから以下などを実行
$ curl -X POST -H "Content-Type: text/plain" -d 'CSVファイル名' 先ほど作成したAPI Gatewayのエンドポイント $ curl GET 先ほど作成したAPI Gatewayのエンドポイント
今後に向けて
Lambda関数を使ってS3のデータをEFSに移動したりしてみたいです。
参考
素晴らしい記事に感謝致します。
新機能 – Lambda関数の共有ファイルシステム – Amazon Elastic File System for AWS Lambda | Amazon Web Services ブログ
AWS Lambda から Amazon EFS へのアクセス - Qiita