Transform: AWS::Serverless-2016-10-31

Description: Publishes Help Centre content from Salesforce Knowledge to manage-frontend.

Parameters:
  Stage:
    Type: String
    AllowedValues:
      - PROD
      - DEV
      - CODE
    Default: CODE
  AppName:
    Type: String
    Default: manage-help-content-publisher

Conditions:
  IsProd: !Equals [ !Ref Stage, PROD ]

Resources:

  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub /aws/lambda/${AppName}-${Stage}
      RetentionInDays: 90

  Lambda:
    Type: AWS::Serverless::Function
    DependsOn: LogGroup
    Properties:
      FunctionName: !Sub ${AppName}-${Stage}
      Description: >
        Codebase: https://github.com/guardian/manage-help-content-publisher.
      Policies:
        - Statement:
            - Sid: S3BucketListPolicy
              Effect: Allow
              Action:
                - s3:ListBucket
              Resource:
                # It shouldn't be necessary to have a separate list policy but there seems to be a bug in the S3 service somewhere
                - arn:aws:s3:::manage-help-content*
        - Statement:
            - Sid: S3BucketPolicy
              Effect: Allow
              Action:
                - s3:GetObject
                - s3:PutObject
              Resource:
                - !Sub arn:aws:s3:::manage-help-content/${Stage}/*
        - Statement:
            - Sid: s3Deploy
              Effect: Allow
              Action: s3:GetObject
              Resource:
                - arn:aws:s3::*:membership-dist/*
      Handler: managehelpcontentpublisher.PublishingHandler::handleRequest
      Runtime: java11
      CodeUri:
        Bucket: membership-dist
        Key: !Sub membership/${Stage}/${AppName}/${AppName}.jar
      Environment:
        Variables:
          stage: !Ref Stage
      Timeout: 30
      MemorySize: 2048
      Events:
        ApiEvent:
          Type: Api
          Properties:
            Path: /
            Method: POST
            RestApiId:
              Ref: ApiGateway

  TakingDownLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub /aws/lambda/${AppName}-takedown-${Stage}
      RetentionInDays: 90

  TakingDownLambda:
    Type: AWS::Serverless::Function
    DependsOn: TakingDownLogGroup
    Properties:
      FunctionName: !Sub ${AppName}-takedown-${Stage}
      Description: >
        Codebase: https://github.com/guardian/manage-help-content-publisher.
      Policies:
        - Statement:
            - Sid: S3BucketListPolicy
              Effect: Allow
              Action:
                - s3:ListBucket
              Resource:
                # It shouldn't be necessary to have a separate list policy but there seems to be a bug in the S3 service somewhere
                - arn:aws:s3:::manage-help-content*
        - Statement:
            - Sid: S3BucketPolicy
              Effect: Allow
              Action:
                - s3:GetObject
                - s3:PutObject
                - s3:DeleteObject
              Resource:
                - !Sub arn:aws:s3:::manage-help-content/${Stage}/*
        - Statement:
            - Sid: s3Deploy
              Effect: Allow
              Action: s3:GetObject
              Resource:
                - arn:aws:s3::*:membership-dist/*
      Handler: managehelpcontentpublisher.TakingDownHandler::handleRequest
      Runtime: java11
      CodeUri:
        Bucket: membership-dist
        Key: !Sub membership/${Stage}/${AppName}/${AppName}.jar
      Environment:
        Variables:
          stage: !Ref Stage
      Timeout: 30
      MemorySize: 2048
      Events:
        ApiEvent:
          Type: Api
          Properties:
            Path: /{articlePath}
            Method: DELETE
            RestApiId:
              Ref: ApiGateway

  ApiGateway:
    Type: AWS::Serverless::Api
    DependsOn:
      - Lambda
      - TakingDownLambda
    Properties:
      Name: !Sub ${AppName}-${Stage}-api-gateway
      StageName: !Sub ${Stage}
      Auth:
        ApiKeyRequired: true
        UsagePlan:
          CreateUsagePlan: PER_API
          UsagePlanName: !Sub ${AppName}-${Stage}-usage-plan

  4xxApiAlarm:
    Type: AWS::CloudWatch::Alarm
    Condition: IsProd
    DependsOn: ApiGateway
    Properties:
      AlarmActions:
        - !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:alarms-handler-topic-PROD
      AlarmName: !Sub 4XX rate from ${AppName}-${Stage}
      AlarmDescription: >
        See https://github.com/guardian/manage-help-content-publisher/blob/main/README.md#Troubleshooting
        for troubleshooting tips.
      ComparisonOperator: GreaterThanThreshold
      Dimensions:
        - Name: ApiName
          Value: !Sub ${AppName}-${Stage}-api-gateway
        - Name: Stage
          Value: !Sub ${Stage}
      EvaluationPeriods: 1
      MetricName: 4XXError
      Namespace: AWS/ApiGateway
      Period: 3600
      Statistic: Sum
      Threshold: 1
      TreatMissingData: ignore

  5xxApiAlarm:
    Type: AWS::CloudWatch::Alarm
    Condition: IsProd
    DependsOn: ApiGateway
    Properties:
      AlarmActions:
        - !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:alarms-handler-topic-PROD
      AlarmName: !Sub 5XX rate from ${AppName}-${Stage}
      AlarmDescription: >
        See https://github.com/guardian/manage-help-content-publisher/blob/main/README.md#Troubleshooting
        for troubleshooting tips.
      ComparisonOperator: GreaterThanThreshold
      Dimensions:
        - Name: ApiName
          Value: !Sub ${AppName}-${Stage}-api-gateway
        - Name: Stage
          Value: !Sub ${Stage}
      EvaluationPeriods: 1
      MetricName: 5XXError
      Namespace: AWS/ApiGateway
      Period: 3600
      Statistic: Sum
      Threshold: 1
      TreatMissingData: ignore
