--- AWSTemplateFormatVersion: 2010-09-09 Parameters: InstanceId: Type: String Default: i-0678a248873175675 probeFQDN: Type: String Description: DNS name for Instance, this can be a custom DNS name or the AWS provided DNS name probeSearchString: Type: String Default: '' probeResourcePath: Type: String Default: Description: Optional - Specify for Route 53 Probe health check to target a specific path other than the root site probeType: Type: String Default: TCP AllowedValues: - HTTPS - HTTP - HTTPSTRMATCH - HTTPSSTRMATCH - TCP probePort: Type: String Default: probeHealthCheckRegions: Type: CommaDelimitedList Default: us-east-1,us-west-2,eu-west-1 Description: "Comma separated list of regions to complete Route 53 health checks from list of us-east-1, us-west-1, us-west-2, eu-west-1, ap-southeast-1, ap-southeast-2, ap-northeast-1, sa-east-1" SNSTopicNotifications: Type: String Default: Metric1Name: Type: String Default: CPUUtilization Metric2Name: Type: String Default: NetworkIn Metric1Threshold: Type: Number Default: 0.85 MinValue: 0.01 MaxValue: 1 Metric2Threshold: Type: Number Default: 1000 Description: Default represents 1 Gb/s for 1 minute straight Default: 64424509440 MinValue: 0 Metric1Statistic: Type: String Default: Average AllowedValues: - Average - Sum - Minimum - Maximum Metric2Statistic: Type: String Default: Sum AllowedValues: - Average - Sum - Minimum - Maximum Conditions: AlarmActionFlag: !Not [!Equals [!Ref SNSTopicNotifications, '']] SearchStringFlag: !Or [!Equals [!Ref probeType, 'HTTPSSTRMATCH'],!Equals [!Ref probeType, 'HTTPSTRMATCH']] ProbePathFlag: !Not [!Equals [!Ref probeResourcePath, '']] probePortFlag: !Not [!Equals [!Ref probePort, '']] Mappings: ProbeMap: Port: "TCP": "80" "HTTPS": "443" "HTTP": "80" "HTTPSSTRMATCH": "443" "HTTPSTRMATCH": "80" probeTypeMap: "TCP": "TCP" "HTTPS": "HTTPS" "HTTP": "HTTP" "HTTPSSTRMATCH": "HTTPS_STR_MATCH" "HTTPSTRMATCH": "HTTP_STR_MATCH" SNIEnabled: "TCP": False "HTTPS": True "HTTP": False "HTTPSSTRMATCH": True "HTTPSTRMATCH": False Resources: DDOSAlarm: Type: AWS::CloudWatch::Alarm Metadata: cfn_nag: rules_to_suppress: - id: W28 reason: "Exact Name is important, Replacement occurs correctly in this configuration" Properties: AlarmName: !Join ["-", ["DDosDetected", !Ref InstanceId]] ActionsEnabled: True AlarmActions: - Fn::If [ AlarmActionFlag, !Ref "SNSTopicNotifications", !Ref "AWS::NoValue" ] MetricName: DDoSDetected Namespace: AWS/DDoSProtection Statistic: Sum Dimensions: - Name: ResourceArn Value: !Ref InstanceId Period: 60 EvaluationPeriods: 20 DatapointsToAlarm: 1 Threshold: 1 ComparisonOperator: GreaterThanOrEqualToThreshold TreatMissingData: notBreaching Metric1HealthCheck: Type: 'AWS::Route53::HealthCheck' Properties: HealthCheckConfig: Type: CLOUDWATCH_METRIC AlarmIdentifier: Region: !Ref AWS::Region Name: !Ref Alarm1 HealthCheckTags: - Key: Name Value: !Join ["-", [!Ref Metric1Name, !Ref InstanceId]] Alarm1: Type: AWS::CloudWatch::Alarm Metadata: cfn_nag: rules_to_suppress: - id: W28 reason: "Exact Name is important, Replacement occurs correctly in this configuration" Properties: AlarmName: !Join ["-", [!Ref Metric1Name, !Ref InstanceId]] ActionsEnabled: True AlarmActions: - Fn::If [AlarmActionFlag, !Ref SNSTopicNotifications, !Ref AWS::NoValue] MetricName: !Ref Metric1Name Namespace: AWS/EC2 Statistic: !Ref Metric1Statistic Dimensions: - Name: InstanceId Value: !Ref InstanceId Period: 60 EvaluationPeriods: 20 DatapointsToAlarm: 1 Threshold: !Ref Metric1Threshold ComparisonOperator: GreaterThanOrEqualToThreshold TreatMissingData: notBreaching Metric2HealthCheck: Type: 'AWS::Route53::HealthCheck' Properties: HealthCheckConfig: Type: CLOUDWATCH_METRIC AlarmIdentifier: Region: !Ref AWS::Region Name: !Ref Alarm2 HealthCheckTags: - Key: Name Value: !Join ["-", [!Ref Metric2Name, !Ref InstanceId]] Alarm2: Type: AWS::CloudWatch::Alarm Metadata: cfn_nag: rules_to_suppress: - id: W28 reason: "Exact Name is important, Replacement occurs correctly in this configuration" Properties: AlarmName: !Join ["-", [!Ref Metric2Name, !Ref InstanceId]] ActionsEnabled: True AlarmActions: - Fn::If [AlarmActionFlag, !Ref SNSTopicNotifications, !Ref AWS::NoValue] MetricName: !Ref Metric2Name Namespace: AWS/EC2 Statistic: !Ref Metric2Statistic Dimensions: - Name: InstanceId Value: !Ref InstanceId Period: 60 EvaluationPeriods: 20 DatapointsToAlarm: 1 Threshold: !Ref Metric2Threshold ComparisonOperator: GreaterThanOrEqualToThreshold TreatMissingData: notBreaching ProbeHealthCheck: Type: AWS::Route53::HealthCheck Properties: HealthCheckConfig: Type: !FindInMap [ProbeMap, "probeTypeMap", !Ref probeType] ResourcePath: Fn::If [ProbePathFlag, !Ref probeResourcePath, !Ref AWS::NoValue] FullyQualifiedDomainName: !Ref probeFQDN SearchString: Fn::If [SearchStringFlag, !Ref probeSearchString, !Ref AWS::NoValue] Port: !If [probePortFlag,!Ref probePort,!FindInMap [ProbeMap,"Port", !Ref probeType]] EnableSNI: !FindInMap [ProbeMap, "SNIEnabled", !Ref probeType] Regions: !Ref probeHealthCheckRegions HealthCheckTags: - Key: Name Value: !Join ["-", ["Probe", !Ref InstanceId, !Ref InstanceId]] CalculatedHealthCheck: Type: 'AWS::Route53::HealthCheck' Properties: HealthCheckConfig: Type: CALCULATED HealthThreshold: 2 ChildHealthChecks: - !Ref Metric1HealthCheck - !Ref Metric2HealthCheck - !Ref ProbeHealthCheck HealthCheckTags: - Key: Name Value: !Join ["-", ["CalculatedHC", !Ref InstanceId]] Outputs: CalculatedHealthCheckId: Value: !Ref CalculatedHealthCheck