LoginSignup
60

More than 5 years have passed since last update.

S3更新時にCloudFrontのInvalidationを実施する・改

Posted at

SPINFさんの AWS LambdaでS3更新時にCloudFrontのInvalidationを実施する を東京リージョンで実現する方法です。

Classmethodさんの 異なるリージョンのAWS Lambdaを利用する を見て、SNSからは任意のリージョンの Lambda が呼べるので、東京リージョンのS3 bucketでも自動的にInvalidationが出来そうだという事でやってみました。

通知メッセージの形式

S3のObject Creationイベントを、SNS Notification 経由で Lambda に飛ばしてみると、

{
    "Records": [
        {
            "EventSource": "aws:sns",
            "EventVersion": "1.0",
            "EventSubscriptionArn": "arn:aws:sns:ap-northeast-1:000000000000:invalidation:fe80205a-f446-48ac-b536-ab553f8c076f",
            "Sns": {
                "Type": "Notification",
                "MessageId": "d14fcdeb-eb34-5982-9abd-8055cf10fb40",
                "TopicArn": "arn:aws:sns:ap-northeast-1:000000000000:invalidation",
                "Subject": "Amazon S3 Notification",
                "Message": "{\"Records\":[{\"eventVersion\":\"2.0\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"ap-northeast-1\",\"eventTime\":\"2015-05-02T01:01:24.116Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"A000000000000\"},\"requestParameters\":{\"sourceIPAddress\":\"1.2.3.4\"},\"responseElements\":{\"x-amz-request-id\":\"83F249C38C9573DC\",\"x-amz-id-2\":\"se8ASGX/20Lpw7LxK191kRxDJeAaXgh29Yugf6LAysthLNa8OFWB+tjEo/B5L6NUHejDJ1kA9TY=\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"invalidation\",\"bucket\":{\"name\":\"j3tm0t0-test\",\"ownerIdentity\":{\"principalId\":\"A000000000000\"},\"arn\":\"arn:aws:s3:::j3tm0t0-test\"},\"object\":{\"key\":\"dummy\",\"size\":6,\"eTag\":\"f02e326f800ee26f04df7961adbf7c0a\"}}}]}",
                "Timestamp": "2015-05-02T01:01:24.256Z",
                "SignatureVersion": "1",
                "Signature": "XfA0EUOD0sYjwRpkjF36byAJFRrIg0cWeBbb/EyFQbm3MK4JlZFvxbdel6z3H+6b2HVd8TKigkMt2TdWFmXS+q/KdiUgiTKARb8C03VB3VTc/Ihulnrp4/oXsmdaa/Q9Ak1uarQYPsry3EPQQvTqytsVfdg38mriPjCTGxFoAPySXcCAcX8sMPohhq4AnMjIYYVlFpx3MdeXzkvQll4qo1H/ebZf2eYok5CF9K1tBH2r0ZndaK5hEmgm0rtwNeUpGoMixPHw5eq8fHJIUgvpcw8y5bY8p2sRwAGqKxhtIwKSFqHTpSKrmHxZEwFo2WfYzoZz7DHx3982k1u8GEMAVg==",
                "SigningCertUrl": "https://sns.ap-northeast-1.amazonaws.com/SimpleNotificationService-d6d679a1d18e95c2f9ffcf11f4f9e198.pem",
                "UnsubscribeUrl": "https://sns.ap-northeast-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:ap-northeast-1:000000000000:invalidation:fe80205a-f446-48ac-b536-ab553f8c076f",
                "MessageAttributes": {}
            }
        }
    ]
}

のような event が実行されます。この中の Records[0].Sns.Message を取り出すと

{
    "Records": [
        {
            "eventVersion": "2.0",
            "eventSource": "aws:s3",
            "awsRegion": "ap-northeast-1",
            "eventTime": "2015-05-02T01:01:24.116Z",
            "eventName": "ObjectCreated:Put",
            "userIdentity": {
                "principalId": "A000000000000"
            },
            "requestParameters": {
                "sourceIPAddress": "1.2.3.4"
            },
            "responseElements": {
                "x-amz-request-id": "83F249C38C9573DC",
                "x-amz-id-2": "se8ASGX/20Lpw7LxK191kRxDJeAaXgh29Yugf6LAysthLNa8OFWB+tjEo/B5L6NUHejDJ1kA9TY="
            },
            "s3": {
                "s3SchemaVersion": "1.0",
                "configurationId": "invalidation",
                "bucket": {
                    "name": "j3tm0t0-test",
                    "ownerIdentity": {
                        "principalId": "A000000000000"
                    },
                    "arn": "arn:aws:s3:::j3tm0t0-test"
                },
                "object": {
                    "key": "dummy",
                    "size": 6,
                    "eTag": "f02e326f800ee26f04df7961adbf7c0a"
                }
            }
        }
    ]
}

のようなデータになってます。これはS3からダイレクトにLambdaを呼んだ時の構造と同じです。
イベントソースがSNSだった際には、中から取り出して実行してあげれば良さそうですね。

実装

SPINFさんのスクリプトの冒頭に下記のようなコードを付け加えます(フルのコードはこちら)。

  if (event.Records[0].EventSource == "aws:sns")
  {
    if(event.Records[0].Sns.Subject == "Amazon S3 Notification")
    { // overwrite S3 event object from payload
      event=JSON.parse(event.Records[0].Sns.Message);
    }
  }

テスト

東京リージョンのBucketにダミーファイルをアップしてみます。

~$ aws s3 cp dummy s3://j3tm0t0-test/
upload: ./dummy to s3://j3tm0t0-test/dummy

screenshot
Invalidation が実行されました!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
60