AWS SQSを使ってみる(AWS CLIで作ってみる)

とある事情でSQS使ってみようかという話になりS3にファイルがPOSTされたら、SQSにmessageを送る。
ということをしてみた。

以外と公式以外に情報がなくてググりまくった。

## やること

* AWS SQSにキューを作る
* SQS ポリシードキュメントを設定してS3のポリシー許可を設定する
* S3のイベント設定に紐付ける


## 環境

* MACOSX 10.11.3(El Captitan)
	* Python 2.7.10
		* aws-cli/1.10.28

## 前提条件

* aws-cliがインストール済みであること



## 参考にしたサイト

* [[JAWS-UG CLI] SQS:#1 キューの作成](http://qiita.com/tcsh/items/a41ac99e41430c1d758c)
* [(AWS 公式ドキュメント)チュートリアル例 1: バケットを通知用に設定する（メッセージの宛先: SNS トピックおよび SQS キュー）](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/ways-to-add-notification-config-to-bucket.html#step1-create-sqs-queue-for-notification)

## キューの作成

[[JAWS-UG CLI] SQS:#1 キューの作成](http://qiita.com/tcsh/items/a41ac99e41430c1d758c)を写経して作りました

```shell:/path/to/create_queue.sh
#!/bin/env/bash

SQS_QUEUE_NAME=$1
echo "Try Create SQS queue name: ${SQS_QUEUE_NAME}"

QUEUE_NAME_EXISTS=$(aws sqs list-queues --queue-name-prefix ${SQS_QUEUE_NAME})

if [ ${#QUEUE_NAME_EXISTS} -gt 0 ]; then
    echo "InValid Que name. not uniq Que name"
    exit 1
fi

aws sqs create-queue --queue-name ${SQS_QUEUE_NAME}
echo "Created SQS QUEUE name: ${SQS_QUEUE_NAME}"
aws sqs list-queues --queue-name-prefix ${SQS_QUEUE_NAME}
# SQS VisibilityTimeout (VisibilityTimeoutは、受信操作を行うとそのメッセージが見えなくなる一定の時間のことです。 Timeout前にそのメッセージに対して削除操作がされないと、再度キューに戻されます。)
SQS_VTOUT=60

echo "Modified SQS queue-attributes VisibilityTimeout: ${SQS_VTOUT}"
SQS_QUEUE_URL=$( \
        aws sqs get-queue-url \
          --queue-name ${SQS_QUEUE_NAME} \
          --output text \
)
aws sqs set-queue-attributes --queue-url ${SQS_QUEUE_URL} --attributes VisibilityTimeout=${SQS_VTOUT}

# policyの設定ArnLikeの部分を任意のbucketに設定する
SQS_POLICY='{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Effect":"Allow",
      "Principal": { "AWS": "*" },
      "Action":"sqs:SendMessage",
      "Resource":"SQS-queue-ARN",
      "Condition":{
        "ArnLike":{
          "aws:SourceArn": "arn:aws:s3:*:*:fuga"
        }
      }
    }
  ]
}'
SQS_POLICY_ESCAPED=$(echo $SQS_POLICY | perl -pe 's/"/\\"/g')
SQS_POLICY_ATTRIBUTES='{"Policy":"'$SQS_POLICY_ESCAPED'"}'
# policyを設定する
aws sqs set-queue-attributes \
  --queue-url ${SQS_QUEUE_URL} \
  --attributes "$SQS_POLICY_ATTRIBUTES"

echo "Setting SQS QUEUE: ${SQS_QUEUE_NAME}"
aws sqs get-queue-attributes \
        --queue-url ${SQS_QUEUE_URL} \
        --attribute-names \
          Policy \
          VisibilityTimeout \
          MaximumMessageSize \
          MessageRetentionPeriod \
          ApproximateNumberOfMessages \
          ApproximateNumberOfMessagesNotVisible \
          CreatedTimestamp \
          LastModifiedTimestamp \
          QueueArn \
          ApproximateNumberOfMessagesDelayed \
          DelaySeconds \
          ReceiveMessageWaitTimeSeconds \
          RedrivePolicy

echo "SQS Setting Finish URL: ${SQS_QUEUE_URL}"
```

### キューを作成する

```
sh /path/to/create_queue.sh {{ 任意のキュー名 }}
```

## 【補足】SQSのポリシードキュメントを設定

上記shellのPolicyの設定は下記の設定と等価です。

AWS consoleからSQSを選択

![SQS Setting](https://raw.githubusercontent.com/ryurock/qiita_images/master/SQS_Management_Console.png)

ポリシードキュメントの編集画面になったら下記jsonをsampleとして記載する

```hoge.json
{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Effect":"Allow",
      "Principal": { "AWS": "*" },
      "Action":"sqs:SendMessage",
      "Resource":"SQS-queue-ARN",
      "Condition":{
        "ArnLike":{
          "aws:SourceArn": "arn:aws:s3:*:*:hoge"
        }
      }
    }
  ]
}
```

IdとSidはそれぞれユニークな名前で
aws:SourceArnにS3に紐付けたいbucket-nameを設定する


## S3の設定

bucketがない場合は作成しておいてください。

### SQSで作成したキューの確認

先程のshellの実行結果のQueueUrlをコピーしてarnを確認する

```
aws sqs get-queue-attributes \
        --queue-url {{先程のshell結果QueueUrl}} \
        --attribute-names \
            QueueArn \
--query "Attributes.QueueArn" \
--output text

#こんな結果になる
arn:aws:sqs:ap-northeast-1:xxxxxx:hoge
```


### S3 put-bucket-notification-configurationでS3のイベントを登録する

設定するjsonは下記

```sample.json
{
  "QueueConfigurations": [
    {
      "Id":"{{ 任意の名前 }}",
      "QueueArn": "{{ arn:aws:sqs:ap-northeast-1:xxxxxx:hoge }}",
      "Events": ["s3:ObjectCreated:Post"],
      "Filter": {
        "Key": {
          "FilterRules": [{ "Name": "suffix","Value": ".jpg" }]
        }
      }
    }
  ]
}
```

* QueueArnは先程取得したARNの値
* EventsはS3のイベントを実行したいタイミングで好きな値を(今回は作成のみ)
	* [aws-cli put-bucket-notification-configuration](http://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-notification-configuration.html)
* Filterはイベントhook時の設定(今回は拡張子が.jpg)


### S3にイベントを登録する

```
aws s3api put-bucket-notification-configuration --bucket {{ your bucket name }} --notification-configuration file://sample.json
```

S3のコンソールに行くとイベントが登録されています。

### 動作確認

consoleでもCUIでもすきなほうでS3にアップロード後SQSにメッセージが飛んできているか確認する

## 最後に

S3 => SQSってあんまりググっても出てこないのね・・・・