AWSTemplateFormatVersion: 2010-09-09 Description: Stack that sends out billing alerts Parameters: #------------------------ # Deployment Information #------------------------ environment: Type: String Description: Name of the environment to use in naming. Default: production release: Type: String Description: Name of the release name of the stack version to use. Default: production AllowedValues: ['develop', 'production'] ConstraintDescription: "Must be a possible release version." #--------------- # Alert Methods #--------------- discordWebhook: Type: String Description: A webhook for notifications for Discord. (Leave empty for none) Default: "" slackWebhook: Type: String Description: An incoming webhook for notifications for Slack. (Leave empty for none) Default: "" notificationEmail: Type: String Description: An email address to subscribe to the alerting topic. (Leave empty for none) Default: "" notificationPhone: Type: String Description: A mobile number to subscribe to the alerting topic. Formatted as '+1XXXXXXXXXX' (Leave empty for none) Default: "" #------------------- # Alarm Information #------------------- lowPriorityAlert: Type: Number Description: Estimated monthly cost in USD to send a low priority alert. Default: 10 MinValue: 1 mediumPriorityAlert: Type: Number Description: Estimated monthly cost in USD to send a normal alert. Default: 15 MinValue: 2 highPriorityAlert: Type: Number Description: Estimated monthly cost in USD to send a low priority alert. Default: 20 MinValue: 3 updateInterval: Type: Number Description: Time in seconds alarms are updated. Default: 21600 # 6 hours ConstraintDescription: Minimum alarm time is a minute. MinValue: 60 Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: "Deployment Information" Parameters: - environment - release - Label: default: "Alert Methods" Parameters: - notificationEmail - notificationPhone - discordWebhook - slackWebhook - Label: default: "Alarm Settings" Parameters: - lowPriorityAlert - mediumPriorityAlert - highPriorityAlert ParameterLabels: environment: default: "Environment" release: default: "Release" notificationEmail: default: "Email" notificationPhone: default: "SMS Number" discordWebhook: default: "Discord Webhook" slackWebhook: default: "Slack Webhook" lowPriorityAlert: Default: "Cost for Low Priority Alert" mediumPriorityAlert: Default: "Cost for Medium Priority Alert" highPriorityAlert: Default: "Cost for High Priority Alert" Conditions: SubscribeEmail: !Not [!Equals [!Ref "notificationEmail", ""]] SubscribePhone: !Not [!Equals [!Ref "notificationPhone", ""]] Resources: AlertSnsTopic: Type: AWS::SNS::Topic Properties: TopicName: !Sub "BillingAlerts-${environment}" EmailAlertSubscription: Type: AWS::SNS::Subscription Condition: SubscribeEmail Properties: Protocol: email Endpoint: !Ref notificationEmail TopicArn: !Ref AlertSnsTopic PhoneAlertSubscription: Type: AWS::SNS::Subscription Condition: SubscribePhone Properties: Protocol: sms Endpoint: !Ref notificationPhone TopicArn: !Ref AlertSnsTopic AlertExecutionerRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Policies: - PolicyName: LambdaLogging PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: "*" - PolicyName: AlertSNS PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - sns:Publish Resource: !Ref AlertSnsTopic AlertHandler: Type: AWS::Lambda::Function Properties: Handler: lambda_function.lambda_handler Runtime: python3.6 Code: S3Bucket: "sumu-billingalerts" S3Key: !Sub "${release}/lambda/alertHandler.zip" FunctionName: !Sub "FnAlert-${environment}" Description: Lambda receives CloudWatch events and alerts channels. MemorySize: 128 Timeout: 10 Role: !GetAtt AlertExecutionerRole.Arn Environment: Variables: discordWebhook: !Ref discordWebhook slackWebhook: !Ref slackWebhook snsTopic: !Ref AlertSnsTopic CloudWatchReciever: Type: AWS::SNS::Topic Properties: TopicName: !Sub "Billing-CloudWatch-${environment}" CloudWatchAlertSubscription: Type: AWS::SNS::Subscription Properties: Protocol: lambda Endpoint: !GetAtt AlertHandler.Arn TopicArn: !Ref CloudWatchReciever SnsLambdaPermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction Principal: sns.amazonaws.com SourceArn: !Ref CloudWatchReciever FunctionName: !GetAtt AlertHandler.Arn LowPriorityAlarm: Type: AWS::CloudWatch::Alarm Properties: ActionsEnabled: true AlarmActions: - !Ref CloudWatchReciever ComparisonOperator: GreaterThanThreshold Dimensions: - Name: Currency Value: USD EvaluationPeriods: 1 MetricName: EstimatedCharges Namespace: "AWS/Billing" OKActions: - !Ref CloudWatchReciever Period: !Ref updateInterval Statistic: Maximum Threshold: !Ref lowPriorityAlert MediumPriorityAlarm: Type: AWS::CloudWatch::Alarm Properties: ActionsEnabled: true AlarmActions: - !Ref CloudWatchReciever ComparisonOperator: GreaterThanThreshold Dimensions: - Name: Currency Value: USD EvaluationPeriods: 1 MetricName: EstimatedCharges Namespace: "AWS/Billing" OKActions: - !Ref CloudWatchReciever Period: !Ref updateInterval Statistic: Maximum Threshold: !Ref mediumPriorityAlert HighPriorityAlarm: Type: AWS::CloudWatch::Alarm Properties: ActionsEnabled: true AlarmActions: - !Ref CloudWatchReciever ComparisonOperator: GreaterThanThreshold Dimensions: - Name: Currency Value: USD EvaluationPeriods: 1 MetricName: EstimatedCharges Namespace: "AWS/Billing" OKActions: - !Ref CloudWatchReciever Period: !Ref updateInterval Statistic: Maximum Threshold: !Ref highPriorityAlert