Something-driven development

Software development thoughts around Ubuntu, Python, Golang and other tools

Reusable ansible roles for Juju charms

with 3 comments

I’ve been writing Juju charms to automate the deployment of a few different services at work, which all happen to be wsgi applications… some Django apps, others with other frameworks. I’ve been using the ansible support for writing charms which makes charm authoring simpler, but even then, essentially each wsgi service charm needs to do the same thing:

  1. Setup specific users
  2. Install the built code into a specific location
  3. Install any package dependencies
  4. Relate to a backend (could be postgresql, could be elasticsearch)
  5. Render the settings
  6. Setup a wsgi (gunicorn) service (via a subordinate charm)
  7. Setup log rotation
  8. Support updating to a new codebase without upgrading the charm
  9. Support rolling updates a new codebase

Only three of the above really change slightly from service to service: which package dependencies are required, the rendering of the settings and the backend relation (which usually just causes the settings to be rerendered anyway).

After trying (and failing) to create a nice reusable wsgi-app charm, I’ve switched to utilise ansible’s built-in support for reusable roles and created a charm-bootstrap-wsgi repo on github, which demonstrates all of the above out of the box (the README has an example rolling upgrade). The charm’s playbook is very simple, just reusing the wsgi-app role:

 

roles:
    - role: wsgi-app
      listen_port: 8080
      wsgi_application: example_wsgi:application
      code_archive: "{{ build_label }}/example-wsgi-app.tar.bzip2"
      when: build_label != ''

 

and only needs to do two things itself:

tasks:
    - name: Install any required packages for your app.
      apt: pkg={{ item }} state=latest update_cache=yes
      with_items:
        - python-django
        - python-django-celery
      tags:
        - install
        - upgrade-charm

    - name: Write any custom configuration files
      debug: msg="You'd write any custom config files here, then notify the 'Restart wsgi' handler."
      tags:
        - config-changed
        # Also any backend relation-changed hooks for databases etc.
      notify:
        - Restart wsgi

 

Everything else is provided by the reusable wsgi-app role. For the moment I’ve got the source of the reusable roles in a separate github repo, but I’d like to get these into the charm-helpers project itself eventually. Of course there will be cases where the service charm may need to do quite a bit more custom functionality, but if we can encapsulate and reuse as much as possible, it’s a win for all of us.

If you’re interested in chatting about easier charms with ansible (or any issues you can see), we’ll be getting together for a hangout tomorrow (Jun 11, 2014 at 1400UTC).

Written by Michael

June 10, 2014 at 6:22 pm

Posted in ansible, juju, python

3 Responses

Subscribe to comments with RSS.

  1. I really like this approach and I find the tagging ansible tasks with the juju hooks makes it so much easier for people to write charms in a workflow they are probably more familiar with (re puppet, chef, ansible)

    adamstokes2013

    August 8, 2014 at 11:50 am

    • Thanks Adam. Yeah – I certainly find it much easier to put charms together and re-use existing (well-defined) roles. Another benefit is the output in the logs – the ansible output clearly shows which tasks were run, and which weren’t applied because they weren’t necessary.

      There are some things that need working out though still… for example, currently it’s difficult to (unit)test your playbook tasks… I’d like to have the reusable roles unit-tested.

      Michael

      August 8, 2014 at 1:29 pm

      • Sounds good man, I’m currently using this workflow on a charm I’m writing so I’ll let you know if I run into any workflow changes.

        adamstokes2013

        August 10, 2014 at 5:42 am


Leave a comment