How To Run Migrations on AWS ECS and Other One off Tasks
Tung Nguyen
Creator of Jets, Terraspace, Lono, Kubes, Ufo, Cody / AWS Container Hero / Proud Dad
Once a developer came up to me and told me that he was ready to deploy, but the deploy required migrations be run. He asked me an innocent question, how should he run migrations. Embarrassingly, because we were still evolving our tooling for the new infrastructure, we did not have a process for this simple task. We came up with an ad-hoc process that was honestly pretty terrible. It went like this:
- Deploy the app with only the migrations and no other code changes.
- Ssh into the server and docker exec into the container.
- Run the migrations.
- Deploy the app again with the new code changes.
It was such a terrible process that I would notice developers creatively taking their own “shortcut” route to save time:
- Deploy the app with both the code changes and migrations together.
- Hustle and ssh into the server and quickly docker exec into the container.
- Run the migrations.
The second flow would cause issues when the new code ran while the migration still hadn’t been run. Even after the migrations were ran, the app still sometimes continue to error. We would then frantically restart the app to make all well again. I can sympathize developers trying to take the “shortcut” route. Having to do extra manually work at the very end when you have spent all week busting your hump writing code just does not jive well.
In this post, I’ll go over how to run Rails Migrations on AWS ECS in a sane manner without the extra manual work.
ECS Task vs Service
Let’s think about the ways we can run docker containers with AWS ECS. ECS can both run a single one-off task and a long running-service task. The one-off ECS single task is a perfect fit for running migrations. What we need to do is:
- Build a docker image.
- Build and register a task definition.
- Execute a one-off ECS task.
Enter UFO
UFO is a tool that helps you easily build and ship your docker images to AWS ECS. UFO also comes with a handy ufo task command that allows you to run a one-off task. The documentation for it is available on the official ufo Run Single Task documentation. It effectively automates the process mentioned above. Usage is simple:
ufo task hi-web --command bundle exec rake db:migrate
One of the things you can do is set this up on a continuous integration provider like CircleCI or Jenkins, so all the developer needs to do is commit his or her migration to a specific migrate branch, and the CI will run the ufo task command.
The ufo task allows you to quickly deploy and run any code you’d like without lots of manual efforts. No more excuses to cause yourself pain ?? Hope you found this helpful.
Thanks for reading this far. If you found this article useful and would like to see more articles like this follow me. I'd really appreciate it also if you like this article (by clicking the ?? button) so others can find it too! Also connect with me on LinkedIn.
P.S. Be sure to subscribe to receive free DevOps tips and updates.
Creator of Jets, Terraspace, Lono, Kubes, Ufo, Cody / AWS Container Hero / Proud Dad
7 年Roger Lam Thanks! Glad you found it useful. RE: Do you have to make sure your migration is backwards compatible? Ah, thanks. Yup with the newer Rails 5 we should have the db migration version in the class. Good catch. RE: And what do you think about deploying the commit on the service to keep the commit revisions the same? So usually migrations are done separately from application deploys since application deploys are ideally set up so the nodes are autoscaling. With autoscaling, a "deploy" can happen at any time so db migrations are nice to have in a separate task. If you want to make sure that the commit is tracked as part of the migration process and have it completely auditable. One approach I've taken is to run this process on a CI machine, CircleCI, Jenkins, whatever your thing is. Have developers commit their migration into a "migrate" branch and the CI build will pick it up and run the migration. So the only dependency for the developer is having git installed. The tools are installed the remote machine and handle everything for you.
Learning the ins and outs of ML/AI and sharing along the way.
7 年Great post! Do you have to make sure your migration is backwards compatible? And what do you think about deploying the commit on the service to keep the commit revisions the same?