Introduction
AWS Elastic Container Service (ECS) is a popular, significantly simpler alternative to Kubernetes for container orchestration on the AWS platform.
While there is a very robust interface available as part of the AWS CLI for managing and working with ECS, this robustness and complexity can make simple tasks, such as running one-off jobs like database migrations or other maintenance operations within a running cluster, quite challenging.
To address this, I have developed a simple CLI tool that aims to streamline these specific tasks, making them more accessible and easier to execute.
Running a Database Migration
For demonstration purposes, I'll choose an application written in Ruby that uses the lightweight Sinatra library. This application doesn't handle database migrations in the same way as Ruby on Rails does. However, this approach works for any application running in ECS within a Docker container.
The deployment of the application to ECS is automated using GitHub Actions. Thanks to the configured health checks, if an error occurs after deploying a new application version due to an incorrect database schema version, the new version won't be deployed, and the previous version will continue running until the health check passes successfully.
At this point, there is already a task definition referencing the new version of the application, so I can use the runecs tool to execute the database migration.
runecs rake db:migrate --service my-cluster/my-service -w
The parameter -w
used here instructs runecs to wait for the migration job to complete, as the operation is executed asynchronously within the ECS environment. The runecs tool automatically uses the latest available task definition, ensuring that the correct version of the code containing the necessary database migration is used.
Once the database migration is successfully completed, the next attempt by ECS to launch the new version of the application will pass the health check, and the new version of the application will be deployed.
My application is packaged in a Docker image and includes many rake tasks that can perform various jobs in the application environment. This image is run in multiple containers that differ only by their entry point. For instance, one container is the web process, another container manages background jobs using Sidekiq, etc.
In the ECS environment, these containers are run in what are called services. For the example above, where I ran the database migration, I chose any service, since all of them use the identical Docker image. This ensured that the script for the database migration ran in the desired environment with the correct configuration.
Installation
The application is open source and hosted on GitHub, where you can find binary files for various operating systems. Since I'm an OS X user, I created support for installation via Homebrew, which I'll use to demonstrate how to install and use the tool.
brew tap meap/runecs
brew install runecs
After a successful installation, the tool is ready to use immediately. The last important step is granting permissions to access the ECS cluster, which is managed using AWS keys.
I use the direnv tool, which helps me manage keys at the directory level, so I can automatically set these keys as environment variables for each project.
After installing the direnv tool, I create a .envrc
file in the appropriate directory containing the necessary AWS keys.
meap@Petrs-MacBook-Pro runecs % cat .envrc
export AWS_ACCESS_KEY_ID=•••••
export AWS_SECRET_ACCESS_KEY=••••••
export AWS_REGION=eu-central-1
At this point, you can fully utilize runecs
.
Conclusion
The tool offers additional useful features, such as listing available clusters and services, removing old task revisions, and more. You can read more about it on GitHub.
I hope this tool makes your work easier, just as it has made mine. Feedback is, of course, welcome.
Top comments (0)