Automatically Deploy following AWS Best Practices

Wimpy is a opinionated deploy pipeline that implements best-practices for deploying applications on AWS (Amazon Web Services). It’s build as a set of Ansible roles that you can run in a playbook. And since it’s ran by Ansible, it’s really easy to extend to do exactly what you want.

Following Continuous Deployment practices, you can execute the playbook on every change merged to your application master branch so on every change Wimpy will

Installation

Wimpy is a set of Ansible roles but you don’t really need to know how Ansible works.

Using Wimpy from Docker

Instead of installing Ansible and the roles, you can just use our Docker image that contains everything you need for running Wimpy.

$ docker run --rm -it \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v "$PWD:/app" \
    -e AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY -e AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY \
    fiunchinho/wimpy /app/deploy.yml --extra-vars "wimpy_release_version=`git rev-parse HEAD` wimpy_deployment_environment=production"

Using Wimpy locally

You will need to install Ansible and the Wimpy roles that you wan to use.

The following commands will install the roles from the Github repository. You can specify which version of each role you want to install. In this example we are installing the master version

$ ansible-galaxy install git+https://github.com/wimpy/wimpy.build.git,master
$ ansible-galaxy install git+https://github.com/wimpy/wimpy.deploy.git,master
$ ansible-galaxy install git+https://github.com/wimpy/wimpy.ecr.git,master

Usage

Ansible executes commands using what they call “playbooks”, which is like a list of tasks to execute. A playbook contains tasks or roles. A role is a set of tasks that we group together.

Now that we know basic Ansible jargon, create a playbook called, for instance, deploy.yml. An example of deploy.yml file to deploy our application could be:

- hosts: localhost
  connection: local
  vars:
    wimpy_application_name: "my-awesome-project"
    wimpy_application_port: "8080"
  roles:
    - role: wimpy.environment
    - role: wimpy.build
    - role: wimpy.deploy

And use Ansible (or our Docker image) to run it

$ docker run --rm -it \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v "$PWD:/app" \
    -e AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY -e AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY \
    fiunchinho/wimpy /app/deploy.yml --extra-vars "wimpy_release_version=v1.2.3 wimpy_deployment_environment=production"

The cool thing about Wimpy being built using Ansible roles is that you can choose exactly which ones you want to execute. For example, if you just want to build a Docker Image and push it to Amazon Elastic Container Registry (ECR), without deploying anything, just remove the wimpy.deploy role

- hosts: localhost
  connection: local
  vars:
    wimpy_application_name: "my-awesome-application"
  roles:
    - role: wimpy.environment
    - role: wimpy.build

And run it

$ docker run --rm -it \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v "$PWD:/app" \
    -e AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY -e AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY \
    fiunchinho/wimpy /app/deploy.yml --extra-vars "wimpy_release_version=`git rev-parse HEAD`"

This helps you build your Continuous Integration / Continuous Deployment pipeline exactly the way you want it.

Parameters

As you saw in the last section, Wimpy roles need some info about your application to work properly, like the project’s name or the AWS region. Ansible offers several ways of passing parameters to playbooks like vars, vars_files or even extra-vars, that you can mix together, and Wimpy will work fine with any of those.

When passing parameters to our playbook, a pattern that has been working wonders for us is the following:

For example, let’s have a different yaml file for every environment. This would be our staging.yml

wimpy_aws_hosted_zone_name: "staging.example.com"

And this our production.yml

wimpy_aws_hosted_zone_name: "example.com"
wimpy_aws_elb_scheme: "internal"

Then make our playbook to load the right file depending on the chosen environment.

- hosts: localhost
  connection: local
  # Load here variables that change for every environment
  vars_files:
    - "{{ playbook_dir }}/{{ wimpy_deployment_environment }}.yml"
  vars:
    # Put here parameters that remain the same across deployments/environments
    wimpy_application_name: "my-awesome-application"
    wimpy_application_port: 8080
  roles:
    - role: wimpy.environment
    - role: wimpy.build
    - role: wimpy.deploy

And run the playbook passing the parameters that change on every deployment: the version of your application that you want to deploy (typically a Git SHA1 commit) and to which environment you want to deploy it.

$ docker run --rm -it \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v "$PWD:/app" \
    -e AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY -e AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY \
    fiunchinho/wimpy /app/deploy.yml --extra-vars "wimpy_release_version=git rev-parse HEAD wimpy_deployment_environment=production"

Learn More