-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathsqs-to-lambda.yml
130 lines (116 loc) · 4.56 KB
/
sqs-to-lambda.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
Description: |
Creates a Lambda function that invokes other Lambda functions with
SQS events.
Parameters:
QueueToFunctionMapping:
Description: |
The list of SQS queue URLs and corresponding Lambda function
names. Separate queue urls, function names, and pairs with commas:
<queue_url_1>,<function_1>,<queue_url_2>,<function_2>.
There must be an odd number of commas.
Type: String
Frequency:
Description: |
How often you want the specified SQS queues checked. If you choose
"Continuous", a Lambda function will be constantly running, waiting for
items in the queue. If you choose "1Minute", the Lambda function will
only run every minute and check every queue. This can result in drastically
reduced Lambda cost, at the expense of waiting up to a minute for items
to become visibile in the queue before being processed by your functions.
Type: String
Default: Continuous
AllowedValues:
- Continuous
- 1Minute
Outputs: {}
Conditions:
Enable1MinutePoll: !Equals [!Ref Frequency, 1Minute]
Enable5MinutePoll: !Equals [!Ref Frequency, Continuous]
Resources:
### IAM Setup
SQSToLambdaRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: lambda-to-sqs-policy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- sqs:ReceiveMessage
Resource:
# TODO: Should we list the configured queues and functions here?
# Will blank ones cause any problems? One problem is that queues
# are supplied with URLs, and functions with names. (No ARNs.)
- "*"
- Effect: Allow
Action:
- lambda:Invoke*
Resource:
- "*"
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: arn:aws:logs:*:*:*
### CloudWatch Event
CloudWatchEvent1Minute:
Type: AWS::Events::Rule
Condition: Enable1MinutePoll
Properties:
ScheduleExpression: cron(* * * * ? *)
Targets:
- Arn: !GetAtt [SQSToLambdaFunction, Arn]
Id: !Ref SQSToLambdaFunction
CloudWatchEvent5Minute:
Type: AWS::Events::Rule
Condition: Enable5MinutePoll
Properties:
ScheduleExpression: cron(0/5 * * * ? *)
Targets:
- Arn: !GetAtt [SQSToLambdaFunction, Arn]
Id: !Ref SQSToLambdaFunction
### Lambda Function
SQSToLambdaFunctionPermission1Minute:
Type: AWS::Lambda::Permission
Condition: Enable1MinutePoll
Properties:
Action: lambda:InvokeFunction
FunctionName:
Ref: SQSToLambdaFunction
Principal: events.amazonaws.com
SourceArn: !GetAtt [CloudWatchEvent1Minute, Arn]
SQSToLambdaFunctionPermission5Minute:
Type: AWS::Lambda::Permission
Condition: Enable5MinutePoll
Properties:
Action: lambda:InvokeFunction
FunctionName:
Ref: SQSToLambdaFunction
Principal: events.amazonaws.com
SourceArn: !GetAtt [CloudWatchEvent5Minute, Arn]
SQSToLambdaFunction:
Type: AWS::Lambda::Function
Properties:
Description: Invokes Lambda functions with items from SQS queues.
Handler: index.handler
MemorySize: 128
Role: !GetAtt [SQSToLambdaRole, Arn]
Runtime: nodejs
Timeout: 300
Code:
ZipFile:
Fn::Sub: |
var CONFIG = "${QueueToFunctionMapping}".split(",");
var ONCE = "${Frequency}" === "1Minute";
function e(n,i,t,a){return t()<5e3?a():""==n||""==i?a():void s.receiveMessage({QueueUrl:n,MaxNumberOfMessages:1,WaitTimeSeconds:1},function(s,g){return s?(console.log(s),a()):g.Messages&&0!==g.Messages.length?void o.invoke({FunctionName:i,InvocationType:"Event",Payload:JSON.stringify({source:"aws.sqs",QueueUrl:n,Message:g.Messages[0]})},function(s){return s?(console.log(s),a()):e(n,i,t,a)}):r?a():e(n,i,t,a)})}var n=require("aws-sdk"),s=new n.SQS,o=new n.Lambda,i=CONFIG,r=ONCE;exports.handler=function(n,s){if(0===i.length)return s.done();for(var o=i.length/2,r=function(){o-=1,0==o&&(console.log("exiting"),s.done())},t=0;t<i.length;t+=2)e(i[t],i[t+1],s.getRemainingTimeInMillis,r)};