AWSTemplateFormatVersion: 2010-09-09 Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: "Probe Information" Parameters: - resourceArn - probeFQDN - probeSearchString - probeResourcePath - probeType - probePort - probeHealthCheckRegions - UID - Label: default: "Notifications" Parameters: - SNSTopicNotifications - Label: default: "Metric #1" Parameters: - Metric1Name - Metric1Threshold - Metric1Statistic - Label: default: "Metric #2" Parameters: - Metric2Name - Metric2Threshold - Metric2Statistic Parameters: resourceArn: Type: String resourceId: Type: String probeFQDN: Type: String Description: DNS name for Instance, this can be a custom DNS name or the AWS provided DNS name UID: Type: String Default: 1234 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: 85 MinValue: 1 MaxValue: 100 Metric2Threshold: Type: Number Default: 1000 Description: Default represents 1 Gb/s for 1 minute straight 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: "Alarm has a dynamically generated name unique per resources" Properties: AlarmName: !Join ["-", ["DDosDetected", !Ref "resourceId"]] ActionsEnabled: True AlarmActions: - !If [AlarmActionFlag, !Ref "SNSTopicNotifications", !Ref "AWS::NoValue"] MetricName: DDoSDetected Namespace: AWS/DDoSProtection Statistic: Sum Dimensions: - Name: ResourceArn Value: !Ref "resourceArn" 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 "resourceArn"]] Alarm1: Type: AWS::CloudWatch::Alarm Metadata: cfn_nag: rules_to_suppress: - id: W28 reason: "Alarm has a dynamically generated name unique per resources" Properties: AlarmName: !Join ["-", [!Ref "Metric1Name", !Ref "resourceArn"]] ActionsEnabled: True AlarmActions: - !If [AlarmActionFlag, !Ref "SNSTopicNotifications", !Ref "AWS::NoValue"] MetricName: !Ref "Metric1Name" Namespace: AWS/EC2 Statistic: !Ref "Metric1Statistic" Dimensions: - Name: InstanceId Value: !Ref "resourceId" 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 "resourceArn"]] Alarm2: Type: AWS::CloudWatch::Alarm Metadata: cfn_nag: rules_to_suppress: - id: W28 reason: "Alarm has a dynamically generated name unique per resources" Properties: AlarmName: !Join ["-", [!Ref "Metric2Name", !Ref "resourceArn"]] ActionsEnabled: True AlarmActions: - !If [AlarmActionFlag, !Ref SNSTopicNotifications, !Ref "AWS::NoValue"] MetricName: !Ref "Metric2Name" Namespace: AWS/EC2 Statistic: !Ref "Metric2Statistic" Dimensions: - Name: InstanceId Value: !Ref "resourceId" 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: !If [ProbePathFlag, !Ref "probeResourcePath", !Ref "AWS::NoValue"] FullyQualifiedDomainName: !Ref "probeFQDN" SearchString: !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 "resourceArn", !Ref "resourceArn"]] CalculatedHealthCheck: Type: 'AWS::Route53::HealthCheck' DependsOn: - Metric1HealthCheck - Metric2HealthCheck - ProbeHealthCheck Properties: HealthCheckConfig: Type: CALCULATED HealthThreshold: 2 ChildHealthChecks: - !Ref Metric1HealthCheck - !Ref Metric2HealthCheck - !Ref ProbeHealthCheck HealthCheckTags: - Key: Name Value: !Join ["-", ["CalculatedHC", !Ref "resourceId"]] ShieldAssociation: Type: Custom::ShieldProtectionHealthCheck DependsOn: - CalculatedHealthCheck Properties: ServiceToken: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:config-proactive-engagement-${AWS::Region}" ResourceArn: !Ref resourceArn CalculatedHCId: !Ref CalculatedHealthCheck Outputs: CalculatedHealthCheckId: Value: !Ref CalculatedHealthCheck