serverless 构建
by Dmitri Zimine
由Dmitri Zimine
使用Serverless,StepFunctions和StackStorm Exchange构建社区注册应用程序-第2集 (Building a community sign-up app with Serverless, StepFunctions, and StackStorm Exchange — Episode 2)
Build a real-world serverless application on AWS with Serverless framework and ready-to-use functions from StackStorm Exchange open-source catalog.
使用无服务器框架和StackStorm Exchange开源目录中的即用型功能,在AWS上构建真实的无服务器应用程序。
Episode One | Episode Two | Episode Three | Episode Four
In this second episode, I’ll add two more actions: create a contact in ActiveCampaign, and record a user in Dynamo DB. The full code for this episode is on Github at 2-add-more-actions branch.
在第二集中,我将添加另外两个操作:在ActiveCampaign中创建联系人,并在Dynamo DB中记录用户。 该剧集的完整代码在Github的2-add-more-actions分支上 。
添加更多动作 (Add more actions)
To continue to the next step, you’ll need an ActiveCampaign account. Fear not: it takes 2 minutes — I just tried — they didn’t ask me for a credit card or anything stupid. Just email. Once in, go to “My Settings”, and select “Developer”.
要继续下一步,您需要一个ActiveCampaign帐户。 不用担心:这只花了2分钟-我刚刚尝试了-他们没有要求我提供信用卡或任何愚蠢的东西。 只是电子邮件。 进入后,转到“我的设置”,然后选择“开发人员”。
Note the URL
and Key
fields in the "API access" section. Add them into env.yml
like this:
请注意“ API访问”部分中的“ URL
和“ Key
字段。 像这样将它们添加到env.yml
:
# Copy to env.yml and replace with your values.# Don't commit to Github :)slack: admin_token: "xoxs-111111111111-111111111111-..." organization: "your-team"active_campaign: url: "https://YOUR-COMPANY.api-us1.com" api_key: "1234567a9012a12345z12aa2..."
PRO TIP: If you’re not in the mood for Active Campaign, or any sign-ups, just mock up the API endpoint with something like Mocky or mockable.ioand adjust the examples accordingly. For bonus points, create another serverless function with API Gateway endpoint in your serverless.yml
and use it to mock the ActiveCampaign API call.
专家提示:如果您不想参加Active Campaign或任何注册,只需使用Mocky或mockable.io之类的方法模拟API端点并相应地调整示例。 为了获得加分,请在serverless.yml
使用API Gateway端点创建另一个无服务器功能,并使用它来模拟ActiveCampaign API调用。
Now I am ready to add an Active Campaign lambda function. Same routine as in Episode One: start with finding a new action in a pack with sls stackstorm info --pack activecampaign
(hint: the action you're looking is contact_sync
which adds and updates a contact). Inspect the action with sls stackstorm info --action activecampaign.contact_sync
:
现在,我准备添加Active Campaign lambda函数。 与第1集中的例程相同:从带有sls stackstorm info --pack activecampaign
的包中查找新动作开始(提示:您要查找的动作是contact_sync
,用于添加和更新联系人)。 使用sls stackstorm info --action activecampaign.contact_sync
检查操作:
Bunch of parameters, but besides the config, only email
is required. I also want to use first_name
and last_name
. The function definition in serverless.yml
will look like this:
一堆参数,但是除了配置,只需要email
。 我也想使用first_name
和last_name
。 serverless.yml
的函数定义如下所示:
RecordAC: timeout: 10 memorySize: 128 stackstorm: action: activecampaign.contact_add input: email: "{{ input.body.email }}" first_name: "{{ input.body.first_name }}" last_name: "{{ input.body.last_name }}" config: ${file(env.yml):activecampaign}
I had to bump up the timeout as the ActiveCampaign API is taking longer than Lambda's default 6 seconds during Christmas season. But I can reclaim invocation cost by lowering memory use from default 512Mb. This time I don't bother to expose it to AWS API Gateway - we can conveniently test it with sls
.
由于圣诞节期间ActiveCampaign API花费的时间比Lambda的默认6秒更长,因此我不得不提高超时时间。 但是我可以通过降低默认512Mb的内存使用量来收回调用成本。 这次,我不必费心将其公开给AWS API Gateway-我们可以使用sls
方便地对其进行测试。
The function is ready to fly to AWS. We could do it at once with sls deploy
but let's take it slow again and repeat the deployment steps just like in episode 1 of this tutorial to engrave the workflow in your mind:
该功能已准备就绪,可以飞往AWS。 我们可以使用sls deploy
一次完成此操作,但让我们再慢一点,重复一下本教程第1集中的部署步骤,以将工作流刻在脑海中:
- Build and package the bundle: 构建并打包捆绑包:
sls package
2. Test locally (note I’m using --passthrough
to only test transformations, remove it to make an actual call):
2.在本地测试(请注意,我仅使用--passthrough
来测试转换,将其删除以进行实际调用):
sls stackstorm docker run --function RecordAC \--passthrough \--verbose --data '{"body":{"email":"santa@mad.russian.xmas.com", "first_name":"Santa", "last_name": "Claus"}}'
3. Deploy to AWS:
3.部署到AWS:
sls deploy
4. Test on AWS with sls invoke
:
4.使用sls invoke
在AWS上测试:
sls invoke --function RecordAC --logs \ --data '{"body":{"email":"santa@mad.russian.xmas.com", "first_name":"Santa", "last_name": "Claus"}}'
5. Check the logs:
5.检查日志:
sls logs --function RecordAC
and I checked, it works: Santa Claus appeared in ActiveCampaign’s contact list. How do I know it’s our Lambda? Because I no longer believe Santa is real enough to subscribe to community without our little Lambda function.
我检查了一下,它起作用了:圣诞老人出现在ActiveCampaign的联系人列表中。 我怎么知道这是我们的Lambda? 因为我不再相信圣诞老人在没有我们的Lambda小功能的情况下就足以加入社区。
PRO TIP: If you hit a bug or want a feature in a pack you are using from StackStorm Exchange, you can fix it on the spot. Packs are cloned under ./~st2/packs
. Find your action there, modify the code, and use a local run to debug and validate. Big bonus for pushing fixes back to the Exchange: each pack is already a git clone that makes it naturally easy to contribute back to the community.
专业提示:如果您遇到了错误或想要从StackStorm Exchange使用的软件包中包含某个功能,则可以当场进行修复。 包被克隆到./~st2/packs
下。 在此处找到您的操作,修改代码,并使用本地运行进行调试和验证。 将修补程序推回Exchange的巨大好处:每个软件包都已经是一个git clone,可以很自然地为社区做出贡献。
Let’s add the final action, RecordDB, that writes contact info into a DynamoDB table. I could have used the aws.dynamodb_put_item
action from the AWS pack on StackStorm Exchange - the pack is heavily used and well maintained. But I decided to make it a native Lambda: it's just 30 lines of code, with no extra Python dependencies, since the Boto library is already in the AWS Lambda environment.
让我们添加最后一个动作RecordDB,该动作将联系人信息写入DynamoDB表中。 我本可以在StackStorm Exchange上使用AWS包中的aws.dynamodb_put_item
操作-该包已被大量使用且维护良好。 但是我决定将其作为本机Lambda:它只有30行代码,没有额外的Python依赖项,因为Boto库已经在AWS Lambda环境中。
The function’s code goes into ./record_db/handler.py
:
该函数的代码进入./record_db/handler.py
:
The final serverless.yml
with all three actions now looks like this:
现在,具有所有三个操作的最终serverless.yml
如下所示:
Wow! The file doubled. The function itself is just 2 lines (35:36), but quite a few interesting additions took place. Let’s review them:
哇! 该文件加倍。 该函数本身只有两行(35:36),但是发生了很多有趣的添加。 让我们回顾一下:
- Line 9 — Table name generated to avoid collisions between regions and environments. 第9行-生成表名以避免区域和环境之间的冲突。
- Lines 10:13 — IAM Role created to give the function access to the DynamoDB table. 第10:13行-创建了IAM角色,以使函数可以访问DynamoDB表。
- Line 39:56 — AWS CloudFormation template defining the table. Line 39:56 —定义表的AWS CloudFormation模板。
The last point brings up an important observation: Serverless framework simplifies mainly the FaaS part of serverless. But because servereless is more than FaaS, you’ll find yourself writing quite a lot of CloudFormation to provision other services. Serverless framework leaves space for provider specific resources. To be seriously serverless on AWS, master CloudFormation. Looking for “provider-agnostic serverless”? Double-check your assumptions.
最后一点提出了一个重要的观点: 无服务器框架主要简化了无服务器的FaaS部分。 但是,由于servereless不仅仅是FaaS,因此您会发现自己编写了很多CloudFormation来提供其他服务。 无服务器框架为提供程序特定的资源留出空间。 要在AWS上实现无服务器严重,请掌握CloudFormation。 寻找“与提供商无关的无服务器”? 仔细检查您的假设。
Also, I moved memorySize
and timeout
to apply to all functions (lines 6:7). And the API Gateway endpoint is gone from the InviteSlack function: it served the demonstration role in the first episode, but now we've learned to test Lambda functions directly. We'll return to API Gateway later to invoke the final StepFunction end-to-end workflow.
另外,我将memorySize
和timeout
移到了所有功能上(第6:7行)。 而且API网关端点不再来自InviteSlack函数:它在第一集中起了演示作用,但是现在我们学会了直接测试Lambda函数。 稍后我们将返回API Gateway来调用最终的StepFunction端到端工作流程。
Let’s get the RecordDB function up to the sky and running. Deploy, invoke, logs. Rinse repeat.
让RecordDB函数运转起来。 部署,调用,记录。 重复冲洗。
# Deploysls deploy ...
# Invokesls invoke --function RecordDB --logs --data '{"body":{"email":"santa@mad.russian.xmas.com", "first_name":"Santa", "last_name": "Claus"}}'...
# Check logs.sls logs --function RecordDB.
Now all three actions are here, waiting to be wired together into a final workflow with a StepFunction. But I’m just reminded not to be Mr. Scrooge: it’s the holiday season, let’s take it easy and put it off to the next episode. Until then, keep the spirits high!
现在所有这三个动作都在这里,等待通过StepFunction将它们连接到最终的工作流程中。 但我只是提醒我不要成为Scrooge先生:现在是假期,让我们轻松一点,将其推迟到下一集。 在此之前,请保持精神振奋!
The complete code example for this episode is on Github at 2-add-more-actions branch.
此剧集的完整代码示例在Github上的2-add-more-actions分支上。
Episode 3: Wiring the actions with a StepFunction
第3集 :使用StepFunction接线操作
Hope this helped you learn something new, find something interesting, or provoked some good thoughts. Please share your thoughts in the comments here, or tweet me @dzimine.
希望这可以帮助您学习新知识,发现有趣事物或激发一些好的想法。 请在此处的评论中分享您的想法,或在推特上给我@dzimine 。
serverless 构建