Ruby 如何让我的AWS Lambda访问存储在供应商/捆绑包中的gems?

Ruby 如何让我的AWS Lambda访问存储在供应商/捆绑包中的gems?,ruby,amazon-web-services,aws-lambda,bundler,Ruby,Amazon Web Services,Aws Lambda,Bundler,我正在用Ruby编写一个Lambda函数,它最终将通过Webhook在Slack中向我发送一些通知。因此,我的lambda_函数文件 require 'json' require 'webhook' def lambda_handler(event:, context:) # TODO implement { statusCode: 200, body: JSON.generate('Hello from Lambda!') } Webhook.post('https:

我正在用Ruby编写一个Lambda函数,它最终将通过Webhook在Slack中向我发送一些通知。因此,我的
lambda_函数
文件

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
bath下还有其他几个文件夹,包括
build\u info
cache
doc
等。为了将此代码放到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'"
  ]
}
{
“errorMessage”:“无法加载此文件--webhook”,
“errorType”:“初始化”,
“stackTrace”:[
“/var/lang/lib/ruby/2.5.0/rubygems/core\u ext/kernel\u require.rb:59:in`require'”,
“/var/lang/lib/ruby/2.5.0/rubygems/core\u ext/kernel\u require.rb:59:in`require'”,
“/var/task/lambda_function.rb:2:in`'”,
“/var/lang/lib/ruby/2.5.0/rubygems/core\u ext/kernel\u require.rb:59:in`require'”,
“/var/lang/lib/ruby/2.5.0/rubygems/core\u ext/kernel\u require.rb:59:in`require'”
]
}

不应该有更多的,因为它显示了如何设置我所拥有的,但不起作用。是否有人成功地从AWS Lambda中的Gem文件中提取Gem?

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


您的zip似乎在2.3.0中安装了gems,但堆栈跟踪列表为2.5.0。这种不匹配意味着lambda runner无法找到您的宝石

我在使用Ruby构建AWS Lambda层时遇到了同样的问题。一种快速而简单的方法是将所有gem路径添加到AWS Lambda中Ruby的$LOAD_路径中。即:

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”

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


当我们通过bundler运行rails时,它为我们带来了一系列“魔力”,包括确保我们的$LOAD_路径指向宝石。由于AWS lambda不使用bundler,我们需要自己做一些“魔术”。

我认为您不应该更改GEM_路径,也不应该在每个lambda函数中设置
$LOAD_路径。
“最佳”方法是在创建图层存档时进行以下小技巧:

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/

您在2.3.0下绑定,并在2.5.0下运行。这可能是一个很好的开始。我在尝试使用GitHub(
master
branch)的gem时遇到了类似的问题。我的gem的路径似乎不一样,它位于:
/vendor/bundle/ruby/2.5.0/bundler/gems/
下。这意味着我必须调整这两行代码,使其看起来像这样:
load\u path=Dir[“/vendor/bundle/ruby/2.5.0/bundler/gems/**/lib”]
。我不知道这是否有什么不同:我使用的是
bundler
version 2.0.1。我需要这个和
2.3
->
2.5
答案。对于那些寻找简单示例的人,你可以在这里找到一个: