Active Job is a framework for declaring jobs and making them run on a variety of queuing backends. In this post we’ll be setting up a worker environment on Elastic Beanstalk and using SQS as our Active Job queue.
We’ll be using the active-elastic-job to do the heavy lifting for us, so this post will be mostly focussed on the configuration to get this Gem working.
Our first port of call will be Simple Queue Service in our AWS account. We’ll need to create a new queue:
.
Now we have our queue we need to give our Elastic Beanstalk environments access to it. If we look at our existing environment we can see that it was created with an instance profile:
In my case the profile is called aws-elasticbeanstalk-ec2-role
. Make a note of this profile name and go to IAM users. Goto the roles tab and find the matching role. You now need to attach a policy to the role that allows access to SQS. In this demo we just use the SQS full access policy, but you may want to create a new policy that limits access to the queue you just created.
The active-elastic-job
needs to know which region we are running in so we need to add an AWS_REGION
environment variable. For my region this will be eu-west-1
you may be running in a different environment so check what your region is called.
We are now ready to create our worker environment. Goto your application and in the actions drop down click Create Environment
For the environment tier - pick Worker environment
:
Make sure to pick Ruby
as your Platform and then click Configure more options
. On the next screen make sure to change the platform configuration to match your web server environment.
Modify the Environment Settings
to give your new environment a sensible name (e.g. demo-worker).
Modify the Sofware
and copy across the following environment variables from your web env - DATABASE_URL
(so we can connect to the database), SECRET_KEY_BASE
(so we can encrypt and decrypt the same data) and AWS_REGION
(so the active-elastic-job
Gem knows which region we are in).
We also need to switch on processing of job in this environment. To do this we need to add PROCESS_ACTIVE_ELASTIC_JOBS
and set it to true.
Check the Security
to make sure the IAM instance profile
matches the one we modified for SQS access.
And finally open the Network
tab and select our VPC, choose our private subnets and the webserver
security group (the webserver security group gives access to the PostgreSQL database).
You can now click Create Environment
.
On the rails side we need to tell Active Job to use our active-elastic-job queue adapter. Add the active_elastic_job
to our Gemfile and run bundle install
. Now edit:
# config/environments/production.rb
config.active_job.queue_adapter = :active_elastic_job
In our Rails application create an Active Job by running
rails generate job capitalise_name
And in the code for our job set the queue_as
property to the name of the queue we created e.g:
class CapitaliseNameJob < ApplicationJob
queue_as :active_job_demo
def perform(person)
person.capitalized_name = person.name.capitalize
person.save!
end
end
And you can now add calls to this job in your code e.g:
CapitaliseNameJob.perform_later @person
Deploy the changes out to your web environment:
eb deploy --profile demo
And then deploy the same code out to your new worker environment:
eb use demo-worker --profile demo
eb deploy --profile demo
You can switch between different environments using (assuming your environments are name demo-web
and demo-worker
:
eb use demo-web --profile demo
eb use demo-worker --profile demo
Your ActiveJobs should now run successfully in your worker environment. If you have issues then check the elastic beanstalk logs on each environment:
eb use demo-web --profile demo
eb logs --profile demo
eb use demo-worker --profile demo
eb logs --profile demo