aws lambda
by Janaka Bandara
通過Janaka Bandara
四處奔走:初學者遇到AWS Lambda (Running around the block: a beginner meets AWS Lambda)
Computing! It sure has a very long, vivid (and sometimes awkward) history. Some key milestones include:
計算! 它肯定有很長的,生動的(有時是尷尬的)歷史。 一些關鍵的里程碑包括:
The Egyptians, who slid a few marbles on a wooden frame to ease up a bit on their brains (and sweated the rest of their day over tons of solid granite)
埃及人在木框上滑動了幾塊大理石,以減輕大腦的負擔(剩下的一天中 ,大量的固體花崗巖出汗 )
The Greeks and their Antikythera Mechanism that could track the movement of planets to two-degrees-per-millennium accuracy.
希臘人及其Antikythera機制可以追蹤行星的運動, 每千年精度為2度 。
Charles Babbage’s Analytical Engine.
查爾斯·巴貝奇( Charles Babbage)的分析引擎 。
Alan Turing’s Enigma-breaker.
艾倫·圖靈(Alan Turing)的謎團破滅者 。
NASA’s pocket calculator that put man on the moon.
美國宇航局的袖珍計算器使人類登上月球 。
Deep Blue defeating Garry Kasparov, the Chess Grandmaster.
深藍擊敗國際象棋大師加里·卡斯帕羅夫(Garry Kasparov)。
In line with all this, software application paradigms also have shifted dramatically. Starting from pure hardware-based programming, to monoliths, modularity, SOA, cloud, and now… serverless.
與此相一致,軟件應用程序范例也發生了巨大變化。 從純粹的基于硬件的編程開始,到整體式,模塊化,SOA,云,現在…… 無服務器 。
At this point in time, “serverless” generally means FaaS (functions-as-a-service). And FaaS literally means AWS Lambda, both from popularity and adoption points of view.
此時,“無服務器”通常表示FaaS(功能即服務)。 從流行度和采用角度來看,FaaS的字面意思是AWS Lambda 。
Hence, it is not an exaggeration to claim that the popularity of serverless development may be related to the ease of use of Lambdas. Or is it?
因此,毫不夸張地說,無服務器開發的普及可能與Lambda的易用性有關。 還是?
Well, Lambda has been around since 2015. It is already integrated into much of the AWS ecosystem, and is in production use at hundreds (if not thousands) of companies. So, Lambda should be pretty intuitive and easy to use, right?
好吧,Lambda 自2015年以來一直存在。 它已經集成到許多AWS生態系統中,并已在數百個(如果不是數千個)公司中投入生產。 因此,Lambda應該非常直觀且易于使用,對嗎?
Well, in my case, it seemed not.
好吧,就我而言,似乎并非如此。
And since “my case” was one of the official AWS examples, I’m not quite convinced Lambda is friendly enough for newbies to the picture.
而且由于“我的案子”是AWS的官方示例之一,所以我不太相信Lambda對于新手來說足夠友好。
For a start, I wanted to implement AWS’s own thumbnail creation use case without following their own guide, to see how far I could get.
首先,我想實現AWS自己的縮略圖創建用例, 而不遵循他們自己的指南 ,以了解我能走多遠。
As a programmer, I naturally started with the Lambda management console. The code had already been written by the generous AWS devs, so why reinvent the wheel? Copy, paste, save, run. Ta-da!
作為程序員,我自然而然地開始使用Lambda管理控制臺 。 該代碼已經由慷慨的AWS開發人員編寫 ,那么為什么要重新發明輪子呢? 復制,粘貼,保存,運行。 -
Hmm, looks like I need to grow up a bit.
嗯,看來我需要長大一點。
The “Create function” wizard was eye-catching, with so many ready-made blueprints. Too bad it didn’t already have the S3 thumbnail generation example, or this story could have ended right here!
“創建功能”向導引人注目,其中包含許多現成的藍圖。 太糟糕了,它還沒有S3縮略圖生成示例,否則這個故事可能就此結束!
So I just went ahead with the “Author from scratch” option, using the name s3-thumbnail-generator
.
因此,我只是使用名稱s3-thumbnail-generator
進行了“從頭開始創作”選項。
Oh wait, what’s this “Role” thing? It’s required, too. Luckily, it has a “Create new role from template(s)” option, which would save my day.
哦,等等,這是什么“角色”? 這也是必需的。 幸運的是,它具有“從模板創建新角色”選項,這可以節省我的時間。
Take it easy. “Role name”: s3-thumbnail-generator-role
. But how about the "policy template"?
別緊張。 “角色名稱”: s3-thumbnail-generator-role
。 但是“策略模板”呢?
Perhaps I should find something S3-related, since my Lambda is all-S3.
也許我應該找到與S3有關的東西,因為我的Lambda是全S3。
Surprise! The only thing I get when I search for S3, is “S3 object read-only permissions”. Having no other option, I just snatched it. Let’s see how far I can get before I fall flat on my face!
驚喜! 當我搜索S3時,唯一得到的是“ S3對象只讀權限”。 沒有其他選擇,我只是搶奪了它。 讓我們看看我能跌倒之前能走多遠!
Time to hit “Create function”.
是時候點擊“創建功能”了。
Wow, their Lambda designer looks really cool!
哇,他們的Lambda設計師真的很棒!
“Congratulations! Your Lambda function “s3-thumbnail-generator” has been successfully created. You can now change its code and configuration. Click on the “Test” button to input a test event when you are ready to test your function.”
“恭喜! 您的Lambda函數“ s3-thumbnail-generator”已成功創建。 現在,您可以更改其代碼和配置。 準備測試功能時,單擊“測試”按鈕以輸入測試事件。”
Okay, time for my copy-paste mission. “Copy” on the sample source code, Ctrl+A
and Ctrl+V
on the Lambda code editor. Simple!
好吧,我該執行復制粘貼任務了。 在示例源代碼上“復制”,在Lambda代碼編輯器上Ctrl+A
和Ctrl+V
簡單!
All green (no reds). Good to know.
全部為綠色(無紅色)。 很高興知道。
“Save”, and “Test”.
“保存”和“測試”。
Oh, I should have known better. Yup, if I am going to “Test”, I need a “Test input”. Obviously.
哦,我應該知道得更多。 是的,如果我要進行“測試”,則需要“測試輸入”。 明顯。
I knew that testing my brand-new Lambda would not be as easy as that. But I didn’t expect having to put together a JSON-serialized event by hand.
我知道測試我的全新Lambda并不那么容易。 但是我沒想到必須手動將JSON序列化的事件放在一起。
Thankfully, the AWS devs had done a great job here as well, providing a ready-made “S3 Put” event template. So what else would I select?
值得慶幸的是,AWS開發人員在這里也做了出色的工作,提供了現成的“ S3 Put”事件模板。 那我還要選擇什么呢?
As expected, the first run was a failure:
不出所料,第一次運行失敗:
{ "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)" ]}
Damn, I should have noticed those require
lines.
該死的,我應該注意到那些require
線。
And, either way, it's my bad. The page where I copied the sample code had a big fat title "Create a Lambda Deployment Package", and clearly explained how to bundle the sample into a Lambda-deployable zip.
而且,無論哪種方式,這都是我的壞事。 我在其中復制了示例代碼的頁面上有一個粗大的標題“創建Lambda 部署程序包 ”,并清楚地說明了如何將示例捆綁到Lambda可部署的zip中。
So, I created a local directory containing my code, and the package.json
, and ran an npm install
(good thing I had node
and npm
preinstalled!).
因此,我創建了一個包含我的代碼和package.json
的本地目錄,并運行了npm install
(好東西,我已經預安裝了node
和npm
!)。
Building, zipping and uploading the application was fairly easy, and hopefully I would not have to go through a zillion and one such cycles to get my Lambda working.
構建,壓縮和上載該應用程序非常容易,希望我不必經歷數不勝數的工作,就可以使Lambda正常工作。
(BTW, I wish I could do this in their built-in editor itself. Too bad I could not figure out a way to add the dependencies.)
(順便說一句,我希望我可以在他們的內置編輯器中進行此操作。很遺憾,我無法找到添加依賴項的方法。)
Anyway, time is ripe for my second test.
無論如何,我第二次考試的時機已經成熟。
{ "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
? Where did that come from?
index
? 那個是從哪里來的?
Wait… my bad, my bad.
等等...我的壞,我的壞。
Seems like the Handler parameter still holds the default value index.handler
. In my case it should be CreateThumbnail.handler
(filename.method
).
似乎Handler參數仍保留默認值index.handler
。 就我而言,它應該是CreateThumbnail.handler
( filename.method
)。
Let’s give it another try.
讓我們再試一次。
Seriously? No way!
認真嗎 沒門!
Ah, yes. The logs don’t lie.
是的。 日志不會說謊。
2018-02-04T17:00:37.060Z ea9f8010-09cc-11e8-b91c-53f9f669b596 Unable to resize sourcebucket/HappyFace.jpg and upload to sourcebucketresized/resized-HappyFace.jpg due to an error: AccessDenied: Access DeniedEND RequestId: ea9f8010-09cc-11e8-b91c-53f9f669b596
Fair enough. I don’t have sourcebucket
or sourcebucketresized
, but probably someone else does. Hence the access denial. Makes sense.
很公平。 我沒有sourcebucket
或sourcebucketresized
,但可能其他人有。 因此,拒絕訪問。 說得通。
So I created my own buckets, s3-thumb-input
and s3-thumb-inputresized
, edited my event input (thanks to the "Configure test event" drop-down) and tried again.
因此,我創建了自己的存儲桶s3-thumb-input
和s3-thumb-inputresized
,編輯了事件輸入(由于“ Configure test event”下拉菜單),然后再次嘗試。
2018-02-04T17:06:26.698Z bbf940c2-09cd-11e8-b0c7-f750301eb569 Unable to resize s3-thumb-input/HappyFace.jpg and upload to s3-thumb-inputresized/resized-HappyFace.jpg due to an error: AccessDenied: Access Denied
Access Denied? Again?
拒絕訪問? 再次?
Luckily, based on the event input, I figured out that the 403 could actually be indicating a 404 (not found) error, since my bucket did not really contain a HappyFace.jpg
file.
幸運的是,基于事件輸入,我發現403可能實際上指示404(未找到)錯誤,因為我的存儲桶中并未真正包含HappyFace.jpg
文件。
Hold on, dear reader, while I rush to the S3 console and upload my happy face into my new bucket. Just a minute!
親愛的讀者,請稍等,我急忙前往S3控制臺并將開心的臉上傳到我的新存儲桶中。 等一下!
Okay, ready for the next test round.
好吧,準備下一次測試。
2018-02-04T17:12:53.028Z a2420a1c-09ce-11e8-9506-d10b864e6462 Unable to resize s3-thumb-input/HappyFace.jpg and upload to s3-thumb-inputresized/resized-HappyFace.jpg due to an error: AccessDenied: Access Denied
The exact same error? Again? Come on!
完全一樣的錯誤? 再次? 來吧!
It didn’t make sense to me. Why on Earth would my own Lambda running in my own AWS account not have access to my own S3 bucket?
對我來說這沒有意義。 為什么在地球上運行在自己的 AWS賬戶中的自己的 Lambda無法訪問自己的 S3存儲桶?
Wait, could this be related to that execution role thing? The part where I blindly assigned S3 read-only permissions?
等等,這與執行角色有關嗎? 我盲目分配S3 只讀權限的部分?
A bit of Googling led me to the extremely comprehensive AWS IAM docs for Lambda. There, I learned that the Lambda executes under its own IAM role. I would have to manually configure the role based on what AWS services I would be using.
有點古怪的操作使我找到了針對Lambda的極其全面的AWS IAM文檔 。 在那里,我了解到Lambda在其自己的IAM角色下執行。 我將不得不根據要使用的AWS服務手動配置角色。
Worse still, in order to configure the role, I have to go all the way to the IAM management console. Fortunately, this is already linked from the execution role drop-down menu. More importantly, it opens in a new tab.
更糟糕的是,為了配置角色,我必須一直使用IAM管理控制臺 。 幸運的是,這已經從執行角色下拉菜單中鏈接了。 更重要的是,它將在新選項卡中打開。
Fingers crossed, till the custom role page loads.
雙手合十,直到加載自定義角色頁面。
Oh no… More JSON editing?
哦,不...更多JSON編輯嗎?
In the original guide, AWS devs seemed to have nailed the execution role part as well. But it was strange that there was no mention of S3 in there (except in the name). Did they miss something?
在原始指南中,AWS開發人員似乎也已將執行角色部分固定 。 但是奇怪的是,那里沒有提到S3(名字除外)。 他們錯過了什么嗎?
Okay, for the first time in history, I am going to create my own IAM role!
好的,這是歷史上第一次,我將創建自己的IAM角色!
Bless those AWS engineers, a quick Googling revealed their policy generator jewel. Just the thing I need.
保佑那些AWS工程師,快速谷歌搜索顯示了他們的策略生成器寶珠。 只是我需要的東西。
But getting rid of the JSON syntax solves only a little part of the problem. How can I know which permissions I need?
但是,擺脫JSON語法只能解決一小部分問題。 我怎么知道我需要哪些權限?
Google, buddy? Anything?
Google,哥們? 有什么事嗎
Ohh… Back into the AWS docs? Great…
哦…回到AWS文檔中? 大…
Well, it wasn’t that bad, thanks to the S3 permissions guide.
好吧,這還不錯,這要感謝S3權限指南 。
Although it was somewhat overwhelming, I guessed what I needed was some permissions for “object operations”. Luckily, the doc had a nice table suggesting that I needed s3:GetObject
and s3:PutObject
(consistent with the s3.getObject(...)
and s3.putObject(...)
calls in the code).
盡管有點讓人不知所措,但我猜想我需要的是“對象操作”的一些權限。 幸運的是,該文檔有一個漂亮的表,提示我需要s3:GetObject
和s3:PutObject
(與代碼中的s3.getObject(...)
和s3.putObject(...)
調用一致)。
After some thinking, I ended up with an “IAM Policy” with the above permissions on my bucket (named with the tedious syntax arn:aws:s3:::s3-thumb-input
):
經過一番思考,我最終獲得了一個“ IAM策略”, arn:aws:s3:::s3-thumb-input
我的存儲桶具有上述權限(以乏味的語法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" } ]}
I pasted and saved it on the IAM role editor (which automatically took me back to the Lambda console page — how nice!)
我將其粘貼并保存在IAM角色編輯器中(這自動將我帶回到Lambda控制臺頁面-太好了!)
Try again…
再試一次…
Same error?!
同樣的錯誤?
Looking back at the S3 permissions doc, I noticed that the object permissions seem to involve an asterisk (/*
suffix, probably indicating the files) under the resource name. So let's try that as well, with a new custom policy:
回顧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/*" } ]}
Again! (this is starting to sound like Whiplash):
再次! (這聽起來像Whiplash ):
2018-02-04T17:53:45.484Z 57ce3a71-09d4-11e8-a2c5-a30ce229e8b7 Successfully resized s3-thumb-input/HappyFace.jpg and uploaded to s3-thumb-inputresized/resized-HappyFace.jpg
WOO-HOO!!!
嗚嗚!
Believe it or not, a resized-HappyFace.jpg
file had just appeared in my s3-thumb-inputresized
bucket! Oh yeah!
信不信由你,一個resized-HappyFace.jpg
文件剛剛出現在我的s3-thumb-inputresized
存儲桶中! 哦耶!
Now, how can I configure my Lambda to automatically run when I drop a file into my bucket?
現在,當我將文件放入存儲桶時,如何配置Lambda自動運行?
Thankfully, the Lambda console (with its intuitive “trigger-function-permissions” layout) made it crystal clear that what I wanted was an S3 trigger. So I added one, with “Object Created (All)” as the “Event Type” and “jpg” as the suffix, saved everything, and dropped a JPG file into my bucket right away.
值得慶幸的是,Lambda控制臺(具有直觀的“觸發功能允許”布局)使我清楚地知道我想要的是S3觸發器。 因此,我添加了一個,將“創建的對象(全部)”作為“事件類型”,并將“ jpg”作為后綴,保存所有內容,然后立即將JPG文件拖放到我的存儲桶中。
Yup, works like a charm.
是的,就像魅力一樣。
To see how long the whole process took (in actual execution, as opposed to the “tests”), I clicked the “logs” link on the (previous) execution result pane, and went into the newest “log stream” shown there. Nothing!
為了查看整個過程花費了多長時間(在實際執行中,而不是在“測試”中),我單擊了(上一個)執行結果窗格上的“日志”鏈接,然后進入那里顯示的最新“日志流”。 沒有!
And more suspiciously, the last log in the newest log stream was an “access denied” log, although I had gotten past that point and even achieved a successful resize.
更令人懷疑的是,盡管我已經超過了這一點,甚至實現了成功的調整大小,但最新日志流中的最后一個日志是“訪問被拒絕”日志。
Maybe my latest change broke the logging ability of the Lambda?
也許我最近的更改打破了Lambda的伐木能力?
Thanks to Google and StackOverflow, I found that my execution role needs to contain some logging related permissions as well.
多虧了Google和StackOverflow ,我發現我的執行角色也需要包含一些與日志記錄相關的權限。
Now, I remember there were some permissions in the permission editor text box when I started creating my custom role. Once again I was ignorant enough to paste my S3 policies right over them.
現在,我記得開始創建自定義角色時,權限編輯器文本框中有一些權限。 我再一次無知地將我的S3策略粘貼到它們之上。
Another round of policy editing:
另一輪政策編輯:
{ "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:*:*:*" } ]}
Another file drop, and this time both the resize and the logs worked flawlessly… Finally!
另一個文件丟失了,這次調整大小和日志都完美地工作了……最后!
Now that everything is straightened out, and my thumbnail is waiting in my destination bucket, I fired up my browser, typed http://s3-thumb-inputresized.s3.amazonaws.com/resized-HappyFace.jpg
(in accordance with the S3 virtual hosting docs). I hit Enter, expecting a nice thumbnail in return.
既然一切都理順了,我的縮略圖在目標存儲桶中等待,我啟動了瀏覽器,輸入http://s3-thumb-inputresized.s3.amazonaws.com/resized-HappyFace.jpg
(根據S3虛擬主機文檔 )。 我按下Enter鍵,希望得到一個漂亮的縮略圖。
<Error> <Code>AccessDenied</Code> <Message>Access Denied</Message> <RequestId>C8BAC3D4EADFF577</RequestId> <HostId>PRnGbZ2olpLi2eJ5cYCy0Wqliqq5j1OHGYvj/ HPmWqnBBWn5EMrfwSIrf2Y1LGfDT/7fgRjl5Io=</HostId></Error>
Already tired of that “AccessDenied” message!
已經厭倦了“ AccessDenied”消息!
Apparently, although my code generates the file, it does not make the file publicly accessible (but what good would a private thumbnail be, huh?)
顯然,盡管我的代碼生成了文件,但它并未使文件可公開訪問(但是私有縮略圖有什么用處,是嗎?)
Digging through the AWS docs, I soon discovered the ACL
parameter of the putObject
operation, which allows the S3 uploaded file to be public. Hoping this would solve all problems on the planet, I quickly upgraded my code to set the file's ACL to public-read
:
深入研究AWS文檔,我很快發現了putObject
操作的ACL
參數,該參數允許S3上傳的文件公開。 希望這可以解決地球上的所有問題,我Swift升級了代碼,將文件的ACL設置為public-read
:
s3.putObject({ Bucket: dstBucket, Key: dstKey, Body: data, ContentType: contentType, ACL: 'public-read' }, next); }
Saved the function, and hit Test:
保存函數,然后單擊“測試”:
2018-02-04T18:06:40.271Z 12e44f61-19fe-11e8-92e1-3f4fff4227fa Unable to resize s3-thumb-input/HappyFace.jpg and upload to s3-thumb-inputresized/resized-HappyFace.jpg due to an error: AccessDenied: Access Denied
Again?? Are you kidding me?!
再次?? 你在跟我開玩笑嗎?!
Fortunately, this time I knew enough to go straight into the S3 permissions guide, which promptly revealed that I also needed to have the s3:PutObjectAcl
permission in my policy, in order to use the ACL
parameter in my putObject
call.
幸運的是,這次我足夠了解S3權限指南 ,該指南立即顯示我還需要在策略中擁有s3:PutObjectAcl
權限,才能在我的putObject
調用中使用ACL
參數。
So another round trip to the policy editor, to the IAM dashboard, and back to the Lambda console.
因此,又一次往返于策略編輯器,IAM儀表板和Lambda控制臺。
2018-02-04T18:15:09.670Z 1d8dd7b0-19ff-11e8-afc0-138b93af2c40 Successfully resized s3-thumb-input/HappyFace.jpg and uploaded to s3-thumb-inputresized/resized-HappyFace.jpg
And this time, to my great satisfaction, the browser happily showed me my happy face thumbnail when I fed the hosting URL http://s3-thumb-inputresized.s3.amazonaws.com/resized-HappyFace.jpg
into it.
這次,令我非常滿意的是,當我將托管URL http://s3-thumb-inputresized.s3.amazonaws.com/resized-HappyFace.jpg
輸入到瀏覽器時,瀏覽器高興地向我展示了我的笑臉縮略圖。
All in all, I’m satisfied that I was finally able to solve the puzzle on my own, by putting all the scattered pieces together.
總而言之,我很滿意自己能夠通過將所有分散的碎片放在一起來最終解決這個難題。
But I cannot help imagining how cool it would have been if I could build my Lambda in freestyle, with AWS taking care of the roles, permissions and whatnot, on its own, without getting me to run around the block.
但是我不禁想像一下,如果我可以自由樣式地構建Lambda,而AWS可以自己處理角色,權限和其他方面的事情 ,而又不用讓我繞著塊運行,那將會有多酷。
Maybe I should have followed that official guide, right from the start…
也許我應該從一開始就遵循該官方指南…
… but, then again, where’s the fun in that?! :)
……但是,那又有什么樂趣呢? :)
翻譯自: https://www.freecodecamp.org/news/running-around-the-block-a-beginner-meets-aws-lambda-560a1f2849ae/
aws lambda