---
AWSTemplateFormatVersion: '2010-09-09'
Description: 'CloudFormation template for creating CloudWatch Billing Alarm and associated SNS topic to notify by email when estimated charges threshold has been exceeded.'

Parameters:
    SNSTotalEstimatedChargesTopicName:
        Description: The SNS topic name for estimated charges CloudWatch Billing Alarm
        Default: SNSTotalEstimatedChargesBillingAlarm
        Type: String
        AllowedPattern: "[a-zA-Z0-9]*"
        MaxLength: 50
        MinLength: 4
        ConstraintDescription: 'Please enter a SNS topic name for alarm notifications.  Minimum length: 4, Maximum length: 50'

    SNSNotificationEmail:
        Type: String
        AllowedPattern: "^[a-zA-Z0-9+.@]*$"
        ConstraintDescription: 'Please enter notfier email address'

    CloudWatchAlarmName:
        Description: The CloudWatch Billing Alarm name 
        Default: CloudWatchBillingAlarm
        Type: String
        MaxLength: 50
        MinLength: 4
        ConstraintDescription: 'Please name For CloudWatch Alarm.  Minimum length: 4, Maximum length: 50'

    CloudWatchAlarmAmount:
        Default: 10
        Description: Defines the estimated charges threshold for when to trigger CloudWatch Billing Alarm
        Type: String
        AllowedPattern: "[0-9]+"
        MaxLength: 12
        MinLength: 1
        ConstraintDescription: 'Please enter a whole *number* (e.g. 10). Minimum length: 1, Maximum length: 12'

Resources:
    SNSTopic:
        Type: 'AWS::SNS::Topic'
        Properties:
            Subscription:
              - Endpoint: !Ref SNSNotificationEmail
                Protocol: email
            TopicName: !Ref SNSTotalEstimatedChargesTopicName

    CloudWatchAlarm:
        Type: 'AWS::CloudWatch::Alarm'
        Properties:
            AlarmName: !Ref CloudWatchAlarmName
            AlarmDescription: !Join ["", ['CloudWatch Alarm that triggers a notification via the SNS topic when the estimated charges AWS bill reach above $', !Ref CloudWatchAlarmAmount, '.']]    
            MetricName: EstimatedCharges
            Namespace: AWS/Billing
            Statistic: Maximum
            Period: '21600'
            EvaluationPeriods: '1'
            Threshold: !Ref CloudWatchAlarmAmount
            ComparisonOperator: GreaterThanOrEqualToThreshold
            AlarmActions:
              - Ref: SNSTopic
            Dimensions:
              - Name: Currency
                Value: USD
            InsufficientDataActions:
              - Ref: SNSTopic

Outputs:
    SNSTopicTotalEstimatedChargesARN:
        Description: 'SNS Topic ARN'
        Value: !Ref SNSTopic
        Export:
            Name: !Sub "${AWS::StackName}:TotalEstimatedChargesSNSTopic-ARN"

    CloudWatchAlarmURL:
        Description: 'CloudWatch Alarm URL'
        Value: !Join ["", ['https://console.aws.amazon.com/cloudwatch/home?region=',!Ref AWS::Region,'#alarmsV2:alarm/',!Ref CloudWatchAlarmName]]
        Export:
            Name: !Sub "${AWS::StackName}:CloudWatchAlarm-URL"

    CloudWatchAlarmARN:
        Description: 'CloudWatch Alarm ARN'
        Value: !GetAtt CloudWatchAlarm.Arn
        Export:
            Name: !Sub "${AWS::StackName}:TotalChargesAlarm-ARN"