Search code examples
ansibleansible-inventory

Reusing a playbook inside another even if the main playbook fails


I have a playbook which is working fine.

cat  playbooks/logs.yml

---

- hosts: "{{ target }}"
  gather_facts: no
  vars:
    ansible_ssh_user: "{{ user }}"
    ansible_ssh_pass: "{{ password }}"

  tasks:
    - name: Obtain time
      setup:
        filter: "ansible_date_time"
      delegate_to: localhost

    - name: Define archive name
      ansible.builtin.set_fact:
        archive_name: "logs-{{ target }}-{{ ansible_date_time.iso8601_basic_short }}"

    - name: Archive log file
      community.general.archive:
        path: /tmp/*my_files*
        dest: "/tmp/{{ archive_name }}.tar.xz"
        format: xz

    - name: Copy file to remote server
      ansible.builtin.shell: sshpass -p "{{ ansible_ssh_pass }}" scp /tmp/{{ archive_name }}.tar.xz {{ ansible_ssh_user }}@RemoteServer:/www/logs

This playbook is archiving files (/tmp/my_files) in target server and than it's copying the archived file to my remote server (RemoteServer).

I want to reuse this playbook in a different playbook (run-app.yml). Basically I want to run my first playbook (run-app.yml) and, at the end, even if the role run-app fails, I want to run playbook logs.yml.

cat run-app.yml
---
- hosts: "{{ target }}"
  gather_facts: no
  vars:
    ansible_ssh_user: "{{ user }}"
    ansible_ssh_pass: "{{ password }}"

  roles:
   - download-zip-files
   - run-app

I thought using blocks could do the work but to be honest I am not sure. Can you point me in the right direction?

I tried blocks but it's not working:

cat run-app.yml
    ---
    - hosts: "{{ target }}"
      gather_facts: no
      vars:
        ansible_ssh_user: "{{ user }}"
        ansible_ssh_pass: "{{ password }}"
    
      roles:
       - download-zip-files
       

     tasks:
       - name: test
         block:
           - ansible.builtin.include_role:
               name: run-app
         always:
           - include: logs.yml

Now I got this error:

The error appears to be in '.../logs.yml': line 5, column 3, but may be elsewhere in the file depending on the exact syntax problem.

  • hosts: "{{ target }}"

    ^ here We could be wrong, but this one looks like it might be an issue with missing quotes. Always quote template expression brackets when they start a value.

Although the playbook logs.yml is working I guess something is wrong when I am calling it like this.

ANy ideas? Maybe some other approach


Solution

  • You cannot include another playbook that way. You can include a tasks file that way. However, it doesn't know what to do with "- hosts: " at all, because that is a playbook element.

    Depending on the failure nature of the first playbook, you could do this.

    ---
    - hosts: "{{ target }}"
      gather_facts: no
      vars:
        ansible_ssh_user: "{{ user }}"
        ansible_ssh_pass: "{{ password }}"
    
      roles:
        - download-zip-files
       
    
      tasks:
        - block:
          - name: test
            ansible.builtin.include_role:
              name: run-app
          rescue:
            - meta: clear_host_errors
    
    - import_playbook: logs.yml
    

    See the examples from ansible.builtin.import_playbook

    That being said, if the host ends up getting ended in the course of the beginning parts, it gets taken out completely unless you do something like meta: clear_host_errors on it. That requires a rescue section. I added that into my example after considering it.