最近,我们为Sigma Cloud IDE上的无服务器项目引入了两个新的AWS Lambda事件源(触发类型): SQS队列和DynamoDB流 。 (是的,AWS在几个月前就向他们介绍了;但是我们仍然是一个很小的团队,还遇到了其他一千件事!)
在开发对这些触发器的支持时,我注意到Lambda事件源触发器配置的常见模式(是的,很明显)。 我觉得值得分享。
为什么AWS Lambda触发器搞砸了
Lambda –或更确切地说,AWS –具有一个相当奇怪且混乱的触发器架构; 轻轻地说。 对于不同的触发类型,您必须在各处进行配置。 CloudWatch Events规则的目标 ,API Gateway端点的集成 ,S3存储桶事件的通知配置等。 考虑到其他平台(例如GCP),您可以在一处配置所有东西,这真是一团糟:实际目标函数的“触发”配置。
到处都是。
如果您已经使用基础结构作为代码(IAC)服务(例如CloudFormation(CF)或Terraform(TF)) ,那么您已经知道我的意思了。 您到处都需要映射,链接,权限和其他提示,以使简单的HTTP URL正常工作。 ( SAM确实确实简化了这一点,但它有其自身的局限性 -我们已尽力避免Sigma IDE中的此类复杂性。)
考虑到AWS提供的服务的多样性及其时间表(也许毕竟,Lambda只是一个四岁的孩子 ),这也许是意料之中的。 AWS当然应该必须进行一些疯狂的黑客操作,以支持从众多服务中触发Lambda。 从而造成混乱,分散的配置。
事件源映射:隧道尽头的光?
幸运的是,最近引入的流类型触发器遵循一种常见的模式:
- 一个AWS Lambda事件源映射 ,以及
- Lambda的执行角色上的一组权限声明 ,使它可以分析,使用和确认/删除流上的消息
- 服务级别权限,允许事件源调用该函数
这样,您确切地知道应在何处配置触发器,以及如何让Lambda使用事件流。
没有更多的跳跃。
当您基于IAC(例如CloudFormation)时,这非常方便:
{ ... // event source (SQS queue) "sqsq" : { "Type" : "AWS::SQS::Queue" , "Properties" : { "DelaySeconds" : 0 , "MaximumMessageSize" : 262144 , "MessageRetentionPeriod" : 345600 , "QueueName" : "q" , "ReceiveMessageWaitTimeSeconds" : 0 , "VisibilityTimeout" : 30 } }, // event target (Lambda function) "tikjs" : { "Type" : "AWS::Lambda::Function" , "Properties" : { "FunctionName" : "tikjs" , "Description" : "Invokes functions defined in \ tik/js.js in project tik. Generated by Sigma.", ... } }, // function execution role that allows it (Lambda service) // to query SQS and remove read messages "tikjsExecutionRole" : { "Type" : "AWS::IAM::Role" , "Properties" : { "ManagedPolicyArns" : [ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" ], "AssumeRolePolicyDocument" : { "Version" : "2012-10-17" , "Statement" : [ { "Action" : [ "sts:AssumeRole" ], "Effect" : "Allow" , "Principal" : { "Service" : [ "lambda.amazonaws.com" ] } } ] }, "Policies" : [ { "PolicyName" : "tikjsPolicy" , "PolicyDocument" : { "Statement" : [ { "Effect" : "Allow" , "Action" : [ "sqs:GetQueueAttributes" , "sqs:ReceiveMessage" , "sqs:DeleteMessage" ], "Resource" : { "Fn::GetAtt" : [ "sqsq" , "Arn" ] } } ] } } ] } }, // the actual event source mapping (SQS queue -> Lambda) "sqsqTriggertikjs0" : { "Type" : "AWS::Lambda::EventSourceMapping" , "Properties" : { "BatchSize" : "10" , "EventSourceArn" : { "Fn::GetAtt" : [ "sqsq" , "Arn" ] }, "FunctionName" : { "Ref" : "tikjs" } } }, // grants permission for SQS service to invoke the Lambda // when messages are available in our queue "sqsqPermissiontikjs" : { "Type" : "AWS::Lambda::Permission" , "Properties" : { "Action" : "lambda:InvokeFunction" , "FunctionName" : { "Ref" : "tikjs" }, "SourceArn" : { "Fn::GetAtt" : [ "sqsq" , "Arn" ] }, "Principal" : "sqs.amazonaws.com" } } ... }
(实际上,这就是这篇文章的全部原因/目的。)
提示:你并不需要担心这整个IAC / CloudFormation啄-或写冗长的JSON / YAML -如果你喜欢一个完全自动化的资源管理工具去SLAppForge西格玛无服务器云IDE 。
但是...事件源映射是否已准备好参加大型比赛?
它们看起来确实很有希望,但是在我们可以在全自动的生产环境中使用它们之前,似乎事件源映射确实需要更成熟一些。
您无法通过IAC更新事件源映射。
例如,即使事件源从开始以来已经超过四年,但事件源在通过IaC(例如CloudFormation或无服务器框架)创建后仍无法更新 。 这会造成严重的麻烦; 如果更新映射配置,则需要手动删除旧的并部署新的。 第一次正确设置它,否则您将不得不进行繁琐的手动清理以使整个事情重新开始。 自动化非常重要!
The event source arn (aaa) and function (bbb) provided mapping already exists. Please update or delete the existing mapping...
听起来很老派。
还有其他一些不太明显的问题。 首先,事件源映射是由轮询机制驱动的 。 如果您的源是SQS队列,则Lambda服务将继续对其进行轮询,直到收到下一条消息为止。 尽管这完全无法控制,但这确实意味着您要为轮询支付费用 。 另外,作为一名开发人员,我不认为轮询完全适合事件驱动的无服务器范例。 当然, 一切都归结为最后的投票 ,但仍然……
最后:为什么不尝试事件源映射?
是否准备就绪,似乎事件源映射将保留下来。 随着数据流 ( Kinesis ),队列驱动的分布式处理和协调 ( SQS )和事件分类帐 ( DynamoDB Streams )的日益普及,随着时间的流逝,它们将变得越来越受欢迎。
您可以通过多种方式尝试事件源映射的工作方式: AWS控制台 , aws-cli
, CloudFormation , Serverless Framework和易于使用的图形化IDE SLAppForge Sigma 。
只需拖放即可轻松管理事件源映射!
在Sigma IDE中,您可以简单地将事件源( SQS队列 , DynamoDB表或Kinesis流 ) 拖放到Lambda函数代码的event
变量上。 Sigma将弹出一个包含可用映射配置的对话框,因此您可以轻松配置源映射行为。 您甚至可以在弹出窗口中配置一个全新的源(队列,表或流),而不使用现有的源。
部署后,Sigma将为您的新事件源自动生成所有必要的配置和权限,并为您将其发布到AWS。 全部都是完全托管,完全自动化和完全透明的。
聊够了。 让我们开始吧!
翻译自: https://www.javacodegeeks.com/2019/05/aws-lambda-source-mappings-bringing-your-triggers.html