# Amazon Pinpoint & SES message sending queuing # # **DO NOT DELETE** # # author: pavlosik@ --- AWSTemplateFormatVersion: 2010-09-09 Description: SES - Pinpoint messages queuing Parameters: SQSBatchSize: Type: Number Description: Provide the SQS batch-size ReservedLambdaConcurrency: Type: Number Description: Set the AWS Lambda poller function reserved concurrency Emailthroughput: Type: Number Description: Your email throughput e.g. 100 emails per second DashboardName: Type: String Description: Name for the CloudWatch dashboard EmailFrom: Type: String Description: The email address you will send from for testing purposes NoOfMessagesSQS: Type: String Description: How many messages will you write to SQS (for demo purposes) LambdaCodeS3BucketName: Type: String Description: Type the S3 bucket name with the Lambda code Resources: ##### SQS Queues ####################################### MessagesQueue: Type: AWS::SQS::Queue Properties: VisibilityTimeout: 500 KmsMasterKeyId: alias/aws/sqs RedrivePolicy: deadLetterTargetArn: !GetAtt MessagesDeadLetterQueue.Arn maxReceiveCount: 3 MessagesDeadLetterQueue: Type: AWS::SQS::Queue Properties: KmsMasterKeyId: alias/aws/sqs ##### Lambda Functions ####################################### PublisherLambda: Type: AWS::Lambda::Function Properties: Role: !GetAtt PublisherLambdaRole.Arn Timeout: 60 Environment: Variables: SQS_QUEUE_URL: !Ref MessagesQueue NO_OF_MESSAGES: !Ref NoOfMessagesSQS EMAIL_FROM: !Ref EmailFrom Handler: lambda_function.lambda_handler Runtime: python3.9 Code: S3Bucket: !Ref LambdaCodeS3BucketName S3Key: "sqs_message_publisher.zip" PublisherLambdaRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - "sts:AssumeRole" Path: "/" Policies: - PolicyName: "root" PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: sqs:SendMessage Resource: !GetAtt MessagesQueue.Arn - Effect: "Allow" Action: - "logs:CreateLogGroup" - "logs:CreateLogStream" - "logs:PutLogEvents" Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*" CloudWatchInvokeLambda: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: !GetAtt PublisherLambda.Arn Principal: events.amazonaws.com SourceArn: !GetAtt EventBridgeRulePublishSQS.Arn PollerLambda: Type: AWS::Lambda::Function Properties: Role: !GetAtt PollerLambdaRole.Arn Timeout: 300 Environment: Variables: SQS_QUEUE_URL: !Ref MessagesQueue SQS_DLQ_QUEUE_URL: !Ref MessagesDeadLetterQueue Handler: lambda_function.lambda_handler Runtime: python3.9 ReservedConcurrentExecutions: !Ref ReservedLambdaConcurrency Code: S3Bucket: !Ref LambdaCodeS3BucketName S3Key: "sqs_message_poller.zip" PollerLambdaEventMapping: Type: AWS::Lambda::EventSourceMapping Properties: BatchSize: !Ref SQSBatchSize MaximumBatchingWindowInSeconds: 1 Enabled: True EventSourceArn: !GetAtt MessagesQueue.Arn FunctionName: !Ref PollerLambda PollerLambdaRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - "sts:AssumeRole" Path: "/" Policies: - PolicyName: "root" PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - "mobiletargeting:SendMessages" Resource: !Sub arn:aws:mobiletargeting:${AWS::Region}:${AWS::AccountId}:* - Effect: Allow Action: - "ses:SendEmail" - "ses:SendBulkEmail" Resource: !Sub arn:aws:ses:${AWS::Region}:${AWS::AccountId}:* - Effect: Allow Action: - "sqs:SendMessage" - "sqs:ReceiveMessage" - "sqs:DeleteMessage" - "sqs:GetQueueAttributes" Resource: !GetAtt MessagesQueue.Arn - Effect: Allow Action: - "sqs:SendMessage" Resource: !GetAtt MessagesDeadLetterQueue.Arn - Effect: "Allow" Action: - "logs:CreateLogGroup" - "logs:CreateLogStream" - "logs:PutLogEvents" Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*" - Effect: "Allow" Action: - "cloudwatch:PutMetricData" Resource: "*" ##### CloudWatch dashboard ####################################### SESCloudwatchDashboard: Type: AWS::CloudWatch::Dashboard Properties: DashboardName: !Ref DashboardName DashboardBody: !Sub | { "widgets": [ { "height": 9, "width": 24, "y": 0, "x": 0, "type": "metric", "properties": { "metrics": [ [ "AWS/SES", "Send" ], [ ".", "Delivery" ], [ "AWS/Lambda", "Invocations", "FunctionName", "${PollerLambda}", { "label": "Lambda Invocations", "yAxis": "right" } ], [ "ses_custom_metrics", "no_SQSmessages_processed", { "label": "Lambda No SQS messages processed" } ], [ ".", "ses_throttling", { "yAxis": "left", "label": "SES_throttling" } ], [ "AWS/SQS", "NumberOfMessagesSent", "QueueName", "${MessagesQueue.QueueName}", { "label": "SQS number of messages sent" } ] ], "view": "timeSeries", "stacked": false, "region": "${AWS::Region}", "stat": "Sum", "period": 1, "title": "Email Queuing Monitoring", "yAxis": { "right": { "max": 20 } } } }, { "height": 6, "width": 6, "y": 9, "x": 0, "type": "metric", "properties": { "metrics": [ [ "AWS/SES", "Delivery"] ], "view": "gauge", "region": "${AWS::Region}", "stat": "Average", "period": 10, "yAxis": { "left": { "min": 0, "max": ${Emailthroughput} } }, "title": "Email-Throughput" } }, { "height": 6, "width": 6, "y": 9, "x": 6, "type": "metric", "properties": { "view": "timeSeries", "stacked": true, "metrics": [ [ "AWS/SQS", "ApproximateNumberOfMessagesVisible", "QueueName", "${MessagesQueue.QueueName}" ] ], "region": "${AWS::Region}", "period": 10, "title": "SQS-NumberOfMessagesVisible" } }, { "height": 6, "width": 6, "y": 9, "x": 12, "type": "metric", "properties": { "metrics": [ [ "ses_custom_metrics", "message_sent_ms" ], [ "AWS/Lambda", "Duration", "FunctionName", "${PollerLambda}", { "yAxis": "right", "label": "Lambda poller duration" } ] ], "view": "timeSeries", "stacked": false, "region": "${AWS::Region}", "stat": "Average", "period": 10, "title": "Lambda duration & SES API duration" } }, { "height": 6, "width": 6, "y": 9, "x": 18, "type": "metric", "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/Lambda", "ConcurrentExecutions", "FunctionName", "${PollerLambda}" ], [ ".", "Errors", ".", ".", { "stat": "Sum", "yAxis": "right" } ] ], "region": "${AWS::Region}", "period": 10, "title": "Lambda - Poller metrics" } } ] } #### EVENT BRIDGE RULE FOR PUBLISHER LAMBDA ################################## EventBridgeRulePublishSQS: Type: AWS::Events::Rule Properties: Name: "TriggerSQSPublishMessagesLambda" Description: "Invokes publisher AWS Lambda function, which writes dummy test messages to SQS" State: "DISABLED" ScheduleExpression: "rate(1 minute)" Targets: - Arn: !GetAtt PublisherLambda.Arn Id: EventBridgeRulePublishSQS