Search code examples
rubyamazon-web-servicesaws-lambda

Cannot load file mysql2 on AWS Lambda


Trying to have a Lambda connect to an RDS database but can't get the mysql2 gem to load. Tried the pristine instruction but that didn't resolve the issue.

I've got the built mysql2 gem in the vendor directory. Did this using bundle install --deployment.

Presumably this is a problem because of the compiled extensions used by mysql2. Not sure how I can sort this for AWS Lambda though. Thoughts?

Here's the log output:

START RequestId: 62f35c49-039f-11e9-be04-1fd1111df42b Version: $LATEST
Ignoring mysql2-0.5.2 because its extensions are not built. Try: gem pristine mysql2 --version 0.5.2
Init error when loading handler lambda_function.lambda_handler
{
  "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/lambda_function.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'"
  ]
}
END RequestId: 62f35c49-039f-11e9-be04-1fd1111df42b
REPORT RequestId: 62f35c49-039f-11e9-be04-1fd1111df42b  Duration: 1439.17 ms    Billed Duration: 1500 ms    Memory Size: 128 MB Max Memory Used: 17 MB  
Unknown application error occurred
Init<LoadError>

Here's my Gemfile:

source 'https://rubygems.org'

gem 'mysql2', '~> 0.5.2'
gem 'sequel', '~> 5.15.0'

Gemfile.lock

GEM
remote: https://rubygems.org/
specs:
  mysql2 (0.5.2)
  sequel (5.15.0)

PLATFORMS
  ruby

DEPENDENCIES
  mysql2 (~> 0.5.2)
  sequel (~> 5.15.0)

BUNDLED WITH
  1.17.2

Here's the top of my lambda_function.rb file

require 'json'
require 'logger'
require 'mysql2'
require 'sequel'

Solution

  • Prerequesties: * Docker

    Create a docker file like this

        FROM lambci/lambda:build-ruby2.5
        RUN yum -y install mysql-devel
        RUN gem update bundler
        CMD "/bin/bash"
    

    Build the docker

        docker build -t lambda-ruby2.5-mysqldep .
    

    Docker run in your source code folder with the below command

        docker run --rm -it -v $PWD:/var/task -w /var/task lambda-ruby2.5-mysqldep
    

    It will get you into the bash Inside the bash

    • move the mysql folder from /usr/lib64/mysql to /usr/mysql
    • mkdir -p /var/task/lib
    • cp -a /usr/mysql/.so. /var/task/lib/
    • bundle config --local build.mysql --with-mysql-config=/usr/local/mysql/bin/mysql_config
    • bundle install with and without deployment

    Then exit the bash. And create a lambda deployment package and upload it to AWS. It worked for me