【 AWS 】S3 → Lambda → SQS にメッセージを投げるまでの構築手順！

# __やりたいこと__
タイトルの通り、「__Lamda__」から「__Amazon SQS__」に「__メッセージを送信__」すること。

![All.jpg](https://qiita-image-store.s3.amazonaws.com/0/180432/cecc2e00-28a7-2c0f-cb88-ce1518b566a1.jpeg "全体像")

__具体的には、こんな感じ。__

# 処理フロー
1. S3にファイルをアップロードする。__( User )__
2. ファイルアップロードをトリガーにAmazon SQSにメッセージを送信する。__( Lambda )__
3. Amazon SQS内のキューにメッセージを格納する。__( Amazon SQS )__
4. 5分間隔で、Amazon SQSのキューのメッセージ個数をログ出力する。__( Lambda )__

実装する前に、ちょっとだけ__Amazon SQS__について紹介します。

# __What's Amazon SQS !?__

![SQS.jpg](https://qiita-image-store.s3.amazonaws.com/0/180432/3a9e7542-5dad-fb74-4978-1754a6fa189d.jpeg)


そもそもメッセージキューイングって何？

「__Message Queueing__ _( MQ : メッセージキューイング )_ 」

>アプリケーションソフト間でデータを交換して連携動作させる際に、送信するデータをいったん保管しておき、
相手の処理の完了を待つことなく次の処理を行う方式。

> - [IT用語辞典 - メッセージキューイング](http://e-words.jp/w/%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%82%AD%E3%83%A5%E3%83%BC%E3%82%A4%E3%83%B3%E3%82%B0.html)

_メッセージキューイングの仕組みを活用することにより、
メッセージ送信者は受信側のステータスを気にすることなく、
メッセージを送信し、送信側と受信側間で非同期での処理が可能に。_

__Amazon SQSは、Pull型のMQサービス__

![MQ.jpg](https://qiita-image-store.s3.amazonaws.com/0/180432/be9f058a-d472-ddc9-45f8-dc70639333f6.jpeg)

受信側 (Instance) がSQSに問い合わせて、メッセージを取得します。

### __Amazon SQSは、AWSフルマネージドな分散キュー__

> __フルマネージドとは ?__

> サービスの利用に必要な機器などの運用や管理、
導入時に必要な機器の設置や設定なども一体として提供するサービスのこと。

> - [マネージドサービス 【 managed service 】](http://e-words.jp/w/%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8%E3%83%89%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9.html)

- 高い信頼性 : 複数のサーバー/データセンターにメッセージを保持
- スケーラブル : 多数の送信者/受信者に対応
- 高スループット : メッセージが増加しても高スループットを出し続ける
- 低コスト : 毎月の無料枠 + 使った分だけの従量課金

# 動作検証

## (1) Lambda関数作成


※ 作成手順の詳細は、下記記事を参考にしていただければと思います。
「[__Lambda関数を作成する方法 ~S3へのファイルアップロードをトリガーにログ出力編~__](https://qiita.com/Futo23/items/fc2f9e472e6a2765d15d)」

_ここでは、特に重要な部分のみ抜粋しています。_

### __1.トリガーの設定__
---

ここでは、トリガーの対象となるS3のバケット名とイベント(今回は、「オブジェクトの作成」)の指定を行います。
また、作成後すぐに検証が行えるように、「__トリガーの有効化__」にチェックを入れておきます。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/a66a804f-ff0b-9414-2916-88265c017644.png)

### __2.関数コードの編集__
---

続いて、関数コードの編集を行います。ここでは、トリガーの対象となるイベント発生時に
どのような処理をおこなうのかを記述していきます。(Node.js 6.10)

今回は、下記のAmazon SQSへの操作を実装していきます。

__(1) Amazon SQSに、新しいキューを作成__ (AWS Console上で作成)

> Amazon SQSのページを開き、「__新しいキューの作成__」ボタンを押下します。

> ![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/cb3abdd3-636f-e57e-029a-824da9750d8f.png)

> 任意の「__キュー名__」を付けます。

> ![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/5d9aaebf-be70-3845-76fb-909d0573c1f3.png)

> 「__キューの作成__」を押下すると、新しくキューが作成され、一覧に表示されます。

> ![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/5ffa7db2-9314-3846-01fb-95e3c987d4ef.png)

> 続いて、作成したキューにメッセージを送信します。

__(2) (1)で作成したキューに、メッセージを送信__

> ![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/558ac064-ff68-42f9-43fb-884454f8fccc.png)

```sendMessage.js

console.log('Loading function');

const AWS = require('aws-sdk');
const SQS = new AWS.SQS({apiVersion: '2012-11-05'});
/* 宛先QueueのURL */
const QUEUE_URL = 'https://sqs.ap-northeast-1.amazonaws.com/<アカウントID>/<キューの名前>';

exports.handler = function(event, context) {

    // Get Upload FilePath
    var Bucket = event.Records[0].s3.bucket.name;
    var ObjKey = event.Records[0].s3.object.key;
    var FilePath = Bucket + '/' + ObjKey;

    // SendMessage
    var params = {
        MessageBody: FilePath, /* required */
        QueueUrl: QUEUE_URL,   /* required */
        DelaySeconds: 0
    };
    
    SQS.sendMessage(params, function(err, data) {
        if (err) console.log(err, err.stack); // an error occurred
        else     console.log(data);           // successful response
    });
    
};

```

> - [sendMessage](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SQS.html#sendMessage-property) (公式サイト)

> ※ちなみに、対象キューのURLは、Amazon Console画面上から確認することができます。(SDKでも可。) _[下図、赤色部分]_

> ![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/41641eab-c729-7582-de46-988805a15a0d.png)

> これで、S3にファイルをアップロードすると、Messageが送信されると思います。

と、その前に、Lambda上で、sendMessageをするためには、
実行ロールにAmazon SQSへの書き込み権限、ポリシーのアタッチをする必要があります。


### __3.アクセスポリシーのアタッチ__
---

__実行RoleにSQSアクセスポリシーをアタッチ__

> ![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/60f69d04-6801-1a13-4445-18666e642129.png)

> 「__AmazonSQSFullAccess__」のポリシーを実行ロールにアタッチします。

> ![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/9acfc083-ec10-98ab-02e7-f0e8acaff59b.png)

これですべての準備が整いました。
S3にファイルをアップロードしてみましょう。

## (2) S3へファイルアップロード

上記で作成したLambda関数が動作をしているか実際に検証してみます。

> __適当なファイルを対象のバケット内にアップロード__

> ![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/9a1aa539-aa0a-d7a6-f5c6-9c148fe6c302.png)

> __Lamda関数が実行されていれば、Amazon SQSにメッセージが届いているはずです。__

> ![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/1b91318f-5ccf-988c-2bec-e82afa961436.png)

> __利用可能なメッセージが1になりました。もう1つS3にファイルをアップロードしてみると、、。__

> ![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/d63a5c65-4dae-5f59-cbfc-66958d704644.png)

> __しっかりと、利用可能なメッセージが2に増えていますね。__

# 終わりに

ひとまず、__[S3へファイルアップロード]__ → __[Lambda関数実行]__ → __[Amazon SQSにメッセージ追加]__ までの
一連の流れが動くという検証ができました。

次回記事で、キュー内のメッセージ個数を確認する[__Lambda関数__]を作成したいと思います。

最後までお読みいただきありがとうございました。