ec2 deployment planner/executor
Ruby
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
bin
lib
.gitignore
README.md
awsome.gemspec

README.md

awsome

An Amazon Web Services (AWS) environment manager tool designed to automate EC2 instance reconfigurations, scaling, and software deployments. Just change your YAML requirements file and let awsome do all the planning and heavy lifting.

One drawback is that in order to leverage software deployment features, all software must be packaged in Debian archives and all instances must run dpkg-enabled operating systems such as Ubuntu. For help with packaging your software in Debian archives, see https://github.com/0x0539/debstep.git. I use reprepro to manage Debian repositories in an automated fashion and would recommend it to a friend.

Prerequisites

Install the gem. It comes with a binary, so you may need to sudo.

gem install awsome

Next, download the EC2 api tools and the ELB api tools.

Getting Started

awsome takes a YAML file that describes your EC2 requirements as input:

options:
  except_instance_ids:           # instances to be ignored by the planner
  - i-11111111
  - i-22222222
  volumes:                       # any volumes you plan to attach/detach go here
  - id: vol-11111111
    device: /dev/sdf             # desired device name
    dir: /var/lib/mongodb        # mount point
    preumount: sudo stop mongodb # command to execute before unmounting/detaching
filters:
  - "tag:environment": prod      # only get instances tagged with 'production'
traits:
  base_trait:
    availability_zone: us-southwest-4a
    ami_id: ami-11111111
    key: xyz
    security_group_ids: default
    tags:
      environment: prod
instances:
- packages:                      # debian packages to deploy (latest version)
    - debian-package-1           
    - debian-package-2
  traits:                        # inherit properties from these traits
    - base_trait
  instance_type: m1.small
  elbs: 
    - elb-1
    - elb-2
  volumes:
    - vol-11111111
  cnames:                        # cnames to assign to this instance's private IP
    - zone: somezone.com.
      private:                   # these will use the internal ip-A-B-C-D DNS
      - mongodb.somezone.com.
      - internal.somezone.com.
      public:                    # these will use the external ec2-A-B-C-D DNS
      - external.somezone.com.

You need to declare some environment variables before you run the tool. A shell script that exports those variables will suffice:

export AWS_ACCESS_KEY="..."
export AWS_SECRET_KEY="..."
export AWS_CREDENTIAL_FILE="/path/to/credentials"
export AWS_ELB_HOME="/path/to/elb-cli-dir"
export EC2_HOME="/path/to/ec2-cli-dir"
export JAVA_HOME="/path/to/java/home"
export PATH="$PATH:$EC2_HOME/bin"
export PATH="$PATH:$AWS_ELB_HOME/bin"
export REGION="us-north-7"
export EC2_URL="https://ec2.$REGION.amazonaws.com"
export SSH_KEY="$HOME/.ssh/xyz.pem"
export SSH_USER="root"

Note: When invoking a script like this, make sure you use . path/to/script.sh or source path/to/script.sh instead of /bin/sh path/to/script.sh. Otherwise the environment variables will be defined in a subshell; they won't be there when the script ends.

The credentials file at AWS_CREDENTIAL_FILE is something you need to create for the ELB tools. It has the following format:

AWSAccessKeyId=...
AWSSecretKey=...

Running It

Once your environment variables have been defined and your requirements file is ready, you are ready to run awsome. It's usage is:

Usage: awsome [options]
    -r, --requirements [FILE]        Use a requirements file from another location (default is ./requirements.yml)
    -v, --verbose                    Print commands as they are executed
    -d, --debug                      Run ec2 commands with --debug
    -s, --stacks                     Print out full stack traces when commands are executed

You can run awsome --help to see usage and options from the command line.

In the grand scheme of things, awsome should probably be run by Jenkins or some other CI server. This can be easily accomplished by checking your requirements file into version control and running awsome on a post-commit hook.

Planning Algorithm

awsome attempts to plan the least-destructive upgrade to your EC2 environment possible. You can find the matching logic in lib/awsome/matchmaker.rb. Crudely speaking, it is performed in two basic steps.

1. Group instances and requirements by pool
2. For each pool, find the optimal mapping of running instances to requirements

Instances and requirements are assigned to the same pool if their compound keys match. The compound key of an instance or requirement is defined as:

``(ami_id, key, instance_type, availability_zone, security_group_ids)```

Those fields were chosen for the compound key because they are the only fields that cannot be changed once an instance has started (afaik).

The second component of the algorithm involves finding the optimal mapping of running instances to requirements. The only possible mapping of instances i1, i2 to requirements r1, r2 are:

1. {i1 => r1, i2 => r2}
2. {i1 => r2, i2 => r1}

All mappings are considered. I consider volume attachments/detachments to be more destructive than package removals/installations. awsome first chooses the mapping that minimizes volume attachments/detachments. In the event of a tie, awsome chooses the one that minimizes the number of package removals/installations.