1

I am trying execute the following playbook using python script.

playbook = dict(
        name = "Enable Site",
        hosts = [host],
        gather_facts = 'no',
        tasks = [
            dict(action=dict(
                module='find', args=dict(paths="/etc/apache2/sites-enabled")), register='files_found'),
            dict(action=dict(
                module='shell', args="cd /etc/apache2/sites-enabled && a2dissite *"), register='shell_out', when='files_found.matched > 0'),
            dict(action=dict(module='shell', args="a2ensite " + site_name), register='shell_out'),
            dict(action=dict(module='service', args="name='apache2' state='reloaded'"), register='shell_out'),
        ]
    )

This playbook basically checks if any apache site is enabled if yes then it disables them by removing all the files from /etc/apache2/sites-enabled.

The second task is supposed to be executed when the directory /etc/apache2/sites-enabled is empty. But the "when" the condition is always evaluated to be true. Even if I write when="False". Also tried when="eval(False)"

Amarjit Singh
  • 2,068
  • 19
  • 52

2 Answers2

0

If I convert your playbook dictionary to a regular Ansible playbook, like this:

- name: Enable Site
  hosts:
    - localhost
  gather_facts: no
  tasks:
    - action:
        module: find
        args:
          paths: /etc/apache2/sites-enabled
      register: files_found
    - action:
        module: shell
        args: cd /etc/apache2/sites-enabled && a2dissite *
      register: shell_out
      when: files_found.matched > 0
    - action:
        module: shell
        args: a2ensite 100-mysite.conf
      register: shell_out
    - action:
        module: service
        args: name='apache2' state='reloaded'
      register: shell_out

It seems to run as intended. That is, if I start with an empty /etc/apache2/sites-enabled directory, I see:

PLAY [Enable Site] *******************************************************************

TASK [find] **************************************************************************
ok: [localhost]

TASK [shell] *************************************************************************
skipping: [localhost]

TASK [shell] *************************************************************************
changed: [localhost]

You can see it's skipping the second shell task there. However, think about what your playbook does:

  • It checks if the directory is empty
  • If it's not, it disabled everything
  • It install a file into the directory

That means every time you run this playbook, it's going to empty out /etc/apache2/sites-enabled, and then re-enable the site named in your site_name variable.

larsks
  • 277,717
  • 41
  • 399
  • 399
  • Yeah, it works with the regular playbook. But the question is how to write python playbook using python dictionary. Cause I am using python to execute Ansible playbooks. I am following this code https://docs.ansible.com/ansible/latest/dev_guide/developing_api.html – Amarjit Singh Jan 27 '20 at 12:49
0

this question is rather old but you can find how ansible interprets the playbook but using the api you tried to use: per instance:

#!/usr/bin/python

import json
from ansible import context
from ansible import constants as C
from ansible.playbook import Playbook
from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager

loader=DataLoader()
variable_manager = VariableManager(loader=loader)


pb = Playbook.load('pb.yml', variable_manager=variable_manager, loader=loader)
print(json.dumps(pb._loader.__dict__['_FILE_CACHE']['/usr/ansible/pb.yml'][0], indent=2))

this will output the playbook in json format. then you can use it with the python api or with ansible-runner.

note the API is bound to change without notice so this may not work in future versions. . tested with ansible 2.9 on RHEL7.

danidar
  • 179
  • 2
  • 10