· ansible devops

Ansible autoscale (tower) alternatives

In my last post, I wanted to deploy a cluster of workers, but stopped after setting up autoscaling groups as I wanted a “nice” way to build them up. I could have plowed on with a userdata script that was built with the original master server ip, followed by using ansible-playbook to download and execute some plays. In fact, that seems awfully reasonable to me right now instead of going on this yak-shaving adventure. Unfortunately, there are times for push and there are times for pull, and this is a time for pull.

But let’s press on. We still would like an alternative to setting up clusters of servers that isn’t dependent on either setting up ip’s into a userdata script or moving that level of abstraction up to s3 and putting the ip up there. Those solutions do work, but are sub-optimal for anything remotely complex with multiple masters or partitions. The ansible knockd comment pretty much says it all - “And at that point I might as well just use chef – this whole setup is to avoid running an open service and having to manage agents and certs.”

Ansible tower does support autoscaling. They do callbacks with a shared secret, with some userdata script that calls back to the server. The server then verifies that the node doing the callback is indeed in the correct ec2 autoscale group, etc. and kicks off the playbooks. But it’s not free and looks like it requires some GUI configuration.

Some must-have’s regarding this:

There’s semaphore, which seems to be only a GUI for ansible. After some fixes, it requires a lot of manual intervention and doesn’t support autoscaling yet.

This type of stuff makes me want to go back to Chef. I could easily automate the creation of a temporary chef server, run my stuff and be done. In fact, that’s exactly what I’ve been doing for the past year for all my vagrant lxc hosts since I didn’t find chef-zero good enough at the time. Of course, what I wanted to avoid was the 30 minutes and 300 lines of code to bootstrap a chef-server.

But to continue on this adventure, we’ll need to setup a server on EC2 to execute commands on all the other nodes. So taking inspiration from the knockd post, I’ve created a role that should take care of the autoscaling problem.


It does the following during the bootstrap:

The callback application:

Setting up the ansible autoscale master

We’ll can test this out with the example playbook in the repo. It will setup the ansible_asg_master, the launch configuration, and then the autoscale group. The newly created worker will then connect back to the ansible_asg_master on the private ip address, which will launch an ansible run. The userdata script specifies the playbook to run, in this case:

- name: Create autoscale group
  hosts: localhost
  connection: local
  gather_facts: False
    # This will get set to run during the callback to the master server
    userdata_playbook: worker.yml

And our worker.yml is just this in the examples/playbooks:

- hosts: all
  sudo: true
    - shell: touch /tmp/ran_the_playbook

Here are the steps to test it out, we’ll be using the playbook in the repo and uploading it to the ansible master on ec2:

ansible-playbook -i example/inventory --tags main example/playbooks/create.yml
PLAY [Create AWS resources] *************************************************** 

TASK: [Create security group] ************************************************* 
changed: [localhost ->]

TASK: [create main instance] ************************************************** 
changed: [localhost ->]

... a lot more output ...

PLAY RECAP ********************************************************************              : ok=31   changed=28   unreachable=0    failed=0   
localhost                  : ok=8    changed=4    unreachable=0    failed=0   
ansible-playbook -i example/inventory --tags autoscale_group example/playbooks/create.yml
PLAY [Create autoscale group] ************************************************* 

TASK: [setup the launch config for the autoscale group for workers with the user_data scripts] *** 
changed: [localhost]

TASK: [setup the autoscaling group] ******************************************* 
changed: [localhost]

PLAY RECAP ******************************************************************** 
localhost                  : ok=2    changed=2    unreachable=0    failed=0   

Success. Of course, if you don’t have success, there are log files on the ansible master in /var/log/ansible_asg/

Now that we have a master, we can do other things, such as run ansible directly on the master. We can setup cron jobs on our workers to periodically poll for any updates in the cluster. We can do our autoscaling. And another yak has been shaved.

tl;dr - https://github.com/tjheeta/ansible_asg_master - setups up an ansible master and allows autoscaling. Examples in the repo.

  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket