---
AWSTemplateFormatVersion: "2010-09-09"
Description: CloudFormation to create cloudwath alarms based on metrics. IPSEC

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
    - Label:
        default: Configuration
      Parameters:
        - LogGroupName
        - EmailAddress

Parameters:
  LogGroupName:
    Description: Name of the Log Group (Log GroupName can only include letters (A-Z and a-z), numbers (0-9), dashes, underscores, and periods)
    Type: String
  EmailAddress:
    Description: email to create SNS topic
    Type: String

Resources:
  CWLoggingRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - "ec2.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      Path: "/"
      Policies:
        - PolicyName: CloudWatchAccessPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: "Allow"
                Action:
                  - "cloudwatch:PutMetricData"
                  - "logs:PutLogEvents"
                  - "logs:DescribeLogStreams"
                  - "logs:DescribeLogGroups"
                  - "logs:CreateLogStream"
                  - "logs:CreateLogGroup"
                  - "logs:PutRetentionPolicy"
                Resource: "*"
              - Effect: "Allow"
                Action:
                  - "ssm:GetParameter"
                Resource: "arn:aws:ssm:*:*:parameter/AmazonCloudWatch-*"
        - PolicyName: CloudwatchIAMaccessPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: "Allow"
                Resource: "arn:aws:logs:*:*:*"
                Action:
                  - "ec2:RunInstances"
                  - "ec2:DescribeVolumes"
                  - "ec2:DescribeTags"
                  - "ec2:AssociateIamInstanceProfile"
                  - "ec2:ReplaceIamInstanceProfileAssociation"

  VNS3InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles:
        - !Ref CWLoggingRole

  CWLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Ref LogGroupName

  LogStream2:
    Type: AWS::Logs::LogStream
    Properties:
      LogGroupName: !Ref CWLogGroup
      LogStreamName: syslog


  noproposalchosenMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      LogGroupName: !Ref CWLogGroup
      FilterPattern: "NO_PROPOSAL_CHOSEN"
      MetricTransformations:
      - MetricValue: 1
        MetricNamespace: VNS3cwMetrics
        MetricName: "no proposal metric"
  errorMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      LogGroupName: !Ref CWLogGroup
      FilterPattern: "ERROR"
      MetricTransformations:
      - MetricValue: 1
        MetricNamespace: VNS3cwMetrics
        MetricName: "error metric"
  isdownMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      LogGroupName: !Ref CWLogGroup
      FilterPattern: "is_down"
      MetricTransformations:
      - MetricValue: 1
        MetricNamespace: VNS3cwMetrics
        MetricName: "tunnel down metric"
  invalidspiMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      LogGroupName: !Ref CWLogGroup
      FilterPattern: "INVALID_SPI"
      MetricTransformations:
      - MetricValue: 1
        MetricNamespace: VNS3cwMetrics
        MetricName: "invalid SPI metric"
  invalidIDMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      LogGroupName: !Ref CWLogGroup
      FilterPattern: "INVALID_ID"
      MetricTransformations:
      - MetricValue: 1
        MetricNamespace: VNS3cwMetrics
        MetricName: "INVALID_ID metric"
  dpdMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      LogGroupName: !Ref CWLogGroup
      FilterPattern: "DPD action"
      MetricTransformations:
      - MetricValue: 1
        MetricNamespace: VNS3cwMetrics
        MetricName: "DPD metric"
  retransmissionMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      LogGroupName: !Ref CWLogGroup
      FilterPattern: "retransmission will wait 2 seconds"
      MetricTransformations:
      - MetricValue: 1
        MetricNamespace: VNS3cwMetrics
        MetricName: "retransmission metric"
  tunlogMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      LogGroupName: !Ref CWLogGroup
      FilterPattern: "TLS Error"
      MetricTransformations:
      - MetricValue: 1
        MetricNamespace: VNS3cwMetrics
        MetricName: "tunlog metric"
  PSKmismatchMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      LogGroupName: !Ref CWLogGroup
      FilterPattern: "preshared secret"
      MetricTransformations:
      - MetricValue: 1
        MetricNamespace: VNS3cwMetrics
        MetricName: "PSK mismatch"

  noproposalAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      ActionsEnabled: true
      AlarmActions:
      - !Ref 'vns3AlarmNotificationTopic'
      AlarmName: "NoProposalChosenAlarm"
      ComparisonOperator: GreaterThanOrEqualToThreshold
      DatapointsToAlarm: 1
      EvaluationPeriods: 1
      Statistic: Sum
      Period: 30
      Threshold: 1
      TreatMissingData: notBreaching
      MetricName: "no proposal metric"
      Namespace: VNS3cwMetrics
