charmhelpers.contrib.ansible package

Charm Helpers ansible - declare the state of your machines.

This helper enables you to declare your machine state, rather than program it procedurally (and have to test each change to your procedures). Your install hook can be as simple as:

{{{
import charmhelpers.contrib.ansible


def install():
    charmhelpers.contrib.ansible.install_ansible_support()
    charmhelpers.contrib.ansible.apply_playbook('playbooks/install.yaml')
}}}

and won’t need to change (nor will its tests) when you change the machine state.

All of your juju config and relation-data are available as template variables within your playbooks and templates. An install playbook looks something like:

{{{
---
- hosts: localhost
  user: root

  tasks:
    - name: Add private repositories.
      template:
        src: ../templates/private-repositories.list.jinja2
        dest: /etc/apt/sources.list.d/private.list

    - name: Update the cache.
      apt: update_cache=yes

    - name: Install dependencies.
      apt: pkg={{ item }}
      with_items:
        - python-mimeparse
        - python-webob
        - sunburnt

    - name: Setup groups.
      group: name={{ item.name }} gid={{ item.gid }}
      with_items:
        - { name: 'deploy_user', gid: 1800 }
        - { name: 'service_user', gid: 1500 }

  ...
}}}

Read more online about playbooks and standard ansible modules.

A further feature os the ansible hooks is to provide a light weight “action” scripting tool. This is a decorator that you apply to a function, and that function can now receive cli args, and can pass extra args to the playbook.

e.g.

@hooks.action() def some_action(amount, force=”False”):

“Usage: some-action AMOUNT [force=True]” # <– shown on error # process the arguments # do some calls # return extra-vars to be passed to ansible-playbook return {

‘amount’: int(amount), ‘type’: force,

}

You can now create a symlink to hooks.py that can be invoked like a hook, but with cli params:

# link actions/some-action to hooks/hooks.py

actions/some-action amount=10 force=true

class charmhelpers.contrib.ansible.AnsibleHooks(playbook_path, default_hooks=None)

Bases: charmhelpers.core.hookenv.Hooks

Run a playbook with the hook-name as the tag.

This helper builds on the standard hookenv.Hooks helper, but additionally runs the playbook with the hook-name specified using –tags (ie. running all the tasks tagged with the hook-name).

Example:

hooks = AnsibleHooks(playbook_path='playbooks/my_machine_state.yaml')

# All the tasks within my_machine_state.yaml tagged with 'install'
# will be run automatically after do_custom_work()
@hooks.hook()
def install():
    do_custom_work()

# For most of your hooks, you won't need to do anything other
# than run the tagged tasks for the hook:
@hooks.hook('config-changed', 'start', 'stop')
def just_use_playbook():
    pass

# As a convenience, you can avoid the above noop function by specifying
# the hooks which are handled by ansible-only and they'll be registered
# for you:
# hooks = AnsibleHooks(
#     'playbooks/my_machine_state.yaml',
#     default_hooks=['config-changed', 'start', 'stop'])

if __name__ == "__main__":
    # execute a hook based on the name the program is called by
    hooks.execute(sys.argv)
action(*action_names)

Decorator, registering them as actions

execute(args)

Execute the hook followed by the playbook using the hook as tag.

register_action(name, function)

Register a hook

charmhelpers.contrib.ansible.apply_playbook(playbook, tags=None, extra_vars=None)
charmhelpers.contrib.ansible.install_ansible_support(from_ppa=True, ppa_location='ppa:rquillo/ansible')

Installs the ansible package.

By default it is installed from the PPA linked from the ansible website or from a ppa specified by a charm config..

If from_ppa is empty, you must ensure that the package is available from a configured repository.