ablog

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

S3バケットの Static website hosting が有効化されたら CWE -> Lambda で自動的に無効化する

S3バケットの Static website hosting が有効化されたら、CloudWatch Events で検知して Lambda で無効化してみたメモ。

設定

Lambda 関数を作成する
  • 名前: S3DeleteBucketWebsite
  • ランタイム: Python 2.7
  • ロール: S3FullAccess
  • 関数コード
import boto3
s3 = boto3.client('s3')

def lambda_handler(event, context):
    print( 'event: ', event )
    bucket_name=event['detail']['requestParameters']['bucketName']
    print( bucket_name )
    s3.delete_bucket_website(Bucket=bucket_name)
    return 'S3DeleteBucketWebsite finished!'
CloudWatch Events
  • [CloudWatch]-[イベント]-[ルール]を選択し、[ルールの作成]をクリックしてルールを作成する。
  • [イベントパターン]を選択する。
  • サービス名: S3
  • イベントタイプ: Bucket Level Operation
  • Lambda関数の機能で "S3DeleteBucketWebsite" を指定する。

実行してみる

  • 任意のS3バケットの Static website hosting を有効化する。
  • CloudTrail でイベントを確認する

  • 手動で Static website hosting を有効化したときのイベント詳細
{
    "eventVersion": "1.05",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "...:yoheia",
        "arn": "arn:aws:sts::...:assumed-role/Admin/yoheia",
        "accountId": "...",
        "accessKeyId": "...",
        "sessionContext": {
            "attributes": {
                "mfaAuthenticated": "false",
                "creationDate": "2018-10-01T01:23:41Z"
            },
            "sessionIssuer": {
                "type": "Role",
                "principalId": "...",
                "arn": "arn:aws:iam::...:role/Admin",
                "accountId": "...",
                "userName": "Admin"
            }
        }
    },
    "eventTime": "2018-10-01T01:29:24Z",
    "eventSource": "s3.amazonaws.com",
    "eventName": "PutBucketWebsite",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "***.***.164.95",
    "userAgent": "[S3Console/0.4, aws-internal/3 aws-sdk-java/1.11.408 Linux/4.9.93-0.1.ac.178.67.327.metal1.x86_64 OpenJDK_64-Bit_Server_VM/25.181-b13 java/1.8.0_181]",
    "requestParameters": {
        "bucketName": "...",
        "website": [
            ""
        ],
        "WebsiteConfiguration": {
            "IndexDocument": {
                "Suffix": "index.html"
            },
            "xmlns": "http://s3.amazonaws.com/doc/2006-03-01/",
            "ErrorDocument": {
                "Key": "error.html"
            }
        }
    },
    "responseElements": null,
    "additionalEventData": {
        "vpcEndpointId": "vpce-..."
    },
    "requestID": "5713892F375F06E7",
    "eventID": "8bf143b4-0c11-4d2f-ade2-8d8a48fd264d",
    "eventType": "AwsApiCall",
    "recipientAccountId": "...",
    "vpcEndpointId": "vpce-..."
}
  • Lambda で自動無効化したときのイベント詳細
{
    "eventVersion": "1.05",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "...:S3DeleteBucketWebsite",
        "arn": "arn:aws:sts::...:assumed-role/S3FullAccess/S3DeleteBucketWebsite",
        "accountId": "...",
        "accessKeyId": "...",
        "sessionContext": {
            "attributes": {
                "mfaAuthenticated": "false",
                "creationDate": "2018-09-30T23:48:23Z"
            },
            "sessionIssuer": {
                "type": "Role",
                "principalId": "...",
                "arn": "arn:aws:iam::...:role/S3FullAccess",
                "accountId": "...",
                "userName": "S3FullAccess"
            }
        }
    },
    "eventTime": "2018-10-01T01:29:46Z",
    "eventSource": "s3.amazonaws.com",
    "eventName": "DeleteBucketWebsite",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "**.***.125.247",
    "userAgent": "[Boto3/1.7.74 Python/2.7.12 Linux/4.14.67-66.56.amzn1.x86_64 exec-env/AWS_Lambda_python2.7 Botocore/1.10.74]",
    "requestParameters": {
        "bucketName": "...",
        "website": [
            ""
        ]
    },
    "responseElements": null,
    "requestID": "82F29B6174AE2EEF",
    "eventID": "90c11fd3-c30e-4423-b429-9e9aae689df3",
    "eventType": "AwsApiCall",
    "recipientAccountId": "..."
}

補足

  • テストの際は[テストイベントの設定] で CloudTrail のイベントをコピー&ペーストするとテスト&デバッグが楽。実際にイベントを発生させなくてもイベントから渡される情報を使ったテストが可能。ただし、CloudTrail の画面のイベントの詳細は event['detail'] 以降のネームスペースになる。

参考

Delete a Bucket Website Configuration

  • The example below shows how to:

Delete a bucket website configuration using delete_bucket_website.
Example

import boto3

# Create an S3 client
s3 = boto3.client('s3')

# Call S3 to delete the website policy for the given bucket
s3.delete_bucket_website(Bucket='my-bucket')
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-example-static-web-host.html