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