{
  "Resources": {
    "ObjectCreatedTopic92F47E19": {
      "Type": "AWS::SNS::Topic"
    },
    "ObjectCreatedTopicPolicyA938ECFC": {
      "Type": "AWS::SNS::TopicPolicy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": "sns:Publish",
              "Condition": {
                "ArnLike": {
                  "aws:SourceArn": {
                    "Fn::GetAtt": [
                      "MyBucketF68F3FF0",
                      "Arn"
                    ]
                  }
                }
              },
              "Effect": "Allow",
              "Principal": {
                "Service": "s3.amazonaws.com"
              },
              "Resource": {
                "Ref": "ObjectCreatedTopic92F47E19"
              },
              "Sid": "0"
            }
          ],
          "Version": "2012-10-17"
        },
        "Topics": [
          {
            "Ref": "ObjectCreatedTopic92F47E19"
          }
        ]
      }
    },
    "ObjectDeletedTopic2A914EC0": {
      "Type": "AWS::SNS::Topic"
    },
    "ObjectDeletedTopicPolicy026B02E6": {
      "Type": "AWS::SNS::TopicPolicy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": "sns:Publish",
              "Condition": {
                "ArnLike": {
                  "aws:SourceArn": {
                    "Fn::GetAtt": [
                      "MyBucketF68F3FF0",
                      "Arn"
                    ]
                  }
                }
              },
              "Effect": "Allow",
              "Principal": {
                "Service": "s3.amazonaws.com"
              },
              "Resource": {
                "Ref": "ObjectDeletedTopic2A914EC0"
              },
              "Sid": "0"
            }
          ],
          "Version": "2012-10-17"
        },
        "Topics": [
          {
            "Ref": "ObjectDeletedTopic2A914EC0"
          }
        ]
      }
    },
    "MyBucketF68F3FF0": {
      "Type": "AWS::S3::Bucket"
    },
    "MyBucketNotifications46AC0CD2": {
      "Type": "Custom::S3BucketNotifications",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": [
            "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691",
            "Arn"
          ]
        },
        "BucketName": {
          "Ref": "MyBucketF68F3FF0"
        },
        "NotificationConfiguration": {
          "TopicConfigurations": [
            {
              "Events": [
                "s3:ObjectCreated:*"
              ],
              "TopicArn": {
                "Ref": "ObjectCreatedTopic92F47E19"
              }
            },
            {
              "Events": [
                "s3:ObjectRemoved:*"
              ],
              "Filter": {
                "Key": {
                  "FilterRules": [
                    {
                      "Name": "suffix",
                      "Value": ".txt"
                    },
                    {
                      "Name": "prefix",
                      "Value": "foo/"
                    }
                  ]
                }
              },
              "TopicArn": {
                "Ref": "ObjectDeletedTopic2A914EC0"
              }
            }
          ]
        }
      }
    },
    "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": "lambda.amazonaws.com"
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "ManagedPolicyArns": [
          {
            "Fn::Join": [
              "",
              [
                "arn",
                ":",
                {
                  "Ref": "AWS::Partition"
                },
                ":",
                "iam",
                ":",
                "",
                ":",
                "aws",
                ":",
                "policy",
                "/",
                "service-role/AWSLambdaBasicExecutionRole"
              ]
            ]
          }
        ]
      }
    },
    "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": "s3:PutBucketNotification",
              "Effect": "Allow",
              "Resource": "*"
            }
          ],
          "Version": "2012-10-17"
        },
        "PolicyName": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36",
        "Roles": [
          {
            "Ref": "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC"
          }
        ]
      }
    },
    "BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Description": "AWS CloudFormation handler for \"Custom::S3BucketNotifications\" resources (@aws-cdk/aws-s3)",
        "Code": {
          "ZipFile": "exports.handler = (event, context) => {\n    const s3 = new (require('aws-sdk').S3)();\n    const https = require(\"https\");\n    const url = require(\"url\");\n    log(JSON.stringify(event, undefined, 2));\n    const props = event.ResourceProperties;\n    if (event.RequestType === 'Delete') {\n        props.NotificationConfiguration = {}; // this is how you clean out notifications\n    }\n    const req = {\n        Bucket: props.BucketName,\n        NotificationConfiguration: props.NotificationConfiguration\n    };\n    return s3.putBucketNotificationConfiguration(req, (err, data) => {\n        log({ err, data });\n        if (err) {\n            return submitResponse(\"FAILED\", err.message + `\\nMore information in CloudWatch Log Stream: ${context.logStreamName}`);\n        }\n        else {\n            return submitResponse(\"SUCCESS\");\n        }\n    });\n    function log(obj) {\n        console.error(event.RequestId, event.StackId, event.LogicalResourceId, obj);\n    }\n    // tslint:disable-next-line:max-line-length\n    // adapted from https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-code.html#cfn-lambda-function-code-cfnresponsemodule\n    // to allow sending an error messge as a reason.\n    function submitResponse(responseStatus, reason) {\n        const responseBody = JSON.stringify({\n            Status: responseStatus,\n            Reason: reason || \"See the details in CloudWatch Log Stream: \" + context.logStreamName,\n            PhysicalResourceId: context.logStreamName,\n            StackId: event.StackId,\n            RequestId: event.RequestId,\n            LogicalResourceId: event.LogicalResourceId,\n            NoEcho: false,\n        });\n        log({ responseBody });\n        const parsedUrl = url.parse(event.ResponseURL);\n        const options = {\n            hostname: parsedUrl.hostname,\n            port: 443,\n            path: parsedUrl.path,\n            method: \"PUT\",\n            headers: {\n                \"content-type\": \"\",\n                \"content-length\": responseBody.length\n            }\n        };\n        const request = https.request(options, (r) => {\n            log({ statusCode: r.statusCode, statusMessage: r.statusMessage });\n            context.done();\n        });\n        request.on(\"error\", (error) => {\n            log({ sendError: error });\n            context.done();\n        });\n        request.write(responseBody);\n        request.end();\n    }\n};"
        },
        "Handler": "index.handler",
        "Role": {
          "Fn::GetAtt": [
            "BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC",
            "Arn"
          ]
        },
        "Runtime": "nodejs8.10",
        "Timeout": 300
      }
    }
  }
}