大田区から発信するゆるゆる日記

主にITエンジニアに関する備忘録日記。たまに趣味も。何か不備があればコメント頂けると幸いです。Twitterアカウント https://twitter.com/ryuzan03

【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
セキュリティ オープン


ターミナルから以下などを実行

bash

$ 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