【问题标题】:How to dynamically create an inline Lambda with AWS SDK for JavaScript?如何使用适用于 JavaScript 的 AWS 开发工具包动态创建内联 Lambda?
【发布时间】:2019-03-19 15:22:31
【问题描述】:

我需要从另一个 Lambda 以编程方式创建一个简单的 Lambda。

这可以通过 CloudFormation 实现:

MyLambda:
  Type: AWS::Lambda::Function
  Properties:
    FunctionName: my-lambda
    Handler: index.handler
    Runtime: nodejs8.10
    Role: !GetAtt MyRole.Arn
    Code:
      ZipFile: >
        exports.handler = event => console.log('EVENT', event)

我想以同样的方式以编程方式创建一个 Lambda。

当我将 Lambda 代码打包成 zip 文件并使用 Lambda 代码上传 zip 时,一切正常:

const lambda = new Lambda({apiVersion: '2015-03-31'});
...
await lambda.createFunction({
    FunctionName: 'my-lambda',
    Handler: 'index.handler',
    Runtime: 'nodejs8.10',
    Role: role.Role.Arn,
    Code: {
        ZipFile: fs.readFileSync('my-lambda.zip')
    }
}).promise();

但是将 Lambda 代码写入文件并随后压缩它是很多样板代码。

如果我尝试将 Lambda 代码设置为内联:

...
Code: {
    ZipFile: "exports.handler = event => console.log('EVENT', event)"
}

我得到一个预期的错误:

失败:无法解压缩上传的文件。请检查您的文件,然后尝试重新上传。

有没有办法如何从另一个 Lambda 动态创建内联 Lambda 函数,类似于顶部提到的 CloudFormation “hack”?

编辑:问题的重点是动态创建代码,无需先压缩。

【问题讨论】:

  • 您可以通过将其保存到 /tmp 来动态创建一个 zip 文件,因为您在那里确实具有写入权限。
  • @ThalesMinussi 非常感谢,我认为它会起作用!但问题的重点实际上是代码的“内联”创建,它意味着不需要创建一个 zip 文件。我对问题进行了一些编辑以使其清楚。
  • 我明白了。是的,这是一个非常好的问题!让我们看看是否有人回复你:)
  • 用例是什么?为什么不简单地使用 Terraform 之类的东西呢?让一个 Lambda 创建另一个 Lambda 对我来说似乎是一种不好的做法……您冒着触发重试的错误风险,最终会得到数百个 Lambda

标签: node.js amazon-web-services aws-lambda aws-sdk


【解决方案1】:

我认为 aws-cdk 是一个不错的选择。它从 javascript 或 typescript 生成 cloudformation,并将编码行数降至最低。

在您的主 lambda 项目中

npm i @aws-cdk/aws-lambda --save-exact

然后您需要在 /tmp 中创建一个目录并使用 node_cmd 从节点 shell 运行 cdk init

然后你会让你的 lambda 导出 cdk Lambda 模板,如下所示到 /tmp/output.js(转换我假设是你想要的内联部分)

import lambda = require('@aws-cdk/aws-lambda');    
const fn = new lambda.Function(this, 'MyFunction', {
    runtime: lambda.Runtime.NodeJS810,
    handler: 'index.handler',
    code: lambda.Code.inline('exports.handler = function(event, ctx, cb) { return cb(null, "hello ttulka"); }')
});

然后您需要使用node_cmd 从节点外壳运行cdk --app 'node /tmp/output.js' synth

【讨论】:

    【解决方案2】:

    TLDR 代码作为部署包上传到 Lambda - 这是一个 zip 文件。因此,您可以动态编写新的函数代码,但在将其传递给 lambda.createFunction 之前,您仍然需要动态创建一个部署包 zip。

    其他信息: 在 Lambda API 文档中,代码元素必须是 FunctionCode 对象。 FunctionCode 对象的选项是指定本地部署包 zip 文件,或指定部署包 zip 文件在 s3 上的位置。

    FunctionCode 对象参考:https://docs.aws.amazon.com/lambda/latest/dg/API_FunctionCode.html

    语法:

    "Code": { 
          "S3Bucket": "string",
          "S3Key": "string",
          "S3ObjectVersion": "string",
          "ZipFile": blob
       }
    

    来源:https://docs.aws.amazon.com/lambda/latest/dg/API_CreateFunction.html

    牢记一些 Lambda 部署包限制(撰写本文时的值):

    1. 如果您将 zip 文件直接作为 blob 上传,则它需要小于 50 MB。
    2. 如果大于 50 MB,您需要先上传到 s3,并指定位置。
    3. 解压后的总大小仍需小于 250 MB。

    Lambda 限制参考:https://docs.aws.amazon.com/lambda/latest/dg/limits.html

    【讨论】:

      猜你喜欢
      • 2019-05-04
      • 2017-08-28
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多