Hi,
So what I want to do, and have not yet found a way todo yet, is to run a handler if a taks fails rather then if it succeeds.
For example I want to do a yum install mysql on a server, but this server does not have python-simplejson and/or other packages that is neccesary for Ansible.
How do I then trigger a “fix” and then preferably rerun the failed task. Is this possible?
Something similar to:
- hosts: mysql
user: admin
vars:
passwd: VeryHardPasswd
user: analytics
tasks:
- name: create user Analytics
mysql_user: name={{ user }}
password={{ passwd }}
priv=.:SELECT,‘SHOW DATABASES’
state=present
login_user=ROOT
login_password=PASSWORD
register: mysql_result
ignore_errors: True
notify_on_fail: install mysqldb-python
handlers:
- name: Install mysqldb-python
raw: sudo yum install -y MySQL-python
In this specific case you'd just assert the python-simplejson package
exists right?
If it's already installed then nothing happens, and you'll be able to
skip on to the
other tasks.
If of course you're in a catch-22 situation (can't run ansible to set
up ansible pre-requisites),
then you'll need to seed your base image with what's required.
For example, my kickstarts bring up a machine with
* SSHd enabled and tcp/22 inbound permitted on the local firewall
* an 'ansible' account with a pre-defined list of SSH keys in its
authorised_keys file
* passwordless sudo configured for that account
Everything else is managed by Ansible.
This general approach also applies to CM with puppet, chef, etc.
(which typically
have much more requirements).
To be honest, I would also be interested in a solution to this.
Of course all the machines, that I install myself (preseed, kickstart, ...) meet the requirements for ansible.
For already existing machines which should be managed by us, the requirements are somewhere in the middle of met or unmet.
To my knowledge python-simplejson (required on Python 2.4 boxes) can only be installed using the raw module and not with the apt or yum module.
Therefore this is a task which I'd not like to be executed on every run.
Maybe the first task in the list could be an ansible ping and if it fails do some brute-force raw commands.
....
And as writing this I answered my question
My prototype looks like this:
- hosts: all
user: root
tasks:
- name: ping
ping:
register: result
- name: conditional task
raw: here_your_command
when: result|failed
Cheers
Christian
Hmm -
I have fixed it with a when statement and then notify a handler that in turns install and notifies yet another handler.
Thou this solution does not look nice and I would really like to not relay on any other managementsystem other then Ansible.
My sollution to problem looks like this atm:
handlers:
…
The above one works kinda but is not the best looking.
Preffered would be similar to:
- name: something
register: something
notify_when: something|failed
- simplejson
handlers:
- name: simplejson
raw: “yum -y install python-simplejson”
Does anyone know if something like this might be implemented in the near future or if anyone can point me to where I can suggest a “patch”
You are definitely overcomplicating it.
There’s no reason to need the register really.
- shell: yum -y install python-simplejson
Yum naturally is smart enough to not do anything if the package is already installed, so it takes care of the “idempotence” (I kinda still hate the over-complexity of that word, but it’s a word) for you.
As we have to manage a mixed environment, we do have different packagemanagers.
So I often use when clauses like this
when: ansible_pkg_mgr == "apt"
I really like facts to be available in my playbooks.
So my goal is/was to avoid running raw yum commands against a debian or apt against Red Hat in our global site playbook.
A other thing I want to avoid is having a complicated documentation about which playbook to run against a server.
I am dreaming of a one-size-fits-all playbook
Will the shell module work if the install of python-simplejson is required?
At least for the install of python (Minimal debian does not have it) I need to go for raw.
- shell: yum install python-simplejson
ignore_errors: true
changed_when: False
ugly but should work
This is also a bit weird looking, but you could abuse the "removes"
parameter to the shell command, which does not run a command when a binary
does not exist.
The downside is this makes your playbook look weirder.
- shell: yum install python-simplejson removes=/usr/bin/yum
referenced here: http://docs.ansible.com/shell_module.html
Generally this is done to prevent running installers a second time, and
will not remove the indicated file.
Another solution is usually to have the kickstart or base image slightly
prepped in the case of those older OSes, but we definitely don't require it.