Jets Gem Layer

This gem provides a framework for automatically creating and publish an AWS Lambda Layer from project gems and their linked libraries for use with Ruby on Jets.

This gem creates a Lambda Layer based on your Jets project namespace and ruby version. I.e. for the app demo in production environment, the Lambda Layer demo-prod-ruby-3_2_2-gem_layer will be created or its version incremented as needed. A new version is published whenever your Gemfile.lock and/or Gemfile is changed (this is tracked based on a hash value stored in the Lambda Layer version description).

  • The gem's build task runs in a docker container, i.e. public.ecr.aws/sam/build-ruby:3.2. The container version is based on the current minor ruby version (i.e. 3.2 for ruby 3.2.2, so ensure your build environment's ruby version is correctly set for your project.
  • Docker is a prerequisite and must be installed to use this gem.
  • This gem has not been tested to work on windows machines.

Installation

  1. Jets Pro would typically be disabled when using this gem so as to not generate duplicative Lambda Layers.
# config/application.rb

config.pro.disable = true
  1. The layer ARN created by this gem must be inserted so it is referenced on app deployment. The easiest way to do this is to add the included helper to your environment configuration.
# config/production.rb

# JetsGemLayer.arn will resolve to the latest version of the published Layer, also looking for a correct hash in the
# layer description indicating the current Gemfile.lock and Gemfile are supported.
# If a suitable layer is not found, the gem will log an error and resolve to 'error-fetching-gem-layer-arn' which will allow your
# application to run locally but hopefully prevent an invalid deployment
config.lambda.layers = [JetsGemLayer.arn]
  1. Add this gem to your Gemfile:

    # Gemfile
    gem 'jets_gem_layer'
    
  2. Add the gem's initializer to your Rakefile

    # Rakefile
    

require 'jets' require_relative 'config/application'

Jets.application.load_tasks JetsGemLayer.load_tasks


3. After running `bundle install`, run `rake -T` and you should see this Gem's tasks available for use.

➜ rake -T rake gem_layer:build_and_publish # Build, publish, and clean (will be a no-op if already published) rake gem_layer:build # Build the gem layer zip file rake gem_layer:publish # Publish the built gem laye zip to AWS rake gem_layer:clean # Clean up the gem's tmp files rake gem_layer:cleanup_published # Deletes all prior versions of the lamda layer from AWS rake gem_layer:delete_all_published # Deletes all versions of the lamda layer from AWS


## Configuration

The following environmental variables may be used:
* `GEM_LAYER_ENV`: Comma-separated `key=value` pairs which will be added to the docker build environment.
For example, to pass a Gemfury token for Bundler, you could use `GEM_LAYER_ENV="BUNDLE_GEM__FURY__IO=xxyyzz"`
and `BUNDLE_GEM__FURY__IO` will be set correctly within the build container.
* `GEM_LAYER_PACKAGE_DEPENDENCIES`: use this to identify comma separated dependencies required for bundle install
specific to your Gemfile. For example, to build the `mysql2` gem you will need to set `GEM_LAYER_PACKAGE_DEPENDENCIES=mysql-devel`.
Dependencies will be installed within the build container and copied into the published Lambda Layer.

## Deployment
Within your project directory (example for development environment) or through your CI/CD platform:
1. `JETS_ENV=development JETS_AGREE=no rake gem_layer:build_and_publish`
   * If needed, builds and publishes a new gem layer version based on the current Jets namespace, Gemfile.lock and Gemfile
2. `JETS_ENV=development JETS_AGREE=no jets deploy`
   * Deploy your application
3. `JETS_ENV=development JETS_AGREE=no rake gem_layer:cleanup_published`
   * After a successful deploy, you may run this to cleanup the old gem layer version(s) no longer in use

## Acknowledgements
A big thank you to the authors of [Lambda Layer Cake](https://github.com/loganb/lambda-layer-cake), which served as a reference.