Today I want to share with you the project I’ve been working on for the last year in my free time. For me, the project has already been a success: it’s a pet project that has allowed me to learn a lot about Amazon Web Services, Docker and Ansible. But letting that aside, I believe is a useful project that can help you deploy your software better!
Wimpy is an open source Platform as a Service that you run from your terminal to deploy your applications to AWS, following cloud best practices.
Heavily inspired on the great Ansistrano, it’s built as a set of Ansible roles and it’s executed using an Ansible playbook in your application’s repository.
Wimpy’s goal is to make it easy to follow AWS best practices, embracing immutable infrastructure patterns where your servers are considered to be immutable. Whenever a new version is released, the servers get never updated but replaced by new servers containing the new released version.
Let’s see an example for a playbook, where you can configure how Wimpy will deploy your application:
- hosts: all connection: local vars: # Name of the application, used to name resources in AWS wimpy_application_name: "awesome-application" # Where your application is listening for HTTP requests wimpy_application_port: "80" # It will create a new DNS for awesome-application.armesto.net wimpy_aws_hosted_zone_name: "armesto.net" roles: - role: wimpy.environment - role: wimpy.build - role: wimpy.deploy
Now you can just run the playbook using Ansible, or, if you don’t have Ansible installed, you can just use our Docker image that contains Ansible and all Wimpy roles:
$ docker run -v /var/run/docker.sock:/var/run/docker.sock \ -v "$PWD:/app" fiunchinho/wimpy /app/deploy.yml \ --extra-vars "wimpy_release_version=`git rev-parse HEAD` \ wimpy_deployment_environment=production"
In this case, there are two variables that we want to pass on every deploy we make: the version being deployed and in which environment we want to deploy it. In this case, the version being deployed is the SHA1 commit hash from Git, but you can choose any arbitrary tag for your version, like “v1.4.2” or whatever.
Once executed, you can browse to http://awesome-application.armesto.net to see your application, and you will have a bunch of resources in your AWS account.
As I said earlier, Wimpy has been build with modularity in mind, so it’s not an all-or-nothing kind of tool. You can choose which roles to execute. Let’s see what these roles do.
First of all, this role will enable CloudTrail for your account, an audit log so you can track who-did-what-when in your account. It also registers a master key in KMS for applications to encrypt and decrypt secrets.
Your AWS account must be prepared before you can deploy your applications. By executing this role, your accout gets two different isolated environments called
production. Each environment gets its own Virtual Private Cloud, meaning that applications in one environment can’t connect to applications in a different environment. Total isolation between environments right from the start.
The same applies for S3. Wimpy creates a single bucket for all your applications, but each application will only be able to access the application folder in the environment where is running. For example, if your S3 bucket is called
storage, the application called
cats-api will have access to the
storage/production/cats-api/ folder when deployed in
production, but it will have access only to
storage/staging/cats-api/ when deployed in the
Last but not least, this role creates the needed security groups to allow traffic to your applications:
- From the internet to the Load Balancer specified port.
- From the Load Balancer to your application exposed port.
- From the application to the databases.
By default, any other access it not allowed, so for example, databases can’t be accesed from the internet.
Docker is not only great for running applications but for packaging as well. By using Docker for packaging, Wimpy is language agnostic and can deploy any application written in any language.
By default, this role will use an Elastic Container Registry on AWS to store your applications images, but you can choose any Docker Registry that you like.
On every deployment, it will package your application as a Docker image that can be run anywhere. Not only is available for the deployments in production, but different teams within your organization can start sharing their applications to make development easier.
This is probably the most interesting part! This role will deploy your application as an Auto Scaling Group with Scaling Policies that will scale up and down the number of instances. Each instance will run the application’s Docker container, supervised by systemd.
If you want, it will create a new Route53 DNS register pointing to your Load Balancer, which will balance the traffic between all the instances in your Auto Scaling Group.
The end result would be something like this:
The role offers two different deployment strategies.
Using this deployment strategy, we rely on the built-in Rolling Update mechanism for Auto Scaling Groups, where each instance of the Auto Scaling Group is replaced by a new instance that contains the version being deployed.
If something fails while replacing old instances with new ones, AWS will handle the rollback for us.
Blue / Green (Red / Black) deployment
In this strategy, we create a new CloudFormation for every deploy. This means that every deploy will generate a new Auto Scaling Group (which instances contain the version being deployed), a new Load Balancer and a new DNS register. Since now we have two different registers for the same domain name (one for each version deployed), Wimpy uses Route53 weighted registers to control how much traffic goes to every version.
You can tune how much traffic goes to new versions, so you can use this feature for canary releases. This is great for testing in production with real traffic.
I’ve two examples that show Wimpy in action
- Fork of the Symfony demo project, but adding Wimpy to deploy the application from Travis.
- Fork of the Spring pet-clinic demo project, also just adding Wimpy to be executed on every merge to master.
Wimpy tries to help you automate your deployments and infrastructure best practices in the AWS, making sure that different teams within your organization all deploy applications the same way.
It’s composed by different roles that you can combine, or even extend, building your own roles/tasks.
Everything is created on your own AWS account. That means that you are in full control of your resources, and if you don’t want to use Wimpy anymore, you won’t lose anything.
You can learn more about the project in the documentation page. Feel free to read through the code in the Github organization. Contributions are really welcomed!
Finally, I’d like to thank all the people that have helped me during the development of this project. This would’ve never happened without them, specially: