Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Lambda: Ruby function failing to load gem

I have a Ruby Lambda function which depends on an external (ie non-AWS) RubyGem. I have a Gemfile, a Gemfile.lock and a vendor/bundle directory. Everything looks fine from a local perspective.

I've tried using bundle install --path vendor/bundle and bundle install --deployment to install the gems, and am specifically including the vendor directory when zipping up the files: zip -r function.zip myfunction.rb vendor

Despite this, when I test the function in the Lambda console, it's failing with errors complaining about not being able to find the libraries, e.g.

{
  "errorMessage": "cannot load such file -- mysql2",
  "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/hello_ruby_record.rb:3: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'"
  ]
}

Presumably I'm doing something really obviously wrong in bundling up the gems before uploading the function; but I can't figure out what. Does anyone have any ideas?

like image 567
TimD Avatar asked Dec 07 '18 16:12

TimD


2 Answers

I faced the same issue. The underlying reason is different ruby versions being used in local and Lambda function. Currently AWS Lambda is using Ruby 2.5 and your gems are located at '/vendor/bundle/ruby/'. Thus your lambda function is unable to locate the gem libraries uploaded by you. To override the gem path with your Ruby version, add the below mentioned code at the top of your file containing the handler function:

  my_gem_path = Dir["./vendor/bundle/ruby/<your-ruby-version>/gems/**/lib"]
  $LOAD_PATH.unshift(*my_gem_path)

Or, just try upgrading and matching your local Ruby version with the exact version used by Lambda function viz 2.5 currently.

like image 145
Abhishek Sinha Avatar answered Oct 23 '22 18:10

Abhishek Sinha


Please do make sure your bundle config is exactly this:

BUNDLE_PATH: "vendor/bundle"

If you just follow what the official document says:

To update a Ruby function with dependencies

  1. Install libraries in the vendor directory using the bundle command.
bundle config set --local path 'vendor/bundle' \ 
bundle install

......

You will get a redundant trailing space, which mess things up:

BUNDLE_PATH: "vendor/bundle " <-- a trailing space here

I am using ruby 2.7.3p183 (2021-04-05 revision 6847ee089d) [x86_64-darwin19] and it works without problem.

like image 40
hungmi Avatar answered Oct 23 '22 18:10

hungmi