😀

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

2022/11/28に公開

とある事情で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 キューの作成を写経して作りました

/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

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

{
  "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は下記

{
  "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のイベントを実行したいタイミングで好きな値を(今回は作成のみ)
  • 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ってあんまりググっても出てこないのね・・・・

Discussion

ログインするとコメントできます