cfn.yaml (305 lines of code) (raw):
AWSTemplateFormatVersion: 2010-09-09
Description: Lambda function which retrieves the latest beta version from App Store Connect.
Parameters:
Stack:
Description: Stack name
Type: String
Default: mobile
App:
Description: Application name
Type: String
Default: live-app-versions
Stage:
Description: Stage name
Type: String
AllowedValues:
- CODE
- PROD
Default: CODE
AppleAppId:
Description: The Apple id of the iOS app which will be polled against
Type: String
DeployBucket:
Description: Bucket where RiffRaff uploads artifacts on deploy
Type: String
Default: mobile-dist
Mappings:
StageVariables:
CODE:
UploadPath: reserved-paths/CODE/*-live-app/
ScheduleStatus: DISABLED
AlarmActionsEnabled: FALSE
PROD:
UploadPath: reserved-paths/*-live-app/
ScheduleStatus: ENABLED
AlarmActionsEnabled: TRUE
Resources:
ExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
Path: /
Policies:
- PolicyName: logs
PolicyDocument:
Statement:
Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: arn:aws:logs:*:*:*
- PolicyName: lambda
PolicyDocument:
Statement:
Effect: Allow
Action:
- lambda:InvokeFunction
Resource: "*"
- PolicyName: privateConfiguration
PolicyDocument:
Statement:
Effect: Allow
Action:
- ssm:GetParametersByPath
Resource: !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${Stage}/${Stack}/${App}
- PolicyName: s3BuildOutput
PolicyDocument:
Statement:
- Effect: Allow
Action:
- s3:PutObject
- s3:PutObjectAcl
- s3:GetObject
Resource: !Sub
- arn:aws:s3:::static-content-dist/${Path}*
- Path: !FindInMap [StageVariables, !Ref Stage, UploadPath]
- Effect: Allow
Action:
- s3:ListBucket
Resource: arn:aws:s3:::static-content-dist
IosDeploymentsLambda:
Type: AWS::Lambda::Function
Properties:
FunctionName: !Sub ios-deployments-${Stage}
Code:
S3Bucket:
Ref: DeployBucket
S3Key: !Sub ${Stack}/${Stage}/${App}/${App}.jar
Environment:
Variables:
Stage: !Ref Stage
Stack: !Ref Stack
App: !Ref App
APPLE_APP_ID: !Ref AppleAppId
Description: Lambda function which distributes uploaded iOS builds to beta testers.
Handler: com.gu.iosdeployments.Lambda::handler
MemorySize: 1024
Role: !GetAtt ExecutionRole.Arn
Runtime: java21
Timeout: 240
IosLiveAppVersionsLambda:
Type: AWS::Lambda::Function
Properties:
FunctionName: !Sub ios-live-app-versions-${Stage}
Code:
S3Bucket:
Ref: DeployBucket
S3Key: !Sub ${Stack}/${Stage}/${App}/${App}.jar
Environment:
Variables:
Stage: !Ref Stage
Stack: !Ref Stack
App: !Ref App
APPLE_APP_ID: !Ref AppleAppId
Description: Lambda function which retrieves the latest beta version from App Store Connect.
Handler: com.gu.liveappversions.ios.Lambda::handler
MemorySize: 1024
Role: !GetAtt ExecutionRole.Arn
Runtime: java21
Timeout: 60
AndroidLiveAppVersionsLambda:
Type: AWS::Lambda::Function
Properties:
FunctionName: !Sub android-live-app-versions-${Stage}
Code:
S3Bucket:
Ref: DeployBucket
S3Key: !Sub ${Stack}/${Stage}/${App}/${App}.jar
Environment:
Variables:
Stage: !Ref Stage
Stack: !Ref Stack
App: !Ref App
Description: Lambda function which retrieves the latest version/track information from Google Play.
Handler: com.gu.liveappversions.android.Lambda::handler
MemorySize: 1024
Role: !GetAtt ExecutionRole.Arn
Runtime: java21
Timeout: 60
PollingEvent:
Type: AWS::Events::Rule
Properties:
State: !FindInMap [StageVariables, !Ref Stage, ScheduleStatus]
Description: Triggers the lambdas in this project periodically to check for new deployments or completed releases
ScheduleExpression: rate(5 minutes)
Targets:
- Id: IosLiveAppVersionsLambda
Arn: !GetAtt IosLiveAppVersionsLambda.Arn
- Id: AndroidLiveAppVersionsLambda
Arn: !GetAtt AndroidLiveAppVersionsLambda.Arn
- Id: IosDeploymentsLambda
Arn: !GetAtt IosDeploymentsLambda.Arn
PollingEventIosLiveAppVersionsLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt IosLiveAppVersionsLambda.Arn
Principal: events.amazonaws.com
SourceArn: !GetAtt PollingEvent.Arn
PollingEventAndroidLiveAppVersionsLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt AndroidLiveAppVersionsLambda.Arn
Principal: events.amazonaws.com
SourceArn: !GetAtt PollingEvent.Arn
PollingEventIosDeploymentsLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt IosDeploymentsLambda.Arn
Principal: events.amazonaws.com
SourceArn: !GetAtt PollingEvent.Arn
IosLiveAppVersionsFailureAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
ActionsEnabled: !FindInMap [StageVariables, !Ref Stage, AlarmActionsEnabled]
AlarmActions:
- !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:mobile-server-side
OKActions:
- !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:mobile-server-side
AlarmName: !Sub Failures when retrieving or storing the latest iOS versions in ${Stage}
AlarmDescription: |
<<<Runbook|https://docs.google.com/document/d/1by6RLfo_d-6wyAp7OoQquv4tZYUR6FYhAn0GZkJtqH8/edit#heading=h.f2qd026kxlds>>>
Metrics:
- Id: e1
Label: Error percentage of lambda
Expression: "100*(m1/m2)"
- Id: m1
Label: Number of errors for lambda
MetricStat:
Metric:
MetricName: Errors
Namespace: AWS/Lambda
Dimensions:
- Name: FunctionName
Value: !Ref IosLiveAppVersionsLambda
Period: 3600
Stat: Sum
ReturnData: false
- Id: m2
Label: Number of invocations for lambda
MetricStat:
Metric:
MetricName: Invocations
Namespace: AWS/Lambda
Dimensions:
- Name: FunctionName
Value: !Ref IosLiveAppVersionsLambda
Period: 3600
Stat: Sum
ReturnData: false
ComparisonOperator: GreaterThanOrEqualToThreshold
EvaluationPeriods: 1
Threshold: 100
AndroidLiveAppVersionsFailureAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
ActionsEnabled: !FindInMap [StageVariables, !Ref Stage, AlarmActionsEnabled]
AlarmActions:
- !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:mobile-server-side
OKActions:
- !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:mobile-server-side
AlarmName: !Sub Failures when retrieving or storing the latest Android versions in ${Stage}
AlarmDescription: |
<<<Runbook|https://docs.google.com/document/d/1by6RLfo_d-6wyAp7OoQquv4tZYUR6FYhAn0GZkJtqH8/edit#heading=h.vb63w7y2on5t>>>
Metrics:
- Id: e1
Label: Error percentage of lambda
Expression: "100*(m1/m2)"
- Id: m1
Label: Number of errors for lambda
MetricStat:
Metric:
MetricName: Errors
Namespace: AWS/Lambda
Dimensions:
- Name: FunctionName
Value: !Ref AndroidLiveAppVersionsLambda
Period: 3600
Stat: Sum
ReturnData: false
- Id: m2
Label: Number of invocations for lambda
MetricStat:
Metric:
MetricName: Invocations
Namespace: AWS/Lambda
Dimensions:
- Name: FunctionName
Value: !Ref AndroidLiveAppVersionsLambda
Period: 3600
Stat: Sum
ReturnData: false
ComparisonOperator: GreaterThanOrEqualToThreshold
EvaluationPeriods: 1
Threshold: 100
IosDeploymentsFailureAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
ActionsEnabled: !FindInMap [StageVariables, !Ref Stage, AlarmActionsEnabled]
AlarmActions:
- !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:mobile-server-side
OKActions:
- !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:mobile-server-side
AlarmName: !Sub Failures when checking or updating iOS beta deployments in ${Stage}
AlarmDescription: |
<<<Runbook|https://docs.google.com/document/d/1by6RLfo_d-6wyAp7OoQquv4tZYUR6FYhAn0GZkJtqH8/edit#heading=h.fxgskya8ndu0>>>
Metrics:
- Id: e1
Label: Error percentage of lambda
Expression: "100*(m1/m2)"
- Id: m1
Label: Number of errors for lambda
MetricStat:
Metric:
MetricName: Errors
Namespace: AWS/Lambda
Dimensions:
- Name: FunctionName
Value: !Ref IosDeploymentsLambda
Period: 3600
Stat: Sum
ReturnData: false
- Id: m2
Label: Number of invocations for lambda
MetricStat:
Metric:
MetricName: Invocations
Namespace: AWS/Lambda
Dimensions:
- Name: FunctionName
Value: !Ref IosDeploymentsLambda
Period: 3600
Stat: Sum
ReturnData: false
ComparisonOperator: GreaterThanOrEqualToThreshold
EvaluationPeriods: 1
Threshold: 100