In a previous post , I wrote about executing Puppet from within an Ansible playbook. But the output did not look very nice. In this post I take a closer look at how to change that.
Just as a reminder, the output of Puppet looks like this, when called from inside Ansible:
1ansible-playbook -s -i /etc/ansible/puppet_hosts -l "server01*" puppet-ansible-test.yaml 2 3PLAY [Test Puppet agent execution via ansible] ******************************** 4 5GATHERING FACTS *************************************************************** 6ok: [server01.example.com] 7 8TASK: [Puppet run] ************************************************************ 9changed: [server01.example.com] 10 11TASK: [debug var=puppet_agent_result.stdout_lines] **************************** 12ok: [server01.example.com] => { 13 "puppet_agent_result.stdout_lines": [ 14 "\u001b[0;32mInfo: Retrieving plugin\u001b[0m", 15 "\u001b[0;32mInfo: Caching catalog for server01.example.com\u001b[0m", 16 "\u001b[0;32mInfo: Applying configuration version '1414749704'\u001b[0m", 17 "\u001b[mNotice: /Stage[main]//Node[server01.example.com]/File[/tmp/ansible-test]/content: ", 18 "--- /tmp/ansible-test\t2014-10-31 11:03:09.792572953 +0100", 19 "+++ /tmp/puppet-file20141031-19593-alc2zo-0\t2014-10-31 11:11:44.243616162 +0100", 20 "@@ -1 +1 @@", 21 "-Jst a test", 22 "+Just a test", 23 "\\ No newline at end of file", 24 "\u001b[0m", 25 "\u001b[0;32mInfo: FileBucket adding {md5}280ef2f78e2399bbefb3b2a487b79281\u001b[0m", 26 "\u001b[0;32mInfo: /Stage[main]//Node[server01.example.com]/File[/tmp/ansible-test]: Filebucketed /tmp/ansible-test to puppet with sum 280ef2f78e2399bbefb3b2a487b79281\u001b[0m", 27 "\u001b[mNotice: /Stage[main]//Node[server01.example.com]/File[/tmp/ansible-test]/content: content changed '{md5}280ef2f78e2399bbefb3b2a487b79281' to '{md5}9543518919cb69d012934d9a78fb50b3'\u001b[0m", 28 "\u001b[mNotice: Finished catalog run in 0.20 seconds\u001b[0m" 29 ] 30} 31 32PLAY RECAP ******************************************************************** 33server01.example.com : ok=3 changed=1 unreachable=0 failed=0
Ansible offers callback plugins. And according to this gist you can use them to change Ansible’s output. So, does this also work for the Puppet output?
As stated in the docs of Ansible, the parameter callback_plugins in ansible.cfg
tells Ansible where to find the plugins. On my system it is /usr/share/ansible_plugins/callback_plugins
. So I create human_log.py
in this directory. Calling Ansible, shows it does not work completely. It is not working for the debug task:
1ansible-playbook -s -i /etc/ansible/puppet_hosts -l "server01*" puppet-ansible-test.yaml 2 3PLAY [all] ******************************************************************** 4 5GATHERING FACTS *************************************************************** 6ok: [server01.example.com] 7 8TASK: [Puppet run] ************************************************************ 9changed: [server01.example.com] 10 11cmd: 12/usr/bin/puppet agent --test --verbose 13 14start: 152014-12-12 14:00:56.459456 16 17end: 182014-12-12 14:01:02.815022 19 20delta: 210:00:06.355566 22 23stdout: 24Info: Retrieving plugin 25Info: Loading facts in /var/lib/puppet/lib/facter/service_env.rb 26Info: Loading facts in /var/lib/puppet/lib/facter/puppet_vardir.rb 27Info: Loading facts in /var/lib/puppet/lib/facter/service.rb 28Info: Loading facts in /var/lib/puppet/lib/facter/facter_dot_d.rb 29Info: Loading facts in /var/lib/puppet/lib/facter/root_home.rb 30Info: Loading facts in /var/lib/puppet/lib/facter/pe_version.rb 31Info: Caching catalog for server01.example.com 32Info: Applying configuration version '1418388530' 33Notice: /Stage[main]//Node[server01.example.com]/File[/tmp/test]/ensure: defined content as '{md5}0bf60adb1435639a42b490e7e80d25c7' 34Notice: Finished catalog run in 0.19 seconds 35 36stderr: 37 38 39TASK: [debug var=puppet_agent_result] ***************************************** 40ok: [server01.example.com] => { 41 "puppet_agent_result": { 42 "changed": true, 43 "cmd": "/usr/bin/puppet agent --test --verbose", 44 "delta": "0:00:06.355566", 45 "end": "2014-12-12 14:01:02.815022", 46 "failed": false, 47 "failed_when_result": false, 48 "invocation": { 49 "module_args": "/usr/bin/puppet agent --test --verbose", 50 "module_name": "shell" 51 }, 52 "rc": 2, 53 "start": "2014-12-12 14:00:56.459456", 54 "stderr": "", 55 "stdout": "\u001b[0;32mInfo: Retrieving plugin\u001b[0m\n\u001b[0;32mInfo: Loading facts in /var/lib/puppet/lib/facter/service_env.rb\u001b[0m\n\u001b[0;32mInfo: Loading facts in /var/lib/puppet/lib/facter/puppet_vardir.rb\u001b[0m\n\u001b[0;32mInfo: Loading facts in /var/lib/puppet/lib/facter/service.rb\u001b[0m\n\u001b[0;32mInfo: Loading facts in /var/lib/puppet/lib/facter/facter_dot_d.rb\u001b[0m\n\u001b[0;32mInfo: Loading facts in /var/lib/puppet/lib/facter/root_home.rb\u001b[0m\n\u001b[0;32mInfo: Loading facts in /var/lib/puppet/lib/facter/pe_version.rb\u001b[0m\n\u001b[0;32mInfo: Caching catalog for server01.example.com\u001b[0m\n\u001b[0;32mInfo: Applying configuration version '1418388530'\u001b[0m\n\u001b[mNotice: /Stage[main]//Node[server01.example.com]/File[/tmp/test]/ensure: defined content as '{md5}0bf60adb1435639a42b490e7e80d25c7'\u001b[0m\n\u001b[mNotice: Finished catalog run in 0.19 seconds\u001b[0m", 56 "stdout_lines": [ 57 "\u001b[0;32mInfo: Retrieving plugin\u001b[0m", 58 "\u001b[0;32mInfo: Loading facts in /var/lib/puppet/lib/facter/service_env.rb\u001b[0m", 59 "\u001b[0;32mInfo: Loading facts in /var/lib/puppet/lib/facter/puppet_vardir.rb\u001b[0m", 60 "\u001b[0;32mInfo: Loading facts in /var/lib/puppet/lib/facter/service.rb\u001b[0m", 61 "\u001b[0;32mInfo: Loading facts in /var/lib/puppet/lib/facter/facter_dot_d.rb\u001b[0m", 62 "\u001b[0;32mInfo: Loading facts in /var/lib/puppet/lib/facter/root_home.rb\u001b[0m", 63 "\u001b[0;32mInfo: Loading facts in /var/lib/puppet/lib/facter/pe_version.rb\u001b[0m", 64 "\u001b[0;32mInfo: Caching catalog for server01.example.com\u001b[0m", 65 "\u001b[0;32mInfo: Applying configuration version '1418388530'\u001b[0m", 66 "\u001b[mNotice: /Stage[main]//Node[server01.example.com]/File[/tmp/test]/ensure: defined content as '{md5}0bf60adb1435639a42b490e7e80d25c7'\u001b[0m", 67 "\u001b[mNotice: Finished catalog run in 0.19 seconds\u001b[0m" 68 ], 69 "warnings": [] 70 } 71} 72 73PLAY RECAP ******************************************************************** 74server01.example.com : ok=3 changed=1 unreachable=0 failed=0
But do we really need the debug task? It is just a workaround to get the Puppet output when something changed or failed. With the new Ansible plugin it seems possible to realize this without the debug tasks.
Currently the plugin changes the output only for runner_on_ok
and runner_on_failed
. But we need it to only log for runner_on_changed
. I could not find a reference Ansible implements this inside callbacks, instead Ansible hides it inside the res
object. As shown in this gist , the status in runner_on_ok
can be ok or changed.
Let us change the human_log.py to just print the output when something changed:
def runner_on_ok(self, host, res):
if res.pop('changed', False):
human_log(res)
else:
pass
This little change fixes the output and makes it even possible to remove the Ansible debug task. The output now looks like this when something changed:
1ansible-playbook -s -i /etc/ansible/puppet_hosts -l "server01*" puppet-ansible-test.yaml 2 3PLAY [all] ******************************************************************** 4 5GATHERING FACTS *************************************************************** 6ok: [server01.example.com] 7 8TASK: [Puppet run] ************************************************************ 9changed: [server01.example.com] 10 11stdout: 12Info: Retrieving plugin 13Info: Loading facts in /var/lib/puppet/lib/facter/service_env.rb 14Info: Loading facts in /var/lib/puppet/lib/facter/puppet_vardir.rb 15Info: Loading facts in /var/lib/puppet/lib/facter/service.rb 16Info: Loading facts in /var/lib/puppet/lib/facter/facter_dot_d.rb 17Info: Loading facts in /var/lib/puppet/lib/facter/root_home.rb 18Info: Loading facts in /var/lib/puppet/lib/facter/pe_version.rb 19Info: Caching catalog for server01.example.com 20Info: Applying configuration version '1418390818' 21Notice: /Stage[main]//Node[server01.example.com]/File[/tmp/test]/content: 22--- /tmp/test 2014-12-12 14:31:31.073989661 +0100 23+++ /tmp/puppet-file20141212-14315-f1o4yt-0 2014-12-12 14:32:14.069988080 +0100 24@@ -1 +1 @@ 25-ust a test 26+Just a test 27\ No newline at end of file 28 29Info: FileBucket got a duplicate file {md5}6836618568499b53b0c33675e31e0474 30Info: /Stage[main]//Node[server01.example.com]/File[/tmp/test]: Filebucketed /tmp/test to puppet with sum 6836618568499b53b0c33675e31e0474 31Notice: /Stage[main]//Node[server01.example.com]/File[/tmp/test]/content: content changed '{md5}6836618568499b53b0c33675e31e0474' to '{md5}0bf60adb1435639a42b490e7e80d25c7' 32Notice: Finished catalog run in 0.23 seconds 33 34PLAY RECAP ******************************************************************** 35server01.example.com : ok=2 changed=0 unreachable=0 failed=0
As you can see, the plugin also removes the unicode signes, which makes it even more readable. And this is the output when everything passes:
1ansible-playbook -s -i /etc/ansible/puppet_hosts -l "server01*" puppet-ansible-test.yaml 2 3PLAY [all] ******************************************************************** 4 5GATHERING FACTS *************************************************************** 6ok: [server01.example.com] 7 8TASK: [Puppet run] ************************************************************ 9ok: [server01.example.com] 10 11PLAY RECAP ******************************************************************** 12server01.example.com : ok=2 changed=0 unreachable=0 failed=0
This Ansible callback plugin is the solution to our logging problem. With this callback plugin, we can change the Puppet output and also shorten our playbook. When you got question about this topic, do not hesitate to contact me or leave a comment.
More articles
fromChristian Zunker
Your job at codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog author
Christian Zunker
Do you still have questions? Just send me a message.
Do you still have questions? Just send me a message.