AWSTemplateFormatVersion: 2010-09-09
Description: Consumes events produced when an app receives a notification
Parameters:
  Stack:
    Description: Stack name
    Type: String
    Default: mobile-notifications
  App:
    Description: Application name
    Type: String
    Default: eventconsumer
  Stage:
    Description: Stage name
    Type: String
    AllowedValues:
    - CODE
    - PROD
    Default: CODE
  DeployBucket:
    Description: Bucket where RiffRaff uploads artifacts on deploy
    Type: String
    Default: mobile-notifications-dist
  BucketNamePrefix:
    Description: Bucket name prefix to use
    Type: String
  AthenaDatabase:
    Description: Athena Database to query
    Type: String
Mappings:
  StageVariables:
    CODE:
      BucketStage: code
    PROD:
      BucketStage: prod
Resources:
  ExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
          Action: sts:AssumeRole
      Path: /
      Policies:
      - PolicyName: logs
        PolicyDocument:
          Statement:
          - Effect: Allow
            Action: logs:CreateLogGroup
            Resource: !Sub "arn:aws:logs:eu-west-1:${AWS::AccountId}:*"
          - Effect: Allow
            Action:
            - logs:CreateLogStream
            - logs:PutLogEvents
            Resource:
            - !Sub "arn:aws:logs:eu-west-1:${AWS::AccountId}:log-group:/aws/lambda/${Stack}-${App}-athena-${Stage}:*"
      - PolicyName: Athena
        PolicyDocument:
          Statement:
            Effect: Allow
            Action:
            - athena:StartQueryExecution
            - athena:GetQueryResultsStream
            - athena:GetNamespace
            - athena:GetQueryResults
            - athena:GetQueryExecutions
            - athena:GetNamedQuery
            - athena:GetCatalogs
            - athena:GetNamespaces
            - athena:GetWorkGroup
            - athena:GetExecutionEngine
            - athena:GetQueryExecution
            - athena:GetExecutionEngines
            - athena:GetTables
            - athena:GetTable
            - athena:BatchGetNamedQuery
            - athena:BatchGetQueryExecution
            - glue:GetTable
            - glue:GetPartition
            - glue:GetPartitions
            - glue:GetDatabase
            - glue:BatchCreatePartition
            Resource: "*"
      - PolicyName: s3
        PolicyDocument:
          Statement:
            Effect: Allow
            Action:
            - s3:*
            Resource:
            - !Sub
              - arn:aws:s3:::aws-mobile-event-logs-${BucketStage}
              - BucketStage: !FindInMap [StageVariables, !Ref Stage, BucketStage]
            - !Sub
              - arn:aws:s3:::aws-mobile-event-logs-${BucketStage}/*
              - BucketStage: !FindInMap [StageVariables, !Ref Stage, BucketStage]

      - PolicyName: Dynamo
        PolicyDocument:
          Statement:
            Effect: Allow
            Action: dynamodb:*
            Resource: !Sub "arn:aws:dynamodb:eu-west-1:${AWS::AccountId}:table/mobile-notifications-reports-${Stage}"
  AthenaLambda:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub ${Stack}-${App}-athena-${Stage}
      Code:
        S3Bucket:
          Ref: DeployBucket
        S3Key: !Sub ${Stack}/${Stage}/${App}/${App}.jar
      Environment:
        Variables:
          Stage: !Ref Stage
          Stack: !Ref Stack
          App: !Ref App
          IngestLocation: !Sub
            - s3://${BucketNamePrefix}-${BucketStage}/fastly/notifications/received
            - BucketStage: !FindInMap [StageVariables, !Ref Stage, BucketStage]
          AthenaOutputLocation: !Sub
            - s3://${BucketNamePrefix}-${BucketStage}/athena
            - BucketStage: !FindInMap [StageVariables, !Ref Stage, BucketStage]
          AthenaDatabase: !Ref AthenaDatabase
      Description: Queries Athena to update Notification reports in Dynamodb
      Handler: com.gu.notifications.events.AthenaLambda::handleRequest
      MemorySize: 1024
      Role: !GetAtt ExecutionRole.Arn
      Runtime: java11
      Timeout: 120
      Tags:
        - Key: Stage
          Value: !Ref Stage
        - Key: Stack
          Value: !Ref Stack
        - Key: App
          Value: !Ref App

  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      AccessControl: Private
      BucketName: !Sub
      - ${BucketNamePrefix}-${BucketStage}
      - BucketStage: !FindInMap [StageVariables, !Ref Stage, BucketStage]
      LifecycleConfiguration:
        Rules:
          - ExpirationInDays: 21
            Status: Enabled

  AthenaLambdaScheduleEventRule:
    Type: AWS::Events::Rule
    Properties:
      ScheduleExpression: "cron(2/5 * * * ? *)"
      Targets:
        - Id: AthenaLambdaScheduleEventRuleTarget
          Arn: !GetAtt AthenaLambda.Arn
  AthenaLambdaScheduleEventPermission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !GetAtt AthenaLambda.Arn
      Action: lambda:InvokeFunction
      Principal: events.amazonaws.com
      SourceArn: !GetAtt AthenaLambdaScheduleEventRule.Arn
