cfn.yaml (274 lines of code) (raw):
AWSTemplateFormatVersion: '2010-09-09'
Description: lambda to replace the content-notifications-service
Parameters:
Stack:
Description: Stack name
Type: String
Default: content-api-mobile-notifications
App:
Description: Application name
Type: String
Default: mobile-notifications-content
Stage:
Description: Stage name
Type: String
AllowedValues:
- CODE
- PROD
Default: CODE
DeployBucket:
Description: S3 Bucket where RiffRaff uploads artifacts on deploy
Type: String
Default: content-api-dist
MobileAccountId:
Description: Account ID of the gu moble account which
Type: String
Default: 201359054765
CrossAccountBaseRoleName:
Description: Base constituent name of the mobile account roles to assume
Type: String
Default: mobile-content-notifications-lambda-cross-account
ConfigurationBucket:
Description: S3 Bucket containing app configuration
Type: String
Default: mobile-notifications-dist
KinesisStreamName:
Description: Capi kinesis stream
Type: String
Default: content-api-firehose-v2
BuildId:
Description: Tag to be used for the image URL, e.g. riff raff build id
Type: String
Default: dev
SharedResourcesStack:
Description: Mobile notification content shared resources, e.g ecr repositories
Type: String
Default: mobile-notifications-shared-resources
Resources:
ExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
Path: /
Policies:
- PolicyName: assume-mobile-ssm-read-config-role
PolicyDocument:
Statement:
Effect: Allow
Action: sts:AssumeRole
Resource: !Sub arn:aws:iam::${MobileAccountId}:role/${CrossAccountBaseRoleName}-ssm-${Stage}
- PolicyName: assume-mobile-dynamo-role
PolicyDocument:
Statement:
Effect: Allow
Action: sts:AssumeRole
Resource: !Sub arn:aws:iam::${MobileAccountId}:role/${CrossAccountBaseRoleName}-dynamo-${Stage}
- PolicyName: logs
PolicyDocument:
Statement:
Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: "*"
- PolicyName: invoke-lambda
PolicyDocument:
Statement:
Effect: Allow
Action:
- lambda:InvokeFunction
Resource: "*"
- PolicyName: iam-read-and-assume
PolicyDocument:
Statement:
Effect: Allow
Action:
- iam:PassRole
- iam:GenerateCredentialReport
- iam:Get*
- iam:List*
Resource: "*"
- PolicyName: kinesis-read
PolicyDocument:
Statement:
Effect: Allow
Action:
- Kinesis:DescribeStream
- Kinesis:GetRecords
- Kinesis:GetShardIterator
- Kinesis:ListStream
Resource: "*"
- PolicyName: cloudwatch-put-metric-daata
PolicyDocument:
Statement:
Effect: Allow
Action:
- cloudwatch:PutMetricData
Resource: "*"
ContentLambdaV2:
Type: AWS::Lambda::Function
Properties:
FunctionName: !Sub ${App}-${Stage}-v2
PackageType: Image
Code:
ImageUri:
Fn::Join:
- ':'
- - Fn::ImportValue: !Sub ${SharedResourcesStack}-ContentLambdaContainerRepositoryUri
- !Ref BuildId
Environment:
Variables:
CrossAccountSsmReadingRole: !Sub arn:aws:iam::${MobileAccountId}:role/${CrossAccountBaseRoleName}-ssm-${Stage}
App: !Sub ${App}
Stack: !Sub ${Stack}
Stage: !Sub ${Stage}
Description: Lambda to send notification when new content is published
MemorySize: 4096
Role: !GetAtt ExecutionRole.Arn
Timeout: 60
ContentEventV2Source:
Type: AWS::Lambda::EventSourceMapping
Properties:
FunctionName: !Ref ContentLambdaV2
Enabled: true
EventSourceArn: !Sub arn:aws:kinesis:${AWS::Region}:${AWS::AccountId}:stream/${KinesisStreamName}-${Stage}
StartingPosition: LATEST
BisectBatchOnFunctionError: true
contentLambdaErrorPercentageAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
ActionsEnabled: true
AlarmActions:
- !Sub arn:aws:sns:${AWS::Region}:${MobileAccountId}:mobile-server-side
AlarmName:
Fn::Join:
- '-'
- - 'contentLambdaErrorPercentageAlarm'
- !Ref Stage
AlarmDescription: 'Triggers if mobile-notifications-content lambda does not execute successfully. Note: this lambda is hosted in the CAPI account. Impact - Users that are subscribed to tags or contributors on their mobile device may not be getting the latest updates'
ComparisonOperator: GreaterThanThreshold
EvaluationPeriods: 1
Metrics:
- Expression: 100*m1/m2
Id: expr_1
Label:
Fn::Join:
- ""
- - "Error % of "
- Ref: ContentLambdaV2
- Id: m1
MetricStat:
Metric:
Dimensions:
- Name: FunctionName
Value:
Ref: ContentLambdaV2
MetricName: Errors
Namespace: AWS/Lambda
Period: 60
Stat: Sum
ReturnData: false
- Id: m2
MetricStat:
Metric:
Dimensions:
- Name: FunctionName
Value:
Ref: ContentLambdaV2
MetricName: Invocations
Namespace: AWS/Lambda
Period: 60
Stat: Sum
ReturnData: false
OKActions:
- !Sub arn:aws:sns:${AWS::Region}:${MobileAccountId}:mobile-server-side
Threshold: 1
TreatMissingData: notBreaching
DependsOn: ContentLambdaV2
LiveBlogLambdaV2:
Type: AWS::Lambda::Function
Properties:
FunctionName: !Sub ${App}-liveblogs-${Stage}-v2
PackageType: Image
Code:
ImageUri:
Fn::Join:
- ':'
- - Fn::ImportValue: !Sub ${SharedResourcesStack}-LiveblogsLambdaContainerRepositoryUri
- !Ref BuildId
Environment:
Variables:
CrossAccountSsmReadingRole: !Sub arn:aws:iam::${MobileAccountId}:role/${CrossAccountBaseRoleName}-ssm-${Stage}
App: !Sub ${App}
Stack: !Sub ${Stack}
Stage: !Sub ${Stage}
Description: Lambda that sends push notifications when new key events are published on a liveblog
MemorySize: 4096
Role: !GetAtt ExecutionRole.Arn
Timeout: 60
LiveBlogEventSourceV2:
Type: AWS::Lambda::EventSourceMapping
Properties:
FunctionName: !Ref LiveBlogLambdaV2
Enabled: true
EventSourceArn: !Sub arn:aws:kinesis:${AWS::Region}:${AWS::AccountId}:stream/${KinesisStreamName}-${Stage}
StartingPosition: LATEST
BisectBatchOnFunctionError: true
liveBlogLambdaErrorPercentageAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
ActionsEnabled: true
AlarmActions:
- !Sub arn:aws:sns:${AWS::Region}:${MobileAccountId}:mobile-server-side
AlarmName:
Fn::Join:
- '-'
- - 'liveblogLambdaErrorPercentageAlarm'
- !Ref Stage
AlarmDescription: 'Triggers if mobile-notifications-content-liveblogs lambda does not execute successfully. Note: this lambda is hosted in the CAPI account. Impact - Users that are subscribed to liveblog notifications may not be getting the latest updates'
ComparisonOperator: GreaterThanThreshold
EvaluationPeriods: 1
Metrics:
- Expression: 100*m1/m2
Id: expr_1
Label:
Fn::Join:
- ""
- - "Error % of "
- Ref: LiveBlogLambdaV2
- Id: m1
MetricStat:
Metric:
Dimensions:
- Name: FunctionName
Value:
Ref: LiveBlogLambdaV2
MetricName: Errors
Namespace: AWS/Lambda
Period: 60
Stat: Sum
ReturnData: false
- Id: m2
MetricStat:
Metric:
Dimensions:
- Name: FunctionName
Value:
Ref: LiveBlogLambdaV2
MetricName: Invocations
Namespace: AWS/Lambda
Period: 60
Stat: Sum
ReturnData: false
OKActions:
- !Sub arn:aws:sns:${AWS::Region}:${MobileAccountId}:mobile-server-side
Threshold: 1
TreatMissingData: notBreaching
DependsOn: LiveBlogLambdaV2