【AWS Lambda】S3に保存された画像をリサイズして別S3に保存(Ruby利用)

##目標
S3に保存された画像データをLambda関数を利用してリサイズし、別S3に保存する。
プログラミング言語はRubyを利用しています。

##前提
事前に2つのS3バケットを作成していること。

##作業の流れ
| 項番 | タイトル |
|:----:|:-------------|
| 1 | [Lambda関数の作成とアップロード](#1lambda関数の作成とアップロード) |
| 2 | [Lambda環境変数の設定](#2lambda環境変数の設定)|
| 3 | [ハンドラーと実行ロールの設定](#3ハンドラーと実行ロールの設定)|
| 4 | [イベントトリガーの定義](#4イベントトリガーの定義)|
| 5 | [実行ロールの設定](#5実行ロールの設定)|
| 6 | [動作検証](#6動作検証)|

##手順
###1.Lambda関数の作成とアップロード
任意の関数名とLambda関数で利用するプログラミング言語を選択します。
今回は`Ruby2.5`で記述します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/2865391c-bae5-0025-603c-ad2682756e1b.png)

配備するLambda関数本体と外部ライブラリ（mini_magick）をzip化したものを作成します。
作業ディレクトリ上で以下操作を行います。

まずは`Gemfile`の作成

```bash:Gemfile

source 'https://rubygems.org'
gem "mini_magick"
```

`bundle install --path vendor/bundle`を利用して作業ディレクトリ配下にgemをインストールします。

```bash

bundle install --path vendor/bundle
```

更にLambda関数本体となる`handler.rb`を作成します。

```ruby:handler.rb

require 'aws-sdk-s3'
require 'base64'
require 'mini_magick'

def resize_image(event:, context:)
  s3_client = Aws::S3::Client.new(
                           :region => ENV['REGION'],
                           :access_key_id => ENV['ACCESS_KEY'],
                           :secret_access_key => ENV['SECRET_ACCESS_KEY']
                          )
                          
  # イベントソースとして指定したS3から保存された画像を取り込む
  key = event['Records'][0]['s3']['object']['key']
  image_file = s3_client.get_object(:bucket => ENV['BUCKET_BEFORE'], :key => key).body.read
  image = MiniMagick::Image.read(image_file)

  # リサイズした画像をLambda環境の/tmpに一時書き込み
  resized_tmp_file = "/tmp/#{key.delete("images/")}"
  image.resize("300x300").write(resized_tmp_file)

  # アップロード実行
  s3_resource = Aws::S3::Resource.new()
  object = s3_resource.bucket(ENV['BUCKET_AFTER']).object(key).upload_file(resized_tmp_file)
end
```

`handler.rb`と`vender`をzip化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/79a895eb-9570-f9c9-4514-a323201a1905.png)

作成したzipファイルのアップロードを行います。
Lambdaコンソール上の関数コード欄アクションから`.zipファイルをアップロード`をクリック
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/579937a4-97e2-5c8c-0e00-0c1933f5138e.png)

`handler.zip`を選択し、`保存`

![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/84a99ffa-0105-3eba-e28f-1a6f629a4463.png)



###2.Lambda環境変数の設定
Lambdaコンソール上からLambda関数内で利用する環境変数を設定します。

![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/e566318c-658a-eaa3-9ffd-8861710745a4.png)

###3.ハンドラーと実行ロールの設定
どのファイルのどの関数を呼び出すか…という設定は、ハンドラーというパラメータで指示しているとのことなので、
今回作成したLambda関数に合わせて内容を編集します。

Lambdaコンソール上の基本設定の`編集`をクリック
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/425f9f43-7954-14a8-660c-9788dcff4743.png)

ハンドラ欄に`実行ファイル名（拡張子除く）.関数名`の形式で値を入力し保存します。
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/4851047d-b219-4183-c890-d7d7776de67e.png)

###4.イベントトリガーの定義
Lambdaコンソール上から`トリガーを追加`をクリック
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/72870ada-babb-54fd-f9d6-66bd90078148.png)

今回イベントトリガーとするAWSサービスはS3
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/9ea76d1c-a48e-5051-41d4-38b5c643cf8c.png)

トリガーの詳細設定を行います。
今回はimagesディレクトリ内にオブジェクトが作成されたタイミングでのイベント起動とします。
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/3801b5ec-c0c2-c657-61fc-016b5f6a46d7.png)


`トリガーの有効化`をいれることでS3がこのLambda関数に処理をキックすることが可能となります（Lambda関数ポリシーの設定）。
最後に`追加`をクリック

![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/f6503aa5-fe26-eee6-ba55-5613b05185d0.png)


###5.実行ロールの設定
更に今回はリサイズした画像を保存する際にLambdaからS3にアクセスをかける必要があるため、
S3へのアクセス権限付きの実行ロールを付与します。

Lambdaコンソール上部にある`アクセス権限`をクリック後、実行ロール名をクリック

![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/e9d826f6-3f20-9e78-65e6-09158a673c77.png)

`ポリシーをアタッチします`をクリック
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/d7abce6d-303b-946d-d8e2-74e076a78881.png)

`AmazonS3FullAccess`を選択後、`ポリシーのアタッチ`
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/4fb7b838-bc9c-d16d-17b7-1d591c79d1f3.png)

###6.動作検証
イベントソースとして指定したS3のimagesディレクトリ内に任意の画像をアップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/705fa87f-9874-6c91-0e59-b5489d62950f.png)

ちなみにアップロードした画像はこちら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/e6b77cad-2e0d-611b-4287-e00e8a263275.png)


リサイズ後の画像保存先として指定したS3を確認したところ、画像が保存されていたのでOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/f386dd4f-ec77-5ed7-647b-1295a4f2b331.png)

中身もリサイズされていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/e04f6112-e3f6-e7a3-39f7-5d53ce2a5f6b.png)

LambdaのログはCloudwatch Logsから確認可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/1fb4dc94-91bb-3d5a-d0f2-32d0859fc94d.png)

##参考にさせて頂いた記事
[AWS Lambda Ruby を利用して 1時間で作る画像のリサイズ API](https://qiita.com/kiitan/items/4bdc530c66d6cdfbd294)