cloudformation.yaml (155 lines of code) (raw):

--- 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