Lambda関数を設定してS3イベントで動かそう！

#Lambdaってなに？
AWSの提供するサービスの一つで、サーバ管理をすることなく処理を実行することができるサービスです。

例えばLambdaを利用しない場合、EC2でサーバを作成し処理実行に必要なミドルウェアや言語をインストールし、環境設定をすることで初めて処理が実行されます。

しかし、Lambdaではそのようなサーバのプロビジョニングをすることなく、処理を書くだけで実行することが可能になります。

これにより、
★サーバ自体の管理・メンテナンスが不要
★処理が実行されている時間のみ課金されるので処理の頻度によってはコストを大幅削減可能
★他AWSサービスと容易に連携できるので、AWSメインのアーキテクチャでは大変便利
というメリットがあります。

#トリガーとは？
書いた処理を実行させるにはトリガーというものを設定する必要があります。
AWSのあらゆるサービスと連携ができ、CloudWatchでアラームが出たら実行、kinesis data stream にデータが存在するとき実行、S3にファイルが置かれたら実行などが代表的な例になります。

つまりLambdaは**実行する条件**と**実行される処理**だけを書けば動いてくれるサービスなのです。


#実際に設定したい！
ではs3にファイルをアップロードし、アップロードされたことを確認する処理を書いてみましょう。
###1.AWSコンソールにログインし、Lambdaの画面で「関数の作成」をクリック
Lambdaはリージョンごとに関数を設定することになります。
S3の場合は問題ないですが、他リージョンの影響を受けるサービスと連携するときは同じリージョンを選択しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541083/20a174ed-401a-14e1-4849-1c77e81eba48.png)

###2.「1から作成」を選択し、「関数名」と「ランタイム」、「実行ロール」を設定
今回はpython 3.7を利用します。
ロールは「基本的なLambdaアクセス権限で新しいロールを作成」にします。
既存のロールを利用でも問題ないです。
その場合、Lambdaがトリガー条件のサービスやLog出力用のCloudWatchへのロググループ書き込み権限がある必要があります。
※新規作成の場合はCloudWatchのロググループ書き込み権限は自動でアタッチされます。

「ランタイム」とは処理の言語を意味します。2020/02/05時点では選択できる言語は下記となっております。
・Java 11/8
・.NET Core2.1(C#/PowerShell)
・GO 1.x
・Node.js 12.x/10.x
・python 3.8/3.7/3.6/2.7
※カスタムランタイムを利用することであらゆる言語を利用できるようになりますが、本記事では省略します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541083/060ebee0-d0c5-fee3-dfbc-f8ccc18afdd7.png)

###3.「トリガーを追加」で実行条件を設定
今回はs3に何かオブジェクトが作成されたときに実行できるようにします。
トリガー媒体をs3に設定したときの項目は下記の5つになります。
・バケット
・イベントタイプ(ファイルがPUTされたら・・・、ファイルが削除されたら・・・など)
・プレフィックス(バケット以降のディレクトリパスやファイル名など)
・サフィックス(ファイル名や拡張子など)
・トリガーの有効化(チェックするとすぐ上記設定のトリガーが動きます。処理のテストが終わってからonにしましょう)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541083/a90880ec-fd04-8bd6-a5c1-da95abc34f63.png)

###4.関数コードを設定
デフォルトではlambda_function.pyというファイルに処理が記述されています。

~~~lambda_function.py
import json

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
~~~
lambda_handlerとはLambdaに設定されているトリガー条件が満たされたときに自動的に実行される関数です。
``# TODO implement`` 以降を編集し、実行したい処理を書きましょう。

今回はs3にファイルが置かれたら置かれたパスとファイル名を表示するようにしてみます。

~~~lambda_function.py
import json

def lambda_handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = event['Records'][0]['s3']['object']['key']
    print(bucket+'バケットに'+key+'が作成されました！')
~~~

lambda_handlerに引数で渡している``event``にはトリガーとなったイベント情報が配列で入っており、
上記はそこからバケット名とファイルパスを取得し、表示を行っています。

###5.実行・確認
関数の実行自体はトリガーで指定したパスにファイルを置くことで実行できます。
それ以外にも下画像の「テスト」から``event``に入る値をjson形式で設定することにより疑似的にLambda関数を実行することが可能です。
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541083/4411dab7-042c-88b0-aea9-a832d9d02e6d.png)

また、関数の実行LogについてはCloudWatchのロググループから対象の関数を選択し、そこから確認することが可能です。
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541083/227566e7-8867-03a2-5226-6f7c2629974e.png)
<br><br>

正しくLambda関数が実行できていることが確認できました！！
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541083/b5ad0881-9820-c826-6873-863a516ae661.png)

#終わりに
LambdaはAWS環境を利用しており、シンプルな処理をおこなうのであればコスト面、管理面でもとてもおススメです。
少し気になったのは関数が何をしているかの説明文を書いておく欄がないので、わかりやすい関数名・処理内でのコメント記載を徹底し、快適なLambdaライフをおくりましょう！！