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
- 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
- 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/application.rb
require 'jets_gem_layer'
module CrmBroker
class Application < Jets::Application
# 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]
# ...
end
end
- Add this gem to your Gemfile:
# Gemfile
gem 'jets_gem_layer'
- Add the gem's initializer to your Rakefile
# Rakefile
require 'jets'
require_relative 'config/application'
Jets.application.load_tasks
JetsGemLayer.load_tasks
- After running
bundle install
, runrake -T
and you should see this Gem's tasks available for use.
➜ rake -T
rake gem_layer:build_and_publish # Build and publish a gem layer version, if necessary
rake gem_layer:build # Build a gem layer zip file
rake gem_layer:publish # Publish the already built layer zip file
rake gem_layer:clean # Clean jets_gem_layer tmp files
rake gem_layer:cleanup_published # Delete old layer versions from AWS (for use after deployment)
rake gem_layer:delete_all_published # Delete all published versions of the gem layer from AWS
Configuration
The following environmental variables may be used:
-
GEM_LAYER_ENV
: Comma-separatedkey=value
pairs which will be added to the docker build environment. For example, to pass a Gemfury token for Bundler, you could useGEM_LAYER_ENV="BUNDLE_GEM__FURY__IO=xxyyzz"
andBUNDLE_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 themysql2
gem you will need to setGEM_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:
-
JETS_ENV=development 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
-
JETS_ENV=development JETS_AGREE=no jets deploy
- Deploy your application
-
JETS_ENV=development 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
Important: The zip command must be installed in your environment or the layer will fail to zip and upload. Perhaps we will switch to rubyzip in the future.
Acknowledgements
A big thank you to the authors of Lambda Layer Cake, which served as a reference.