一切始于埃及人在一个木框上滑动几块大理石以简单的算术使其大脑放松。 或许是希腊人发明了Antikythera机制来追踪行星的运动至每千年2度的精度 。 无论哪种方式,计算都已经走了很长一段路:查尔斯·巴贝奇的分析引擎 ,艾伦·图灵的Enigma-breaker , 将人送上月球的美国国家航空航天局的袖珍计算器 ,深蓝击败国际象棋大师加里·卡斯帕罗夫( Garry Kasparov)。 与此相应,软件应用程序范例也发生了巨大变化:从无(基于纯硬件的编程),整体式,模块化,SOA,云到现在无服务器。
此时,“无服务器”通常表示FaaS(功能即服务); 从流行度和采用角度来看,FaaS和字面意思是AWS Lambda 。 因此,声称无服务器开发的普及与lambda的易用性成正比并不夸张。
好吧,lambda 自2015年以来就已经存在,已经集成到许多AWS生态系统中,并且已有数百(即使不是数千)公司在生产中使用。 所以lambda应该非常直观且易于使用,对吗?
好吧,至少在我看来,这似乎不是。 我的案例是AWS的官方示例之一,我不太确定lambda是否足够友好,足以让新手了解图片。
首先,我想实现AWS自己的缩略图创建用例, 而不遵循他们自己的指南 ,以了解我能走多远。
作为程序员,我自然而然地开始使用Lambda管理控制台 。 该代码已经由慷慨的AWS专家编写 ,那么为什么要重新发明轮子呢? 复制,粘贴,保存,运行。 da!
嗯,看来我需要长大一点。
坦率地说, “创建功能”向导非常醒目。 有这么多现成的蓝图。 太遗憾了,它还没有S3缩略图生成示例,或者这个故事可能就在这里结束!
因此,我只是使用了一个名为s3-thumbnail-generator
的好名字,选择了“从头开始创作”选项。
哦,等等,这是什么“角色”? 这也是必需的。 幸运的是,它具有“从模板创建新角色”选项,这可以节省我的时间。 (我在“选择现有角色”下没有任何选择,而且我还太年轻,无法“创建自定义角色”。)
别紧张。 “角色名称”: s3-thumbnail-generator-role
。 但是“政策模板”呢?
也许我应该找到与S3有关的东西,因为我的Lambda是全S3。
惊喜! 当我搜索S3时,唯一得到的是“ S3对象只读权限”。 没有其他选择,我只是抢夺了它。 让我们看看我能跌倒多远!
是时候点击“创建功能”了。
哇,他们的Lambda设计师真的很棒!
“恭喜! 您的Lambda函数“ s3-thumbnail-generator”已成功创建。 现在,您可以更改其代码和配置。 准备测试功能时,单击“测试”按钮以输入测试事件。”
好的,我该执行复制粘贴任务了。 样本源代码上的“复制”,lambda代码编辑器上的Ctrl + A和Ctrl + V。 简单!
全部为绿色(无红色)。 很高兴知道。
“保存”和“测试”。
哦,我应该知道得更好。 是的,如果我要“测试”,则需要“测试输入”。 明显。
我知道测试我的全新lambda并不那么容易,但是我并不希望必须手动将JSON系列化事件组合在一起。 值得庆幸的是,他们在这里也做得很好,提供了现成的“ S3 Put”事件模板。 那我还要选择什么呢? :)
不出所料,第一次运行失败:
{"errorMessage": "Cannot find module 'async'","errorType": "Error","stackTrace": ["Function.Module._load (module.js:417:25)","Module.require (module.js:497:17)","require (internal/module.js:20:19)","Object. (/var/task/index.js:2:13)","Module._compile (module.js:570:32)","Object.Module._extensions..js (module.js:579:10)","Module.load (module.js:487:32)","tryModuleLoad (module.js:446:12)","Function.Module._load (module.js:438:3)"]
}
该死的,我应该注意到那些require
线。 无论哪种方式都不好,因为我复制示例代码的页面上有一个很大的标题“创建Lambda 部署程序包 ”,并且清楚地说明了如何将示例捆绑到可Lambda部署的zip中。
因此,我创建了一个包含我的代码和package.json
的本地目录,并运行了npm install
(好东西,我已经预安装了node
和npm
!)。 构建,压缩和上载该应用程序非常容易,希望我不必经历数不胜数的工作,这样的周期就可以使我的lambda正常工作。
(顺便说一句,我希望我可以在他们的内置编辑器中完成此操作;很遗憾,我无法找到添加依赖项的方法。)
无论如何,我第二次考试的时机已经成熟。
{"errorMessage": "Cannot find module '/var/task/index'","errorType": "Error","stackTrace": ["Function.Module._load (module.js:417:25)","Module.require (module.js:497:17)","require (internal/module.js:20:19)"]
}
index
? 那个是从哪里来的?
等等...我的坏,我的坏。
似乎Handler参数仍然保留默认值index.handler
。 就我而言,它应该是CreateThumbnail.handler
( filename.method
)。
让我们再试一次。
认真吗 没门!
是的。 日志不会说谎。
2018-02-04T17:00:37.060Z ea9f8010-09cc-11e8-b91c-53f9f669b596Unable to resize sourcebucket/HappyFace.jpg and upload tosourcebucketresized/resized-HappyFace.jpg due to an error: AccessDenied: Access Denied
END RequestId: ea9f8010-09cc-11e8-b91c-53f9f669b596
很公平; 我没有sourcebucket
或sourcebucketresized
,但可能其他人有。 因此,拒绝访问。 说得通。
因此,我创建了自己的存储桶s3-thumb-input
和s3-thumb-inputresized
,编辑了事件输入(由于“ Configure test event”下拉菜单),然后再次尝试。
2018-02-04T17:06:26.698Z bbf940c2-09cd-11e8-b0c7-f750301eb569Unable to resize s3-thumb-input/HappyFace.jpg and upload tos3-thumb-inputresized/resized-HappyFace.jpg due to an error: AccessDenied: Access Denied
拒绝访问? 再次?
幸运的是,基于事件输入,我发现403实际上指示404(未找到)错误,因为我的存储桶中并未真正包含HappyFace.jpg
文件。
亲爱的读者,请稍等,我急忙前往S3控制台并将开心的表情上传到新的存储桶中。 等一下!
好的,准备下一次测试。
2018-02-04T17:12:53.028Z a2420a1c-09ce-11e8-9506-d10b864e6462Unable to resize s3-thumb-input/HappyFace.jpg and upload tos3-thumb-inputresized/resized-HappyFace.jpg due to an error: AccessDenied: Access Denied
完全一样的错误? 再次? 来吧!
对我来说这没有意义; 为什么在地球上,我自己的lambda将在我自己的AWS帐户中运行,而无法访问我自己的S3存储桶?
等等,这可能与那个执行角色有关吗? 我在哪里盲目分配了S3 只读权限?
稍作谷歌搜索后,我得到了针对lambda的非常全面的AWS IAM文档 ,在其中我了解到lambda是在其自己的IAM角色下执行的; 而且我必须根据要使用的AWS服务手动配置角色。 更糟糕的是,为了配置角色,我必须一直走到IAM管理控制台 (幸运的是,该控制台已经从执行角色下拉列表中链接了,更重要的是在新选项卡中打开)。
双手合十,直到加载自定义角色页面。
哦,不……更多JSON编辑吗?
在原始指南中,AWS伙计们似乎也钉上了执行角色部分 ,但是奇怪的是,那里没有提到S3(名称除外)。 他们错过了什么吗?
好的,这是历史上第一次,我将创建自己的IAM角色!
保佑那些AWS工程师,一个快速的Google搜索显示了他们的策略生成器宝珠。 就是我需要的东西。
但是,摆脱JSON语法只能解决一小部分问题。 我怎么知道我需要哪些权限?
Google,哥们? 有什么事吗
哦…回到AWS文档中? 大…
好吧,这还不错,这要感谢S3权限指南 。 尽管有点让人不知所措,但我猜想我需要的是“对象操作”的某些权限,而且幸运的是,该文档有一张漂亮的桌子,暗示我需要s3:GetObject
和s3:PutObject
(与s3.getObject(...)
和s3.putObject(...)
调用)。
经过一番思考,我最终在我的存储桶上获得了具有上述权限的“ IAM策略”(以乏味的语法arn:aws:s3:::s3-thumb-input
命名):
{"Version": "2012-10-17","Statement": [{"Sid": "Stmt1517766308321","Action": ["s3:PutObject"],"Effect": "Allow","Resource": "arn:aws:s3:::s3-thumb-inputresized"},{"Sid": "Stmt1517766328849","Action": ["s3:GetObject"],"Effect": "Allow","Resource": "arn:aws:s3:::s3-thumb-input"}]
}
并将其粘贴并保存到IAM角色编辑器中(这自动将我带回到lambda控制台页面;太好了!)
再试一次:
同样的错误?
回顾S3权限文档,我注意到对象权限似乎在资源名称下包含一个星号( /*
后缀,可能表示文件)。 因此,我们也尝试使用新的自定义策略:
{"Version": "2012-10-17","Statement": [{"Sid": "Stmt1517766308321","Action": ["s3:PutObject"],"Effect": "Allow","Resource": "arn:aws:s3:::s3-thumb-inputresized/*"},{"Sid": "Stmt1517766328849","Action": ["s3:GetObject"],"Effect": "Allow","Resource": "arn:aws:s3:::s3-thumb-input/*"}]
}
再次(开始感觉像Whiplash ):
2018-02-04T17:53:45.484Z 57ce3a71-09d4-11e8-a2c5-a30ce229e8b7Successfully resized s3-thumb-input/HappyFace.jpg and uploaded tos3-thumb-inputresized/resized-HappyFace.jpg
呜呜!
并且,不管您信不信,一个resized-HappyFace.jpg
文件刚刚出现在我的s3-thumb-inputresized
存储桶中; 是的
现在,当我将文件放入存储桶时,如何配置lambda自动运行?
值得庆幸的是,lambda控制台(具有直观的“触发功能允许”布局)使我清楚地知道我想要的是S3触发器。 因此,我添加了一个,将“创建的对象(所有)”作为“事件类型”,将“ jpg”作为后缀,保存所有内容,然后立即将JPG文件拖放到我的存储桶中。
是的,就像魅力一样。
要查看整个过程花费了多长时间(在实际执行中,而不是在“测试”中),我单击了(上一个)执行结果窗格上的“日志”链接,然后进入那里显示的最新“日志流”; 没有!
更令人怀疑的是,尽管我已经超过了这一点,甚至实现了成功的调整大小,但最新日志流中的最后一个日志是“访问被拒绝”日志。 也许我最近的更改打破了lambda的记录功能?
多亏了Google和StackOverflow ,我发现我的执行角色也需要包含一些与日志记录相关的权限; 确实,现在我记得当我开始创建自定义角色时,权限编辑器文本框中有一些权限,并且我再一次无知地将我的S3策略粘贴在它们上面。
另一轮政策编辑:
{"Version": "2012-10-17","Statement": [{"Sid": "Stmt1517766308321","Action": ["s3:PutObject"],"Effect": "Allow","Resource": "arn:aws:s3:::s3-thumb-inputresized/*"},{"Sid": "Stmt1517766328849","Action": ["s3:GetObject"],"Effect": "Allow","Resource": "arn:aws:s3:::s3-thumb-input/*"},{"Action": ["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents"],"Effect": "Allow","Resource": "arn:aws:logs:*:*:*"}]
}
另一个文件删除了,这次调整大小和日志都完美地工作了……最后!
既然一切都理顺了,我的缩略图正在目标存储桶中等待,我启动了浏览器,输入http://s3-thumb-inputresized.s3.amazonaws.com/resized-HappyFace.jpg
(根据S3虚拟主机docs ),然后按Enter键,期望返回一个漂亮的缩略图。
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>C8BAC3D4EADFF577</RequestId><HostId>PRnGbZ2olpLi2eJ5cYCy0Wqliqq5j1OHGYvj/HPmWqnBBWn5EMrfwSIrf2Y1LGfDT/7fgRjl5Io=</HostId>
</Error>
已经厌倦了“ AccessDenied”消息!
显然,尽管我的代码生成了文件,但它并未使文件可公开访问(但是私有缩略图有什么用,是吧?)
深入研究AWS文档,我很快发现了putObject
操作的ACL
参数,该参数允许S3上传的文件公开。 希望这能解决地球上的所有问题,我Swift升级了代码,将文件的ACL设置为public-read
:
s3.putObject({Bucket: dstBucket,Key: dstKey,Body: data,ContentType: contentType,ACL: 'public-read'},next);}
保存函数,然后单击“测试”:
2018-02-04T18:06:40.271Z 12e44f61-19fe-11e8-92e1-3f4fff4227faUnable to resize s3-thumb-input/HappyFace.jpg and upload tos3-thumb-inputresized/resized-HappyFace.jpg due to an error: AccessDenied: Access Denied
再次?? 你在跟我开玩笑吗?!
幸运的是,这一次我足够了解S3权限指南 ,该指南立即显示我还需要在策略中拥有s3:PutObjectAcl
权限,才能在我的putObject
调用中使用ACL
参数。 因此,再次往返于策略编辑器,IAM仪表板和lambda控制台。
2018-02-04T18:15:09.670Z 1d8dd7b0-19ff-11e8-afc0-138b93af2c40Successfully resized s3-thumb-input/HappyFace.jpg and uploaded tos3-thumb-inputresized/resized-HappyFace.jpg
这次,令我非常满意的是,当我将托管URL http://s3-thumb-inputresized.s3.amazonaws.com/resized-HappyFace.jpg
放入浏览器时,浏览器高兴地向我展示了我的笑脸缩略图。
总而言之,我很满意自己能够通过将所有分散的零件放在一起来最终解决这个难题。 但是我不禁想像一下,如果我可以自由样式地构建lambda,而AWS独自负责角色,权限和其他方面的工作,而又不让我在区块中四处奔走,那将会有多酷。
也许我应该从一开始就遵循该官方指南……但是,再一次,naaah :)
翻译自: https://www.javacodegeeks.com/2018/02/running-around-block-dummys-first-encounter-aws-lambda.html