Beliebte Suchanfragen
//

Migrate from Puppet to Ansible

17.12.2014 | 3 minutes of reading time

In a previous post , I wrote about combining Ansible and Puppet, with Ansible as remote executor for arbitrary commands. In this post I take a look at how to migrate from Puppet to Ansible.

Combine the Execution of Ansible and Puppet

If you want to migrate from Puppet to Ansible, an all or nothing approach is hard to implement. It has all the disadvantages which apply to any Big Bang migration.
The other option is to migrate Puppet modules one by one to Ansible and remove them from Puppet. During the migration you would have to call both tools to provision a server. That is not very effective and error prone. So what can you do?
You can execute Puppet from within an Ansible playbook. This way you always execute both tools and will not miss any role or module.

But you cannot just call Puppet from Ansible, as Ansible expects a return code of 0 when everything works as expected. Puppet will return a code of 2 when it changed something, which is totally fine. However, Ansible interprets this as a failure and stops executing any other steps on this server. So you need to make Ansible accept 0 as well as 2 as successful return codes:

1- name: Start puppet agent
2    sudo: yes
3    shell: /usr/bin/puppet agent  --test --verbose
4    register: puppet_agent_result
5    changed_when: puppet_agent_result.rc == 2
6    failed_when: puppet_agent_result.rc != 2 and puppet_agent_result.rc != 0

This way Puppet fits into Ansibles way of handling things.

Finegrained Integration of Puppet into Ansible

If you would like to take a more fine grained approach, you could use Puppet tags to execute Ansible tasks between two different Puppet agent calls:

1- name: Start puppet agent for system module
2    sudo: yes
3    shell: /usr/bin/puppet agent -t -v --tags=system
4    register: puppet_agent_result
5    changed_when: puppet_agent_result.rc == 2
6    failed_when: puppet_agent_result.rc != 2 and puppet_agent_result.rc != 0
7
8  - name: Do something with Ansible
9    debug: msg=”something”
10
11  - name: Start puppet agent for apache module
12    sudo: yes
13    shell: /usr/bin/puppet agent -t -v --tags=apache
14    register: puppet_agent_result
15    changed_when: puppet_agent_result.rc == 2
16    failed_when: puppet_agent_result.rc != 2 and puppet_agent_result.rc != 0

Execution output

An important detail to consider when calling Puppet from Ansible is Puppet’s execution output. Even though Ansible now knows how to interpret Puppet’s return codes, Ansible only tells you that something changed, but not what changes were made:

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 
11PLAY RECAP ******************************************************************** 
12server01.example.com      : ok=2    changed=1    unreachable=0    failed=0

If you want to see Puppet’s output, when something changed or went wrong, you can use the debug task:

1- debug: var=puppet_agent_result.stdout_lines
2    when: puppet_agent_result.rc != 0
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

The Puppet output does not look very nice, but it is better than having nothing at all. To make it a bit more readable, perhaps such an Ansible callback plugin might help. But this will be the topic of another post.

This post shows how to execute Puppet from inside Ansible Playbooks. I hope this post gives you a starting point on how to migrate your own Puppet installation to Ansible. As always, do not hesitate to contact me when you have any questions.

share post

//

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.