---
AWSTemplateFormatVersion: '2010-09-09'
Description: CAPI podcasts-analytics lambda
Parameters:
  Stage:
    Description: Environment name
    Type: String
    Default: PROD
  ContentApiKey:
    Description: The Content API key
    Type: String
    NoEcho: true
  AlarmSnsTopic:
    Description: Alarm SNS topic
    Type: String
  FunctionName:
    Description: Name of the lambda function, because it cannot be referenced by this cloudformation even though it created the resource
    Type: String
Resources:
  RootRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
      Policies:
      - PolicyName: LambdaPolicy
        PolicyDocument:
          Statement:
          - Effect: Allow
            Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
            Resource: "*"
          - Action:
            - s3:Put*
            - s3:List*
            - s3:Get*
            - s3:Delete*
            Resource:
            - arn:aws:s3::*:content-api-dist/*
            - arn:aws:s3::*:gu-audio-logs/*
            Effect: Allow
  Lambda:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        S3Bucket: content-api-dist
        S3Key:
          Fn::Join:
          - "/"
          - - content-api
            - Ref: Stage
            - podcasts-analytics-lambda
            - podcasts-analytics-lambda.zip
      Description: CAPI podcasts analytics lambda
      Environment:
        Variables:
          CAPI_KEY: !Ref ContentApiKey
      Handler: com.gu.contentapi.Lambda::handleRequest
      MemorySize: 512
      EphemeralStorage:
        Size: 1024  #Provision 1Gb of temp storage for downloads
      Role:
        Fn::GetAtt:
        - RootRole
        - Arn
      Runtime: java11
      Timeout: 300
  LambdaInvocationAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: InvocationAlarm
      AlarmDescription: Alarm when invocation count below 200/hour
      Namespace: AWS/Lambda
      MetricName: Invocations
      Dimensions:
        - Name: FunctionName
          Value:
            !Ref Lambda
      Statistic: Sum
      ComparisonOperator: LessThanThreshold
      Threshold: 200
      Period: 60
      EvaluationPeriods: 1
      AlarmActions:
        - !Ref AlarmSnsTopic
  LambdaErrorAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: ErrorAlarm
      AlarmDescription: Alarm if the Lambda fails with an error
      Namespace: AWS/Lambda
      MetricName: Errors
      Dimensions:
        - Name: FunctionName
          Value:
            !Ref Lambda
      Statistic: Sum
      ComparisonOperator: GreaterThanThreshold
      Threshold: 0
      Period: 60
      EvaluationPeriods: 1
      TreatMissingData: notBreaching
      AlarmActions:
        - !Ref AlarmSnsTopic
  # Alarm on WARN, ERROR and FATAL metrics.
  # -ResourceLeakDetector to ensure we do not alarm on unavoidable and seemingly
  # harmless error messages from Netty - see https://github.com/aws/aws-sdk-java-v2/issues/4654
  LambdaLogWarnMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      FilterPattern: "WARN -ResourceLeakDetector"
      LogGroupName: !Sub "/aws/lambda/${FunctionName}"
      MetricTransformations:
        - MetricValue: 1
          MetricNamespace: content-api/podcasts-analytics-lambda
          MetricName: LogErrors
  LambdaLogErrorMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      FilterPattern: "ERROR -ResourceLeakDetector"
      LogGroupName: !Sub "/aws/lambda/${FunctionName}"
      MetricTransformations:
        - MetricValue: 1
          MetricNamespace: content-api/podcasts-analytics-lambda
          MetricName: LogErrors
  LambdaLogFatalMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      FilterPattern: "FATAL -ResourceLeakDetector"
      LogGroupName: !Sub "/aws/lambda/${FunctionName}"
      MetricTransformations:
        - MetricValue: 1
          MetricNamespace: content-api/podcasts-analytics-lambda
          MetricName: LogErrors
  LambdaLogErrorAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmDescription: Alarm if the Lambda logs an error
      Namespace: content-api/podcasts-analytics-lambda
      MetricName: LogErrors
      Statistic: Sum
      ComparisonOperator: GreaterThanThreshold
      Threshold: 0
      Period: 60
      EvaluationPeriods: 1
      TreatMissingData: notBreaching
      AlarmActions:
        - !Ref AlarmSnsTopic
