-
Notifications
You must be signed in to change notification settings - Fork 0
/
template.yml
264 lines (250 loc) · 8.57 KB
/
template.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: AoC Telegram Bot
Parameters:
Bucket:
Type: String
Description: Package bucket name
Package:
Type: String
Description: Package file name
Version:
Type: String
Description: Package version
Resources:
# Scheduled function to processes leaderboards and invites
AocBotScheduleFunction:
Type: AWS::Serverless::Function
DependsOn:
- AocBotTable
Properties:
FunctionName: !Sub ${AWS::StackName}_AocBotSchedule
Description: !Ref Version
CodeUri:
Bucket: !Ref Bucket
Key: !Ref Package
Handler: src/leaderboards.handler
Runtime: nodejs20.x
Architectures:
- arm64
Timeout: 300
Policies:
- AWSLambdaVPCAccessExecutionRole
- AWSXrayWriteOnlyAccess
- DynamoDBCrudPolicy:
TableName: !Ref AocBotTable
- SSMParameterReadPolicy:
ParameterName: aoc-bot/advent-of-code-secret
- SSMParameterReadPolicy:
ParameterName: aoc-bot/telegram-secret
- SSMParameterReadPolicy:
ParameterName: aoc-bot/webhook-secret
# API function to process HTTP requests
AocBotApiFunction:
Type: AWS::Serverless::Function
DependsOn:
- AocBotTable
Properties:
FunctionName: !Sub ${AWS::StackName}_AocBotApi
Description: !Ref Version
CodeUri:
Bucket: !Ref Bucket
Key: !Ref Package
Handler: src/api.handler
Runtime: nodejs20.x
Architectures:
- arm64
Timeout: 300
Policies:
- AWSLambdaVPCAccessExecutionRole
- AWSXrayWriteOnlyAccess
- DynamoDBCrudPolicy:
TableName: !Ref AocBotTable
- SSMParameterReadPolicy:
ParameterName: aoc-bot/advent-of-code-secret
- SSMParameterReadPolicy:
ParameterName: aoc-bot/telegram-secret
- SSMParameterReadPolicy:
ParameterName: aoc-bot/webhook-secret
# Dynamo DB table to store all data
AocBotTable:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
- AttributeName: id
AttributeType: S
- AttributeName: sk
AttributeType: S
BillingMode: PAY_PER_REQUEST
KeySchema:
- AttributeName: id
KeyType: HASH
- AttributeName: sk
KeyType: RANGE
TableName: aoc-bot
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
# Dynamo DB backup plan
AocBotBackupPlan:
Type: AWS::Backup::BackupPlan
Properties:
BackupPlan:
BackupPlanName: AocBotBackupPlan
BackupPlanRule:
- RuleName: AocBotDecemberRule
TargetBackupVault: Default
ScheduleExpression: "cron(0 4 * DEC ? *)" # every day at 4:00am, only in December
StartWindowMinutes: 60
CompletionWindowMinutes: 180
Lifecycle:
DeleteAfterDays: 35
- RuleName: AocBotNotDecemberRule
TargetBackupVault: Default
ScheduleExpression: "cron(0 4 ? JAN-NOV 1 *)" # every week on Sunday 4:00am, January through November
StartWindowMinutes: 60
CompletionWindowMinutes: 180
Lifecycle:
DeleteAfterDays: 400
# Select resources for the backup plan
AocBotBackupSelection:
Type: AWS::Backup::BackupSelection
Properties:
BackupPlanId: !Ref AocBotBackupPlan
BackupSelection:
SelectionName: AocBotTableBackupSelection
IamRoleArn: !Sub arn:aws:iam::${AWS::AccountId}:role/service-role/AWSBackupDefaultServiceRole
Resources:
- !GetAtt AocBotTable.Arn
# Rule to regularly trigger AocBotScheduleFunction in December
AocBotDecemberRule:
Type: AWS::Events::Rule
Properties:
ScheduleExpression: cron(0/15 * * DEC ? *) # every 15 minutes, only in December
State: ENABLED
Targets:
- Arn: !GetAtt AocBotScheduleFunction.Arn
Id: AocBotRuleTarget
# Permission that allows Events to call AocBotScheduleFunction in December
AocBotDecemberSchedulePerms:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref AocBotScheduleFunction
Principal: events.amazonaws.com
SourceArn: !GetAtt AocBotDecemberRule.Arn
# Rule to regularly trigger AocBotScheduleFunction in January to November
AocBotNotDecemberRule:
Type: AWS::Events::Rule
Properties:
ScheduleExpression: cron(0 12 * JAN-NOV ? *) # at 12:00, January through November
State: ENABLED
Targets:
- Arn: !GetAtt AocBotScheduleFunction.Arn
Id: AocBotRuleTarget
# Permission that allows Events to call AocBotScheduleFunction in January to November
AocBotNotDecemberSchedulePerms:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref AocBotScheduleFunction
Principal: events.amazonaws.com
SourceArn: !GetAtt AocBotNotDecemberRule.Arn
# API Gateway to handle HTTP requests
AocBotApi:
Type: AWS::Serverless::Api
DependsOn:
- AocBotApiFunction
Properties:
StageName: Prod
MethodSettings:
- DataTraceEnabled: false
HttpMethod: "*"
LoggingLevel: INFO
MetricsEnabled: false
ResourcePath: "/*"
AccessLogSetting:
DestinationArn: !GetAtt AocBotApiLog.Arn
Format: >
{
"requestId": "$context.requestId",
"extendedRequestId": "$context.extendedRequestId",
"ip": "$context.identity.sourceIp",
"caller": "$context.identity.caller",
"user": "$context.identity.user",
"requestTime": "$context.requestTime",
"httpMethod": "$context.httpMethod",
"resourcePath": "$context.resourcePath",
"status": "$context.status",
"protocol": "$context.protocol",
"responseLength": "$context.responseLength"
}
DefinitionBody:
openapi: "3.0.1"
info:
title: !Sub "${AWS::StackName}_AocBot"
version: !Ref Version
paths:
/telegram:
post:
x-amazon-apigateway-integration:
uri: !Sub
"arn:aws:apigateway:${AWS::Region}:lambda:path\
/2015-03-31/functions/${AocBotApiFunction.Arn}/invocations"
passthroughBehavior: when_no_match
httpMethod: POST
type: aws_proxy
/start:
options:
x-amazon-apigateway-integration:
uri: !Sub
"arn:aws:apigateway:${AWS::Region}:lambda:path\
/2015-03-31/functions/${AocBotApiFunction.Arn}/invocations"
passthroughBehavior: when_no_match
httpMethod: POST
type: aws_proxy
post:
x-amazon-apigateway-integration:
uri: !Sub
"arn:aws:apigateway:${AWS::Region}:lambda:path\
/2015-03-31/functions/${AocBotApiFunction.Arn}/invocations"
passthroughBehavior: when_no_match
httpMethod: POST
type: aws_proxy
/stop:
options:
x-amazon-apigateway-integration:
uri: !Sub
"arn:aws:apigateway:${AWS::Region}:lambda:path\
/2015-03-31/functions/${AocBotApiFunction.Arn}/invocations"
passthroughBehavior: when_no_match
httpMethod: POST
type: aws_proxy
post:
x-amazon-apigateway-integration:
uri: !Sub
"arn:aws:apigateway:${AWS::Region}:lambda:path\
/2015-03-31/functions/${AocBotApiFunction.Arn}/invocations"
passthroughBehavior: when_no_match
httpMethod: POST
type: aws_proxy
x-amazon-apigateway-binary-media-types:
- "application/json"
# Permission that allows API Gateway to call AocBotApiFunction
AocBotApiPerms:
Type: AWS::Lambda::Permission
DependsOn:
- AocBotApi
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref AocBotApiFunction
Principal: apigateway.amazonaws.com
# Log group for API Gateway access logs
AocBotApiLog:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub API-Gateway-Access-Logs_${AocBotApi}
# Output the API endpoint, to be used for Telegram registration
Outputs:
Endpoint:
Description: "API Endpoint"
Value: !Sub "https://${AocBotApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"