How to get ansible inventory file when tasks are run on localhost

Hi, I have a python script, that parses host file given on command line like this:

ansible-playbook -i hosts main.yml 

and in python script I used

from ansible.inventory.manager import InventoryManager
from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager

dl = DataLoader()
im = InventoryManager(loader=dl, sources=['{{ inventory_file }}'])

The problem is using localhost makes inventory_file undefined. And python script does not need to be run on remote server, I hope it could run on local server.
I verified above by command:

 ansible localhost -m debug -a "msg={{inventory_file}}"

And that inverntory_file is undefined, while given any other host group, it prints correct inventory file path, like this:

ansible -i hosts cseg -m debug -a "msg={{inventory_file}}"

So my question is, in order to get python script work on local machine, how can Python script get inventory_file given on command line:

ansible-playbook -i hosts main.yml 

(main.yml has a task run python script on local machine.)

Does having a ansible.cfg with the inventory file path in it help?

For example:

[defaults]
inventory = hosts
1 Like

You have a couple of options here. One is to add localhost to your inventory and set the ansible_connection for that host as “local”. You don’t have to add the host to a group. Another option is to run your command as such:

 ansible-playbook -i localhost, main.yml

Notice there is a comma right after the word localhost.

2 Likes

Hi, thank you for your help. This is what I did after reading your post:
For option 1, I added group local with one machine localhost or 127.0.0.1 in host file:

[local]
localhost

ansible-playbook result in an error “can not connect”. I think I may not understand option 1 in your post.
for option 2, ansible-playbook -i hosts main.yml, python script needs inventory file on command line, and it is run locally, specified in role host as localhost.

Ansible defaults to ssh connection mode for every host you target in your play, including localhost. You have to instruct it to use another mode (here local) to not use ssh; that’s what @binbashroot was referring to.

See: Connection plugins — Ansible Documentation and Controlling where tasks run: delegation and local actions — Ansible Documentation

Edit: To clarify, second option they proposed is about tricking Ansible to target an host not present in inventory. Sort of passing an inline inventory. Though it doesn’t change the connection mode, so you’d still have to mention it somewhere.

1 Like

I use a YAML inventory works for this, in ansible.cfg:

[defaults]
inventory = hosts.yml

And in hosts.yml:

---
all:
  children:
    localhosts:
      hosts:
        localhost:
          ansible_connection: local
...
2 Likes