AWS Developer Tools Blog

Introducing new features for the aws-sdk-rails gem

The Ruby SDK team is happy to announce that we’ve added new features and consolidated existing gems into the aws-sdk-rails gem to make developing Rails applications using AWS easier than ever.

Features supported

  • Amazon Simple Queue Service (SQS) queue adapter for ActiveJob (new)
  • ActiveSupport::Notification instrumentation (new)
  • DynamoDB ActiveDispatch::Session implementation (new)
  • Include Aws::Record with Rails migration tasks and model generators (new)
  • Amazon Simple Email Service (SES) as an ActionMailer Delivery Method (existing)
  • Automatically configures SDK logging to the Rails logger (existing)
  • Loading of AWS Credentials using Rails encrypted credentials (existing)

Using aws-sdk-rails

Add this gem to your Rails project’s Gemfile:

# Gemfile
gem 'aws-sdk-rails'

By default, aws-sdk-rails only enables logging and loading of credentials using Rails encrypted credentials. All other features are optional and will require some additional configuration.

You will have to ensure that you provide AWS credentials for the SDK to use. You can add them to your Rails encrypted credentials under the :aws key or see the AWS SDK for Ruby Documentation for other ways to configure credentials. Never commit your credentials to source control. Besides being a security risk, it makes it very difficult to rotate your credentials.

DynamoDB Session Store

You can configure ActionDispatch::Session storage in Rails to use DynamoDB instead of cookies, allowing access to sessions from other applications and devices. You will need to have an existing DynamoDB session table to use this feature.

This table can be created manually, or using the ActiveRecord migration generator included with this gem:

rails generate dynamo_db:session_store_migration

Active Support Notification Instrumentation for AWS SDK calls

You can now instrument AWS SDK service calls using ActiveSupport::Notifications. From a Rails initializer, you can enable this feature before you construct any SDK clients:

# config/initializers/aws.rb
Aws::Rails.instrument_sdk_operations
# create client.. etc

Once done, you can create a subscriber to perform actions when SDK calls are made:

ActiveSupport::Notifications.subscribe('put_object.s3.aws') do |name, start, finish, id, payload|
  # process event
end

# Or use a regex to subscribe to all service notifications
ActiveSupport::Notifications.subscribe(/s3[.]aws/) do |name, start, finish, id, payload|
  # process event
end

AWS SQS Active Job

This gem includes a lightweight, high performance SQS backend for ActiveJob. To use SQS for ActiveJob, you first need to:

1. Create a job:
rails generate job greeting

This will generate a job which you can edit:

class GreetingJob < ApplicationJob
  queue_as :default

  def perform(name)
    Rails.logger.info "Hello #{name}" 
  end
end

2. Configure the queuing backend:

# config/application.rb
# for non-blocking (async), use :amazon_sqs_async
config.active_job.queue_adapter = :amazon_sqs

3. Map Rails Queues to your SQS Queue URLs:

# config/aws_sqs_active_job.yml
queues:
  default: 'https://my-queue-url.amazon.aws'

4. Queue up jobs

# in your business logic or from rails console
GreetingJob.perform_later('Person1')
GreetingJob.set(wait: 5.minutes).perform_later('Person2')

To start processing jobs, you need to start a separate process using an executable script (bin/aws_sqs_active_job) provided with this gem. When running in production, its recommended that use a process supervisor such as foreman, systemd, daemontools, etc. Run the backend poller and execute jobs:

RAILS_ENV=development bundle exec aws_sqs_active_job --queue default

At this point you should see output from the jobs you queued up earlier. The poller will poll indefinitely until you kill it. You can use CTRL+C to cleanly shutdown the poller – it will wait for currently executing jobs to finish before exiting.

Serverless workers: processing activejobs using AWS Lambda

Rather than managing the worker processes yourself, you can use Lambda with an SQS Trigger. With Lambda Container Image Support and the lambda handler provided with aws-sdk-rails its easy to use lambda to run ActiveJobs for your dockerized rails app (see below for some tips). All you need to do is:

1. Include the aws_lambda_ric gem
2. Push your image to ECR
3. Create a lambda function from your image (see the Lambda docs for details).
4. Add an SQS Trigger for the queue(s) you want to process jobs from.
5. Set the ENTRYPOINT to /usr/local/bundle/bin/aws_lambda_ric and the CMD to config/environment.Aws::Rails::SqsActiveJob.lambda_job_handler – this will load Rails and then use the lambda handler provided by aws-sdk-rails. You can do this either as function config or in your Dockerfile.

Aws::Record integration and generators

This gem now ships with aws-record if you would like to use it. aws-record is a DynamoDB model abstraction similar to ActiveRecord for SQL. Included with this gem is a rails generator for creating models, as well as a rake task for performing migrations (referred to as Table Config).

# generate a model in app/models
rails generate aws_record:model Forum --table-config primary:10-5
# runs all migrations in app/db/table_config
rake aws_record:migrate

Available Now

The aws-sdk-rails gem is available now on rubygems.org. As always, we’d love to hear your feedback, and welcome any Issues or Pull Requests at the aws-sdk-rails GitHub repo.