如何在没有内联代码的情况下使用 lambda 函数部署 cloudformation?

Posted

技术标签:

【中文标题】如何在没有内联代码的情况下使用 lambda 函数部署 cloudformation?【英文标题】:How do you deploy cloudformation with a lambda function without inline code? 【发布时间】:2021-03-22 13:08:03 【问题描述】:

lambda 函数大小超过 4096 个字符,因此我无法将 lambda 函数部署为 cloudformation 模板中的内联代码。

(https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-code.html)

压缩文件

您的源代码最多可包含 4096 个字符。对于 JSON,您必须使用反斜杠转义引号和特殊字符,例如换行符 (\n)。

我必须先压缩它,上传到一个s3存储桶,在cloudformation中设置s3存储桶和文件详细信息,然后部署它。

我找不到使用一个命令进行部署的方法。如果我更新 lambda 代码,我必须重复上述步骤

但使用 AWS SAM 或无服务器框架,他们可以部署 lambda 函数而无需内联代码。

唯一的问题是,AWS SAM 或无服务器框架默认创建 API 网关,我不需要创建它

对我有什么解决方案或建议吗?

【问题讨论】:

你能澄清一下这个问题吗?你不知道如何制作 zip 并上传到 s3? 我可以。但是没有办法做到一劳永逸 aws cli 提供package 命令,可以制作压缩包并上传。 【参考方案1】:

如果您使用普通的 CloudFormation 和 aws 命令行界面管理您的部署,您可以使用 aws cloudformation package 生成一个“打包”的部署模板来相对轻松地处理这个问题。

aws cloudformation package 接受可以使用本地路径写入某些属性的模板,从本地文件系统压缩内容,上传到指定的 S3 存储桶,然后输出重写这些属性以引用位置的新模板在 S3 而不是本地文件系统上。在您的情况下,它可以为指向本地目录的AWS::Lambda::Function 重写Code 属性,但请参阅aws cloudformation package help 以获取支持的属性的完整列表。您确实需要提前设置一个 S3 存储桶来存储您的资产,但您可以在多个 CloudFormation 项目中重复使用同一个存储桶。

所以,假设您有一个input.yaml,类似:

  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Code: my-function-directory

你可以用类似这样的东西来包装它:

aws cloudformation package \
    --template-file input.yaml \
    --s3-bucket my-packaging-bucket \
    --s3-prefix my-project/ \
    --output-template-file output.yaml

这会产生一个类似于以下内容的output.yaml

  MyLambdaFunction:
    Properties:
      Code:
        S3Bucket: my-packaging-bucket
        S3Key: my-project/0123456789abcdef0123456789abcdef
    Type: AWS::Lambda::Function

然后您可以将output.yamlaws cloudformation deploy 一起使用(或任何其他接受模板的aws cloudformation 命令)。

要真正“使用一个命令进行部署”并确保始终始终如一地进行部署,您可以将这两个命令组合成一个脚本 Makefile 或类似的东西。

【讨论】:

是的,但你必须先有一个桶。而且您不能在模板文件中定义该存储桶,因为您必须在 package 命令之前创建它,然后部署输出 yaml。【参考方案2】:

您可以先压缩文件,然后使用 aws cli 更新您的 lambda 函数

zip function.zip lambda_function.py
aws lambda update-function-code --function-name <your-lambda-function-name> --zip-file fileb://function.zip

【讨论】:

谢谢,我正在研究带有 lambda 函数的 cloudformation,而不是直接使用 lambda。【参考方案3】:

在 CloudFormation 内(最后 3 行):

  BackupLambda:
    Type: "AWS::Lambda::Function"
    Properties:
      Handler: "backup_lambda.lambda_handler"
      Role: !Ref Role
      Runtime: "python2.7"
      MemorySize: 128
      Timeout: 120
      Code:
        S3Bucket: !Ref BucketWithLambdaFunction
        S3Key: !Ref PathToLambdaFile

【讨论】:

是的,这就是问题所在,对吧?所以每次更新 lambda 代码时,我都会手动生成 zip 文件,上传到 s3 bucket ,然后运行部署命令。我不能像 SLS 或 SAM cli 那样在一个命令中做到这一点。【参考方案4】:

回复。您的评论:

唯一的问题是,aws SAM 或无服务器框架默认创建 API 网关,我不需要创建它

对于无服务器框架,默认情况下并非如此。默认生成的 serverless.yml 文件包含 Lambda 函数本身的配置,但 API Gateway 的配置仅在以下注释掉的部分中作为示例提供。

如果您取消注释 http 的“事件”部分,那么它还会为您的 Lambda 创建 API 网关配置,但除非您这样做。

functions:
  hello:
    handler: handler.hello
#    The following are a few example events you can configure
#    NOTE: Please make sure to change your handler code to work with those events
#    Check the event documentation for details
#    events:
#      - http:
#          path: users/create
#          method: get

【讨论】:

以上是关于如何在没有内联代码的情况下使用 lambda 函数部署 cloudformation?的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin函数 ⑦ ( 内联函数 | Lambda 表达式弊端 | “ 内联 “ 机制避免内存开销 - 将使用 Lambda 表达式作为参数的函数定义为内联函数 | 内联函数本质 - 宏替换 )

python 内联函数

函数式编程———内联函数

如何比较内联函数和普通函数的内存使用情况?

如何在没有扩展内联 asm 的情况下在 gcc 内联汇编中声明和初始化局部变量?

使用命名的 lambda 与函数 - 在 lambda 的情况下变量的额外空间使用?