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