Migrating the python-django charm to Ansible

Simon Davy bloodearnest at gmail.com
Fri Nov 7 10:52:15 UTC 2014

On 6 November 2014 01:03, Michael Nelson <michael.nelson at canonical.com> wrote:
> Hi Patrick,
> On Thu, Nov 6, 2014 at 4:22 AM, Patrick Hetu <patrick.hetu at gmail.com> wrote:
>> The shim would do things like:
>> * Translating Juju variable to role variable
> That can be done in the playbook where needed as above.
>> * Sanitize variable like: unit_name, relation_name, etc
> That *should* be done by the existing charmhelpers (it writes out
> /etc/ansible/host_vars/localhost on each hook execution with config,
> relations and some other things like unit name, public and private
> addresses)

It does, but they're not sanitized currently. Would be a good thing to
add a sanitized version of local/remote unit names to the ansible

>> Then using tags to dispatch based on the current relation
>> to the corresponding roles.

I'm confused - this is what the ansible charmhelpers does right now?

>> Build role for re-usability
>> ---------------------------
> Yes...
>> This have the potential to solve the problem of repetition of some
>> high level tasks in other charm.
>> Like adding ppa,
> You can add PPAs with the existing apt_repository module (see the
> example there):
> http://docs.ansible.com/apt_repository_module.html

Yeah, we find 95% or so things we need to do ansible provides OOTB.

For example, and relevant to django:


We can also include roles from ansible galaxy as needed in a charm,
gaining quite a bit of reuse.

>> fetching source code, adding ssl certificate,
>> configuring backup, etc
>> A little bit like what charmhelper is doing right now.
> Yes! I think making reusable roles for common tasks in juju charms is
> really worthwhile [1]. We do have a bunch of public shareable roles
> that Simon Davy and I (mainly) are reusing and improving for some
> internal services [2]. Please take a look and see if there's things
> that could be useful - but our use-case is a bit different (for
> example, the payload role is because we are never pulling sourcecode
> branches from external repositories during deployments, instead
> pulling a built code asset from an internal swift container - although
> there would be no reason why it couldn't be extended to support both).
> Other roles may be useful (directories-and-permissions for listing
> readonly/readwrite dirs, or wsgi-app for interfacing with the gunicorn
> charm.
> A typical charm which I write for a service these days only does two
> things in addition to the re-used roles: installs any specific package
> dependencies and writes out the specific settings/config file and
> handle any other relations (elasticsearch/postgresql). I posted an
> example a while back (uses an old version of the shared roles) [3].
> Also, I know that Simon has a django shared role that he's about to
> submit to charm-ansible-roles - it may be worth a look (Simon?), but
> again, our use-case is a bit different as we're not attempting to
> write one charm to deploy any django project right now (we did try in
> the past, but found it was adding unreasonable complexity for us,
> unless the projects being deployed were very similar).

So, the django role is fairly simple, it includes tasks for syncdb,
migrate, grantuser, and collectstatic.

But it is based on using a migration "action" via juju run, as we
wanted more explicit control of when migrations are run on an update,
and on details of our specific use cases (we always have a different
db user with elevated privs for doing migrations, the run time db user
is very limited)

So it needs a bit of work before it's generally consumable outside of
our specific uses.

Regards the framework charm idea, we found that each of our django
services, while mostly similar, had different config options and
relations we wanted to expose.

We'd previously had experience with a mega-charm (the u1 charm
deployed 10 or so different services from the same codebase, it had 42
relations!), and it wasn't that fun. Having to add all possible config
options, and all possible relations was messy. Plus, then we'd have
some charms that would need to relate to themselves, so you would need
to implement both sides of the relation hook in the same charm, which
was not my idea of a good time.

So we have individual charms for each services, even if running from
the same codebase. Each charm supports only the relations and config
that it needs[1]. We utilise shared ansible roles as Michael said to
reduce the charm to pretty much the bare minimum needed for this
specific service: charm config, relations, writing the service config
to disk. Most other things are taken care of by the roles.

Another way to do this is to use a subordinate, which I think the
django charm currently supports? But limitations around subordinates
(i.e. not being able to remove relations, juju run not working,
etc[1]) has meant we didn't take this route. That, plus the shared
roles has worked well for us.



More information about the Juju mailing list