【问题标题】:Deploying lambdas effectively (only deploy those that changed) with Terraform/CloudFormation/Something else使用 Terraform/CloudFormation/Something 有效地部署 lambdas(只部署那些改变的)
【发布时间】:2019-05-14 08:01:40
【问题描述】:

到目前为止,我一直在使用 CloudFormation 来部署我的 lambda。我发现这个过程非常缓慢且效率低下 - 例如。它可能需要几分钟,但如果它只是部署那个 1 功能应该只需要几秒钟?大多数功能都不会改变,但我相信 CloudFormation 不会区分并且无论如何都会部署所有内容。有没有办法可以更有效地做到这一点?比如检查发生了什么变化并只部署这些变化?

另一个好处是我可以有更少的版本?

【问题讨论】:

  • 您是否尝试通过 Jenkins 等 CI 运行它并检查是否有任何提交?
  • @BeshoyHanna,但通常 CI 是由新提交触发的,在我看来,这是不够的,因为新提交可能只会更改 1 个函数。或者 CI 可能同时部署基础设施和代码。有时只有基础设施更改(例如 terraform/CloudFormation)所以我不需要部署我的代码
  • 是的,我想你是对的,但我是在暗示每个函数可能有单独的存储库?
  • @BeshoyHanna,但这将意味着大量的回购:(
  • @Jiew Meng 能否提供一些示例代码?

标签: lambda continuous-integration amazon-cloudformation terraform


【解决方案1】:

您可以使用 aws_lambda_function 资源的 source_code_hash 让 Terraform 检查 Lambda 函数是否已更改。如果没有任何更改,则不会上传新版本,您的计划将显示无需更改。

这是example in the docs:

resource "aws_lambda_function" "test_lambda" {
  filename         = "lambda_function_payload.zip"
  function_name    = "lambda_function_name"
  role             = "${aws_iam_role.iam_for_lambda.arn}"
  handler          = "exports.test"
  source_code_hash = "${base64sha256(file("lambda_function_payload.zip"))}"
  runtime          = "nodejs8.10"

  environment {
    variables = {
      foo = "bar"
    }
  }
}

【讨论】:

  • 我不确定我是否正确,但我注意到即使更改了源代码并且我做了terraform apply,新的源代码也不会被应用。好像 terraform 更新了上次更新时间和哈希但没有上传新的 zip?
  • 可能值得编辑您的问题以显示您尝试过的内容以及您尝试让 Terraform 更新 Lambda 函数代码所遵循的步骤。查看 aws_lambda_function 资源的源代码,它从 AWS 获取函数包哈希,并独立检查与提供的 source_code_hash 相比,因此 Terraform 不可能忽略对包的更改而只是更新自己的状态文件。
  • 如果使用版本化的 lambda 函数,则需要在 aws_lambda_function 资源上设置 publish = true。 terraform.io/docs/providers/aws/r/lambda_function.html#publish
【解决方案2】:

我创建了this Terraform 模块来解决这个问题。即使设置 source_code_hash 也是不够的,因为在制作 zip 时,它们通常包含一些文件系统元数据。使用我的模块,哈希应该是稳定的(仅在源更改时才更改)。该模块特定于 Python,但哈希稳定性可以应用于任何运行时。

【讨论】:

    【解决方案3】:

    我在 gitlab 管道中使用 aws cli 在提交时部署和更新我的 lambda。

    我压缩内容。将其上传到 S3 并使用 S3 上的新工件触发函数更新。

    这比运行 Cloud Formation 模板快得多:

    # Filename
    FILENAME="${ARTIFACT_ID}-${version}-$BUILD_NUMBER.zip"
    zip -r -D $FILENAME ./*
    # Copy the bundle to s3
    aws s3 cp $FILENAME "s3://$S3_BUCKET/$FILENAME"
    # Trigger update of lambda function
    aws lambda update-function-code --function-name $LAMBDA_FUNCTION_NAME --s3-bucket $S3_BUCKET --s3-key $FILENAME
    

    希望对你有帮助。

    【讨论】:

      【解决方案4】:

      试试https://serverless.com。轻松部署 lambda 函数,您还可以通过几行创建其他资源,例如 dynamodb 或 s3 存储桶。

      1) 创建无服务器项目。

      serverless create --template aws-nodejs --path my-service
      

      2) 在 handler.js 文件中写入函数登录并部署。

      serverless deploy 
      

      3) 您可以在一项服务中创建多个功能。此外,您可以选择仅部署一项功能。

      serverless deploy // for all the functions in one service
      serverless deploy function -f functionName //deploy function with name 'functionName'
      

      您也可以从终端查看日志,无服务器框架也支持插件,例如您可以在 typescript 中编写源代码,而 typescript 的无服务器插件将自行完成其余的工作。 我已经使用无服务器很长一段时间了,这是我找到的持续集成的最佳解决方案。值得一试。

      【讨论】:

        猜你喜欢
        • 2021-04-18
        • 2020-04-15
        • 2018-09-14
        • 1970-01-01
        • 1970-01-01
        • 2017-11-02
        • 2021-01-28
        • 2017-10-21
        • 2020-06-24
        相关资源
        最近更新 更多