I’ve migrated a couple of clients from Heroku to Elastic Beanstalk, so I’ve put together these high-level instructions on how to set up your Rails application to work on Elastic Beanstalk:
Web processes
Within Elastic Beanstalk, you have multiple ways in which you can run your Rails application.
You can use Elastic Beanstalk’s Ruby platform to deploy your Rails application directly on a preconfigured EC2 instance. It will require you to learn how Amazon chose to set up this platform and how you’re supposed to integrate your application with it.
If you have a little Docker experience, a better approach in my opinion would be to use Elastic Beanstalk’s Docker platform and deploy your Rails application as a Docker container.
You can use Heroku’s cedar Docker image as a base for your Rails container, or you can create your own Rails image by following this tutorial. Either way, assuming you have a basic experience with Docker, you’ll quickly end up with a deployable artifact which will be less dependent on the environment it’s running on.
Just pay attention to the fact that at the moment Elastic Beanstalk has two versions of its Docker platform. The first version allows you to run one Docker container per EC2 instance. The second version uses AWS ECS (Elastic Container Service) to schedule multiple Docker containers on the same EC2 machine. I recommend that you use the second version even if you think you won’t need the multicontainer functionality.
Background jobs
If you’re using asynchronous workers as part of your Rails application, there are a couple of ways you can make them run on Elastic Beanstalk.
You can use the Docker’s multicontainer platform to run the worker process along with your Rails web process on the same EC2 machines. You can utilize a similar approach for the regular, non Docker Rails platform. Use “.ebextensions” to configure the worker daemon on all the EC2 instances that run your web processes.
The main disadvantage of this approach is that you won’t be able to scale your worker tier capacity separately from the web tier. And depending on the nature of your applications, the worker and the web process may compete for resources which also can be undesirable.
Another approach is to use Elastic Beanstalk’s worker environment. You still will be able to use the same Docker/Rails platforms, but Elastic Beanstalk won’t attach a load balancer to your worker applications. Instead, it will create an SQS queue and run an agent on each EC2 machine running your application which will post the content of an SQS message to your application. There is no official support for other queues than SQS, however you can always make your application ignore the local SQS agent and just listen to any other queuing system you would like to use.
Database migration
As Richard mentioned in his answer, the simplest way to migrate the Postgresql database from Heroku to RDS (Amazon’s managed database service) will require some sort of a downtime of your application while you export and import the database data from one platform to another. Fortunately, in most of the migrations I’ve done, this wasn’t a huge problem, it was always possible to find the time when a small maintenance window could be scheduled, usually during the times of day when the site has less active users.
Another important topic to cover is how to migrate Heroku addons you’re using in your applications to Elastic Beanstalk. You mentioned that you use very little of third-party services, therefore I won’t cover how to migrate these services along your application to AWS.
If you want to learn more about Heroku addons migration, I’ve published an article which goes into details on how to replicate Heroku addons on AWS.
Hope that helps.