AWSTemplateFormatVersion: '2010-09-09'
Description: Lambda for purging fastly cache in response to CAPI updates

Parameters:
  Stack:
    Description: Stack name
    Type: String
    Default: content-api-fastly-cache-purger
  App:
    Description: Application name
    Type: String
    Default: fastly-cache-purger
  Stage: 
    Description: Stage name
    Type: String
    AllowedValues:
      - CODE
      - PROD
    Default: CODE
  DeployBucket:
    Description: Bucket where RiffRaff uploads artifacts on deploy
    Type: String
    Default: content-api-dist
  ConfigBucket:
    Description: Bucket where app settings are stored
    Type: String
    Default: fastly-cache-purger-config
  KinesisStream:
    Description: Name of the crier kinesis stream
    Type: String
  StreamEFOConsumer:
    Description: Name of the Enhanced Fan Out consumer for the kinesis (firehose) stream
    Type: String
  AlarmTopicSSM:
    Description: 'Pointer to an SNS topic ARN for Cloudwatch alerts'
    Type: AWS::SSM::Parameter::Value<String>
    Default: /account/content-api-common/alarms/urgent-alarm-topic
  OphanAccountID:
    Description: 'AWS account/profile ID of Ophan'
    Type: AWS::SSM::Parameter::Value<String>
    Default: OphanAccountID

Conditions:
  IsProd:
    !Equals
    - !Ref Stage
    - PROD

Resources:
  Lambda:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${App}-${Stage}"
      Description: Fastly cache purger
      Runtime: java11
      Architectures:
      - arm64
      Handler: com.gu.fastly.Lambda::handle
      MemorySize: 768
      Timeout: 30
      Role: !GetAtt LambdaRole.Arn
      ReservedConcurrentExecutions: 10
      Tags:
        - Key: Stack
          Value: !Ref Stack
        - Key: Stage
          Value: !Ref Stage
        - Key: App
          Value: !Ref App
      Code:
        S3Bucket: !Ref DeployBucket
        S3Key: !Sub ${Stack}/${Stage}/${App}/${App}.zip
  LambdaKinesisEvent:
    Type: AWS::Lambda::EventSourceMapping
    Properties:
      BatchSize: 1
      EventSourceArn:
        !If
        - IsProd
        - !Sub "arn:aws:kinesis:${AWS::Region}:${AWS::AccountId}:stream/${KinesisStream}/consumer/${StreamEFOConsumer}"
        - !Sub "arn:aws:kinesis:${AWS::Region}:${AWS::AccountId}:stream/${KinesisStream}"
      FunctionName: !Ref Lambda
      StartingPosition: TRIM_HORIZON
  LambdaRole:
    Type: AWS::IAM::Role
    Properties:
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
        - arn:aws:iam::aws:policy/service-role/AWSLambdaKinesisExecutionRole
      Policies: 
        - PolicyName: ReadConfigFromBucket
          PolicyDocument:
            Statement:
              Action:
                - s3:GetObject
                - s3:ListBucket
              Resource: !Sub arn:aws:s3:::${ConfigBucket}/*
              Effect: Allow
        - PolicyName: AllowPutMetrics
          PolicyDocument:
            Statement:
              Action:
                - cloudwatch:PutMetricData
              Resource: "*"
              Effect: Allow
        - PolicyName: AllowSNSPublish
          PolicyDocument:
            Statement:
              Action:
                - sns:Publish
              Resource: "*"
              Effect: Allow
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
  DecachedContentTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: !Sub "${App}-${Stage}-decached"
      DisplayName: !Sub '${App}-${Stage}-Decached'
  DecachedContentTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      Topics:
        - !Ref DecachedContentTopic
      PolicyDocument:
        Statement:
          - Sid: OphanAccount
            Effect: Allow
            Principal:
              AWS: !Ref 'OphanAccountID'
            Action: "sns:Subscribe"
            Resource: !Ref 'DecachedContentTopic'
  IteratorAgeAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: !Sub ${Stack}-${Stage}-iterator-age-alarm
      AlarmDescription: 'Fastly Cache purger is not keeping up with the Firehose.'
      Namespace: AWS/Lambda
      Dimensions:
        - Name: FunctionName
          Value: !Ref Lambda
      MetricName: IteratorAge
      Statistic: Maximum
      Period: 60
      EvaluationPeriods: 5
      Threshold: 180000
      ComparisonOperator: GreaterThanThreshold
      AlarmActions:
        - !If [ IsProd, !Ref AlarmTopicSSM, !Ref "AWS::NoValue" ]
      InsufficientDataActions:
        - !If [ IsProd, !Ref AlarmTopicSSM, !Ref "AWS::NoValue" ]

Outputs:
  DecachedContentSNSTopicARN:
    Description: ARN of the SNS DecachedContentTopic
    Value:
      Ref: DecachedContentTopic
    Export:
      Name: !Sub "${AWS::StackName}-DecachedContentSNSTopicARN"
