ablog

不器用で落着きのない技術者のメモ

S3イベント通知はオブジェクト作成完了後に通知される

S3イベント通知を使うと、S3バケットにオブジェクトが作成されれたタイミングでイベント・ドリブンでLambda関数を呼び出したりSNSトピックにメッセージを送ったりできるが、作成開始ではなく完了したタイミングでイベント通知されることを確認した。

事前準備

環境変数を設定する
$ export LANG=C
$ export TZ=UTC
$ export AWS_DEFAULT_REGION=ap-northeast-1
SNSトピックを作成する
  • トピック名が重複しないよう既存のを確認する
$ aws sns list-topics
  • SNSトピックを作成する
$ aws sns create-topic --name s3-event-test
  • トピックを subscribe する(指定したメールアドレスに通知する)
$ aws sns subscribe --topic-arn arn:aws:sns:ap-northeast-1:*********:s3-event-test \
	--protocol email \
	--notification-endpoint ******@gmail.com
  • 指定したメールアドレスに確認メールが届くので本文のリンクをクリックする。
Subject: AWS Notification - Subscription Confirmation
Body:
You have chosen to subscribe to the topic: 
arn:aws:sns:ap-northeast-1:*********:s3-event-test

To confirm this subscription, click or visit the link below (If this was in error no action is necessary): 
Confirm subscription
  • トピックのポリシーを設定する
$ cat << EOF > sns_topic_policy.json
{
  "Version": "2008-10-17",
  "Id": "__default_policy_ID",
  "Statement": [
    {
      "Sid": "__default_statement_ID",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": [
        "SNS:Publish",
        "SNS:RemovePermission",
        "SNS:SetTopicAttributes",
        "SNS:DeleteTopic",
        "SNS:ListSubscriptionsByTopic",
        "SNS:GetTopicAttributes",
        "SNS:Receive",
        "SNS:AddPermission",
        "SNS:Subscribe"
      ],
      "Resource": "arn:aws:sns:ap-northeast-1:********:s3-event-test",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": "arn:aws:s3:::az-test-2018"
        }
      }
    }
  ]
}
EOF
$ aws sns set-topic-attributes \
	--topic-arn arn:aws:sns:ap-northeast-1:********:s3-event-test \
	--attribute-name Policy \
	--attribute-value file://sns_topic_policy.json
S3バケットを作成する
$ aws s3 mb s3://az-test-2018
  • SNSへの通知設定をファイルにJSONで記述する。
$ cat << EOF > topic_config.json
{
    "TopicConfigurations": [
        {
            "TopicArn": "arn:aws:sns:ap-northeast-1:********:s3-event-test",
            "Events": [
                "s3:ObjectCreated:*"
            ]
        }
    ]
}
$ aws s3api put-bucket-notification-configuration --bucket "az-test-2018" --notification-configuration file://topic_config.json

SNSに通知されるタイミングを確認する

  • ファイルを作成する
$ perl -le 'print for 1..100000000' > test.txt
$ ls -lh test.txt
-rw-r--r--  1 azekyohe  1896053708   848M Feb 11 10:22 test.txt
$ ls -l test.txt
-rw-r--r--  1 azekyohe  ...  888888898★ Feb 11 01:22 test.txt
  • S3にファイルをアップロードする
$ date; aws s3 cp test.txt s3://az-test-2018/; date
Sun Feb 11 02:28:16 UTC 2018 ★開始時間
upload: ./test.txt to s3://az-test-2018/test.txt
Sun Feb 11 02:30:47 UTC 2018 ★終了時間
  • メールを確認する
Subject:  AWS Notifications
Body:
{"Records":[{"eventVersion":"2.0","eventSource":"aws:s3","awsRegion":"ap-northeast-1",
"eventTime":"2018-02-11T02:30:48.571Z"★,"eventName":"ObjectCreated:CompleteMultipartUpload", ... 
"object":{"key":"test.txt","size":888888898★,...

オブジェクトの作成が完了したタイムスタンプで通知されている。

参考

こんにちは、

"list-objects等で取得可能なキーの一覧には反映されておらず、(キーが)取得できない
(間も、オブジェクトはPUT時の戻り値のキーを引数にget-object等で取得できる)という状況は発生する可能性がある。"
と、理解しました。
つまり、PUT(新規書き込み)完了後、
・キーが取得できないことはあってもオブジェクトが取得できないケースは発生しない(オブジェクトは*必ず*取得できる)
という認識です。もし認識が誤っていればご指摘ください。

はい、そのようなご認識で問題はございません。
「書き込み後の読み取り整合性」は、PUT (新規書き込み)が正常に完了した直後に、GETで該当のキーを結果整合性の影響を受けずに取得できる (=404 NotFoundにはならない) ことを保証しています。

https://forums.aws.amazon.com/thread.jspa?threadID=225802