##      InsufficientDataActions:
##        - Ref: vns3AlarmNotificationTopic
#      OKActions:
#        - !Ref: vns3AlarmNotificationTopic
  errorAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      ActionsEnabled: true
      AlarmActions:
      - !Ref 'vns3AlarmNotificationTopic'
      AlarmName: "error in logs Alarm"
      ComparisonOperator: GreaterThanOrEqualToThreshold
      DatapointsToAlarm: 1
      EvaluationPeriods: 1
      Statistic: Sum
      Period: 60
      Threshold: 3
      TreatMissingData: notBreaching
      MetricName: "error metric"
      Namespace: VNS3cwMetrics
  tunneldownAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      ActionsEnabled: true
      AlarmActions:
      - !Ref 'vns3AlarmNotificationTopic'
      AlarmName: "tunnel down alarm"
      ComparisonOperator: GreaterThanThreshold
      DatapointsToAlarm: 1
      EvaluationPeriods: 1
      Statistic: Sum
      Period: 30
      Threshold: 0
      TreatMissingData: notBreaching
      MetricName: "tunnel down metric"
      Namespace: VNS3cwMetrics
  invalidspiAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      ActionsEnabled: true
      AlarmActions:
      - !Ref 'vns3AlarmNotificationTopic'
      AlarmName: "INVALID_SPI in logs alarm"
      ComparisonOperator: GreaterThanOrEqualToThreshold
      DatapointsToAlarm: 1
      EvaluationPeriods: 1
      Statistic: Sum
      Period: 30
      Threshold: 1
      TreatMissingData: notBreaching
      MetricName: "invalid SPI metric"
      Namespace: VNS3cwMetrics
  dpdAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      ActionsEnabled: true
      AlarmActions:
      - !Ref 'vns3AlarmNotificationTopic'
      AlarmName: "DPD alarm"
      ComparisonOperator: GreaterThanThreshold
      DatapointsToAlarm: 1
      EvaluationPeriods: 1
      Statistic: Sum
      Period: 10
      Threshold: 0
      TreatMissingData: notBreaching
      MetricName: "DPD metric"
      Namespace: VNS3cwMetrics
  retransmissionAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      ActionsEnabled: true
      AlarmActions:
      - !Ref 'vns3AlarmNotificationTopic'
      AlarmName: "retransmission alarm"
      ComparisonOperator: GreaterThanThreshold
      DatapointsToAlarm: 1
      EvaluationPeriods: 1
      Statistic: Sum
      Period: 10
      Threshold: 2
      TreatMissingData: notBreaching
      MetricName: "retransmission metric"
      Namespace: VNS3cwMetrics
  invalididAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      ActionsEnabled: true
      AlarmActions:
      - !Ref 'vns3AlarmNotificationTopic'
      AlarmName: "invalid_ID alarm"
      ComparisonOperator: GreaterThanThreshold
      DatapointsToAlarm: 1
      EvaluationPeriods: 1
      Statistic: Sum
      Period: 10
      Threshold: 0
      TreatMissingData: notBreaching
      MetricName: "INVALID_ID metric"
      Namespace: VNS3cwMetrics
  tunlogAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      ActionsEnabled: true
      AlarmActions:
      - !Ref 'vns3AlarmNotificationTopic'
      AlarmName: "overlay client trying to connect ERROR"
      ComparisonOperator: GreaterThanOrEqualToThreshold
      DatapointsToAlarm: 1
      EvaluationPeriods: 1
      Statistic: Sum
      Period: 240
      Threshold: 3
      TreatMissingData: notBreaching
      MetricName: "tunlog metric"
      Namespace: VNS3cwMetrics
  PSKmismatchAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      ActionsEnabled: true
      AlarmActions:
      - !Ref 'vns3AlarmNotificationTopic'
      AlarmName: "PSK mismatch in logs alarm"
      ComparisonOperator: GreaterThanOrEqualToThreshold
      DatapointsToAlarm: 1
      EvaluationPeriods: 1
      Statistic: Sum
      Period: 30
      Threshold: 1
      TreatMissingData: notBreaching
      MetricName: "PSK mismatch"
      Namespace: VNS3cwMetrics

  vns3AlarmNotificationTopic:
    Type: AWS::SNS::Topic
    Properties:
      Subscription:
      - Endpoint:
          Ref:  EmailAddress
        Protocol: email


Outputs:
  RoleId:
    Description: The Logical ID of the IAM role
    Value: !Ref CWLoggingRole
  RoleArn:
    Description: The Arn of the role
    Value: !GetAtt [CWLoggingRole, Arn]
  TopicArn:
    Description: Arn of the topic
    Value: !Ref noproposalchosenMetricFilter
