Migrating the python-django charm to Ansible

Patrick Hetu patrick.hetu at gmail.com
Fri Nov 7 20:33:00 UTC 2014

​> Specifically, this is not the config.yaml you're talking about, but
> the config file which is passed during deployment right? As in,
> "myconfig.yaml" in:
> juju deploy --config myconfig.yaml mycharm

yes, that's what I meant.

>> [1] Using a configuration file without that charm name at the top
>> was working in the past but now doesn't. Maybe this could be
>> re-enable without to much negative impact.

>That might be worth a juju bug.

Done: https://bugs.launchpad.net/juju-core/+bug/1390525

> Let me know about the shims!

Yes, sorry, I forgot to mention the main problem that shim is trying to
The major reason for shims is because Ansible can't redefined an
existing variable at runtime. Ansible evaluate the yaml as a jinja2 template
first and then run it.

So a shim is an assignement trick to get the right values in the playbook.

For example, I want to use to be able to customize the django_settings
in the charm configuration but set it to the basename of the working_dir in
case it not set:

- name: set settings_module if django_settings != ''
  set_fact: shim_settings_module="{{ django_settings }}"
  when: django_settings != ''

- name: set settings_module if django_settings == ''
  set_fact: shim_settings_module="{{ shim_working_dir | basename
  when: django_settings == ''

I've tried, the default() filter, set_fact module and with_first_found
They are all great tools for simulating simple if.
But redefining a variable will fail silently or trigger an infinite loop.

You can check it out with this snippet:

- hosts: localhost
    a: "abc"
    - debug: msg={{ a }}
    - set_fact: a="b"
    - debug: msg={{ a }}

Then running it with -e to see the problem:

  ansible-playbook redefine.yml -i local -e "a=xyz"

> [2] https://github.com/absoludity/charm-ansible-roles

I've checked those roles and wanted to contribute to it but I got blocked.

I found that tagging the tasks with Juju's hook names make it difficult to
produce a reusable role.
Because you will have to set a tag to all your tasks in the role
and always be running untagged task.
This also make the charm specific to Juju.

I've chose to use tags only in the playbook and not in roles.
I use it in the python-django charm like that:

- role: wsgi-app
    - wsgi-relation-joined
    - wsgi-relation-changed
    - website-relation-joined
    - website-relation-changed
  wsgi_user: "{{ django_uid }}"
  wsgi_group: "{{ django_gid }}"
  working_dir: "{{ shim_working_dir }}"
  python_path: "{{ shim_python_path_list }}"
  app_label: "{{ sanitized_unit_name }}"
  wsgi_application: wsgi
  working_dir: "{{ shim_working_dir }}"
  settings_module: "{{ shim_settings_module }}"

And for task specific to a role, I filter in the roles with a when:

- name: Open port
  when: relations['website']

- name: Reload wsgi
  when: relations['wsgi']

or a better way could be to include base on relations in the playbook like

- include: wsgi_apps/tasks/relations/wsgi.yml
  when: relations['wsgi']

This is far from perfect but I can't see other way to keep the role
flexible but not specific to Juju.

>> 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

I have open a bug about that:


> 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.

Yes that seems to be the way to go. So people would to build a custom
django charm
by adding only pieces that they want in there playbook.

> 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).

I think the python-django charm would be there only to show all the
possible features
available by the reusable roles and people would be encorage to build a
charm per site.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ubuntu.com/archives/juju/attachments/20141107/90ba357e/attachment.html>

More information about the Juju mailing list