{
    "AWSTemplateFormatVersion":"2010-09-09",
    "Description":"AES - Flowlogs - S3, SQS, Notifications.  **Attention** This template creates AWS resources that will incur charges on your account.",
    "Resources":{
        "NotificationQueue" : {
            "Type" : "AWS::SQS::Queue",
            "Properties" : {
                "QueueName" : {"Fn::Join":["", [{"Fn::Select":["2",{"Fn::Split":["/",{"Ref" :"AWS::StackId"}]}]},"-flow-logs-queue"]]},
		"MaximumMessageSize": "4096"
            }
        },
	"NotificationQueueS3PublishPolicy":{
	
            "Type": "AWS::SQS::QueuePolicy",
            "Properties": {
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Principal": {
                                "Service": "s3.amazonaws.com"
                            },
                            "Action": [
                                "SQS:SendMessage"
                            ],
                            "Resource": "*",
                            "Condition": {
                                "ArnEquals": {
                                    "aws:SourceArn": [
                                        {"Fn::Join":["", [ "arn:aws:s3:::",{"Fn::Select":["2",{"Fn::Split":["/",{"Ref" :"AWS::StackId"}]}]},"-flow-logs"]]},
        		                {"Fn::Join":["", [ "arn:aws:s3:::",{"Fn::Select":["2",{"Fn::Split":["/",{"Ref" :"AWS::StackId"}]}]},"-flow-logs/*"]]}                        
                                    ]
                                }
                            }
                        }
                    ]
                },
                "Queues": [{"Ref": "NotificationQueue"}]
            }
        },
        "FlowlogsLambdaExecutionRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [{
                        "Effect": "Allow",
                        "Principal": {"Service": ["lambda.amazonaws.com"]},
                        "Action": ["sts:AssumeRole"]
                    }]
                },
                "Path": "/",
                "Policies": [{
                    "PolicyName": "FlowlogsLambdaExecutionPolicy",
                    "PolicyDocument": {
                        "Version": "2012-10-17",
                        "Statement": [
			    {
			        "Effect": "Allow",
			        "Action": [
			    	    "logs:CreateLogGroup",
			    	    "logs:CreateLogStream",
			    	    "logs:PutLogEvents",
			    	    "ec2:CreateNetworkInterface",
			    	    "ec2:DescribeNetworkInterfaces",
			    	    "ec2:DeleteNetworkInterface"
			        ],
			        "Resource": "*"
			    },			
			    {
                                "Effect": "Allow",
                                "Action": ["s3:List*","s3:DeleteObject","s3:GetObject"],
                                "Resource": [
			            {"Fn::Join":["", [ "arn:aws:s3:::",{"Fn::Select":["2",{"Fn::Split":["/",{"Ref" :"AWS::StackId"}]}]},"-flow-logs"]]},                        
        		            {"Fn::Join":["", [ "arn:aws:s3:::",{"Fn::Select":["2",{"Fn::Split":["/",{"Ref" :"AWS::StackId"}]}]},"-flow-logs/*"]]}                        
                                ]
			    },
                            {
                                "Effect": "Allow",
                                "Action": ["SQS:*"],
                                "Resource": {"Fn::GetAtt":["NotificationQueue","Arn"]}
                            },
                            {
			        "Effect": "Allow",
			        "Action": ["es:ESHttp*"],
			        "Resource": {"Fn::Join":["",["arn:aws:es:",{"Ref":"AWS::Region"},":",{"Ref":"AWS::AccountId"},":domain/*"]]}
			    },
			    {
			        "Effect": "Allow",
			        "Action": ["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents","logs:DeleteLog*"],
			        "Resource": "*"
			    }			    
			      			
			]
                    }
                }]
            }
        },	
        "BucketCleanupLambdaExecutionRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [{
                        "Effect": "Allow",
                        "Principal": {"Service": ["lambda.amazonaws.com"]},
                        "Action": ["sts:AssumeRole"]
                    }]
                },
                "Path": "/",
                "Policies": [{
                    "PolicyName": "BucketCleanupLambdaExecutionPolicy",
                    "PolicyDocument": {
                        "Version": "2012-10-17",
                        "Statement": [
			    {
                            "Effect": "Allow",
                            "Action": ["s3:List*","s3:DeleteObject"],
                            "Resource": [
			        {"Fn::Join":["", [ "arn:aws:s3:::",{"Fn::Select":["2",{"Fn::Split":["/",{"Ref" :"AWS::StackId"}]}]},"-flow-logs"]]},                        
        		        {"Fn::Join":["", [ "arn:aws:s3:::",{"Fn::Select":["2",{"Fn::Split":["/",{"Ref" :"AWS::StackId"}]}]},"-flow-logs/*"]]}                        
                                ]
			    },
			    {
			    "Effect": "Allow",
			    "Action": ["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents","logs:DeleteLog*"],
			    "Resource": "*"
			    }			    
			      			
			]
                    }
                }]
            }
        },    
        "BucketCleanupLambda": {
            "Type": "AWS::Lambda::Function",
            "Properties": {
                "Code": {
                    "ZipFile":{
		        "Fn::Join":[
			    "\n",
			    [    
				"import json",
				"import boto3",
				"from botocore.vendored import requests",
				"def delete_handler(event, context):",
				"    try:",
				"        print(event)",
				"        bucket = event['ResourceProperties']['BucketName']",
				"        if event['RequestType'] == 'Delete':",
				"            s3 = boto3.resource('s3')",
				"            bucket = s3.Bucket(bucket)",
				"            for obj in bucket.objects.filter():",
				"                print(\"Deleting ->\",obj.key)",
				"                s3.Object(bucket.name, obj.key).delete()",
				"        sendResponseCfn(event, context, \"SUCCESS\")",
				"    except Exception as e:",
				"        print(e)",
				"        sendResponseCfn(event, context, \"FAILED\")",
				"def sendResponseCfn(event, context, responseStatus):",
				"    response_body = {'Status': responseStatus,",
				"                     'Reason': 'Log stream name: ' + context.log_stream_name,",
				"                     'PhysicalResourceId': context.log_stream_name,",
				"                     'StackId': event['StackId'],",
				"                     'RequestId': event['RequestId'],",
				"                     'LogicalResourceId': event['LogicalResourceId'],",
				"                     'Data': json.loads(\"{}\")}",
				"    requests.put(event['ResponseURL'], data=json.dumps(response_body))"
			    ]
                        ]
                    }
                },
                "Description": "Cleanup handler to nuke files in a bucket (not done normally with bucket deletes)",
                "FunctionName": "NukeBucketObjects",
                "Handler": "index.delete_handler",
                "MemorySize": "256",
                "Role": {"Fn::GetAtt":["BucketCleanupLambdaExecutionRole","Arn"]},
                "Runtime": "python3.7",
                "Timeout": 300
            }
        },
        "NukeFlowLogsBucketObjects": {
            "Type": "Custom::NukeFlowLogsBucketObjects",
            "Properties": {
                "ServiceToken": {"Fn::GetAtt" : ["BucketCleanupLambda", "Arn"]},
                "BucketName": {"Ref":"FlowLogsDataEncryptedS3Bucket"}
            }
        },
        "FlowLogsDataEncryptedS3Bucket": {
            "Type": "AWS::S3::Bucket",
            "Properties": {
                "BucketName": {"Fn::Join":["", [{"Fn::Select":["2",{"Fn::Split":["/",{"Ref" :"AWS::StackId"}]}]},"-flow-logs"]]}, 
                "BucketEncryption": {
                    "ServerSideEncryptionConfiguration": [{
                        "ServerSideEncryptionByDefault": {
                            "SSEAlgorithm": "AES256"
                        }
                    }]
                },
		"NotificationConfiguration" : {
                    "QueueConfigurations":[
		        {
                            "Event" : "s3:ObjectCreated:*",
                            "Queue" : { "Fn::GetAtt" : ["NotificationQueue", "Arn"]}
                        }
		    ]      	    
		}
            },
            "DeletionPolicy": "Delete",
	    "DependsOn" : "NotificationQueueS3PublishPolicy"
        }
    },
    "Outputs":{
        "FlowLogsBucketName":{
            "Description":"Flow Logs Bucket Name",
            "Value":{"Ref":"FlowLogsDataEncryptedS3Bucket"},
            "Export" : { "Name" : {"Fn::Sub": "${AWS::StackName}-FlowLogsBucketName" }}
        },
        "FlowLogsBucketARN":{
            "Description":"Flow Logs Encrypted Bucket ARN",
            "Value":{"Fn::GetAtt":["FlowLogsDataEncryptedS3Bucket","Arn"]},
            "Export" : { "Name" : {"Fn::Sub": "${AWS::StackName}-FlowLogsBucketARN" }}
        },
        "LambdaRole":{
            "Description":"ARN for the role used by lambda to access S3",
            "Value":{"Fn::GetAtt":["BucketCleanupLambdaExecutionRole","Arn"]},
            "Export" : { "Name" : {"Fn::Sub": "${AWS::StackName}-LambdaRole" }}
        }
    }
}
