如何获得AWS Lambda来访问存储在供应商/捆绑包中的gem?

时间:2018-12-05 14:12:50

标签: ruby amazon-web-services aws-lambda bundler

我正在用Ruby编写Lambda函数,最终将通过Webhook在Slack中向我发送一些通知。所以我的lambda_function文件是

require 'json'
require 'webhook'

def lambda_handler(event:, context:)
    # TODO implement
    { statusCode: 200, body: JSON.generate('Hello from Lambda!') }
    Webhook.post('https://mywebhookurl', {message: 'test'})
end

内联代码编辑器中的目录结构如下:

Gemfile
Gemfile.lock
lambda_function.rb
vendor/
  bundle/
    ruby
      2.3.0
        gems/webhook

2.3.0浴下还有其他几个文件夹,包括build_infocachedoc等。为了将这段代码添加到AWS Lambda,我正在运行

zip -r myLambda.zip *将所有内容打包成zip文件并上传到Lambda。

但是,当我最终去对lambda运行基本测试时,出现以下错误:

{
  "errorMessage": "cannot load such file -- webhook",
  "errorType": "Init<LoadError>",
  "stackTrace": [
    "/var/lang/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'",
    "/var/lang/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'",
    "/var/task/lambda_function.rb:2:in `<top (required)>'",
    "/var/lang/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'",
    "/var/lang/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'"
  ]
}

这里应该没有其他内容了,因为following tutorial确实显示了如何设置我拥有的东西,但是不起作用。有谁能成功从AWS Lambda的gemfile中提取gem?

3 个答案:

答案 0 :(得分:12)

在构建带Ruby的AWS Lambda层时遇到了同样的问题。快速简便的方法是将所有gem路径添加到AWS Lambda中Ruby的$ LOAD_PATH中。 IE:

load_paths = Dir["/opt/ruby/gems/2.5.0/**/lib"]
$LOAD_PATH.unshift(*load_paths)

require 'webhook'

在您的情况下,将"/opt/ruby/gems/2.5.0/**/lib"替换为"./vendor/bundle/ruby/2.3.0/gems/**/lib"

执行require 'webhook'时,它将遍历所有路径并遇到"./vendor/bundle/ruby/2.3.0/gems/webhook-1.0.0/lib/webhook.rb",并将其添加到您的AWS Lambda中。 require不需要文件扩展名。

当我们通过捆绑器运行rails时,对我们来说是很多“魔术”,包括确保$ LOAD_PATH指向gems。由于AWS Lambda不使用捆绑程序,因此我们需要自己做一些“魔术”。

答案 1 :(得分:8)

您需要确保本地捆绑使用的Ruby版本与Lambda使用的版本匹配。

您的zip文件似乎已在2.3.0中安装了gems,但是堆栈跟踪列表中显示了2.5.0。这种不匹配意味着Lambda跑步者找不到您的宝石。

答案 2 :(得分:2)

我认为您不应该更改GEM_PATH或不必在每个lambda函数中设置$LOAD_PATH。 “最佳”方法是在创建图层存档时进行以下操作:

bundle install --path vendor/bundle
cd vendor/bundle
mkdir ruby/gems
mv ruby/2.5.0 ruby/gems/
zip -r layer.zip ruby/gems/2.5.0/