How to run Ansible without specifying the inventory but the host directly?

PythonAnsible

Python Problem Overview


I want to run Ansible in Python without specifying the inventory file through (ANSIBLE_HOST) but just by:

ansible.run.Runner(
  module_name='ping',
  host='www.google.com'
)

I can actually do this in fabric easily but just wonder how to do this in Python. On the other hand, documentation of the Ansible API for python is not really complete.

Python Solutions


Solution 1 - Python

Surprisingly, the trick is to append a ,

# Host and IP address
ansible all -i example.com,
ansible all -i 93.184.216.119,

or

# Requires 'hosts: all' in your playbook
ansible-playbook -i example.com, playbook.yml

The host parameter preceding the , can be either a hostname or an IPv4/v6 address.

Solution 2 - Python

I know this question is really old but think that this little trick might helpful for future users who need help for this:

ansible-playbook -i 10.254.3.133, site.yml

if you run for local host:

ansible-playbook -i localhost, --connection=local site.yml

The trick is that after ip address/dns name, put the comma inside the quotes and requires 'hosts: all' in your playbook.

Hope this will help.

Solution 3 - Python

In my case, I did not want to have hosts: all in my playbook, because it would be bad if someone ran the playbook and forgot to include -i 10.254.3.133,

This was my solution (ansible 2.6):

$ ansible-playbook myplaybook.yml -e "{target: 10.1.1.1}" -i 10.1.1.1, ...

And then, in the playbook:

- hosts: "{{ target }}"
  remote_user: donn
  vars_files:
    - myvars
  roles:
    - myrole

This is a special use-case when I need to provision a host and I don't want/need to add it to the inventory.

Solution 4 - Python

You can do this with:

hosts = ["webserver1","webserver2"]

webInventory = ansible.inventory.Inventory(hosts)

webPing = ansible.runner.Runner(
    pattern='webserver*',
    module_name='ping',
    inventory = webInventory
).run()

Whatever is in hosts becomes your inventory and you can search it with pattern (or do "all").

Solution 5 - Python

I also needed to drive the Ansible Python API, and would rather pass hosts as arguments rather than keep an inventory. I used a temporary file to get around Ansible's requirement, which may be helpful to others:

from tempfile import NamedTemporaryFile

from ansible.inventory import Inventory
from ansible.runner import Runner

def load_temporary_inventory(content):
    tmpfile = NamedTemporaryFile()
    try:
        tmpfile.write(content)
        tmpfile.seek(0)
        inventory = Inventory(tmpfile.name)
    finally:
        tmpfile.close()
    return inventory

def ping(hostname):
    inventory = load_temporary_inventory(hostname)
    runner = Runner(
        module_name='ping',
        inventory=inventory,
    )
    return runner.run()

Solution 6 - Python

A very simple solution as per my understanding, apologize if it's a distraction.

Here are 3 main steps needs to be there,

  1. command-line options
  2. What needs to be exposed in the playbook.yml
  3. What it says

1.command-line options

ansible-playbook -l "host-name"

Please note that host-name is $hostname of the node

2.What needs to be exposed inside the playbook.yml

- hosts: webservers
  tasks:
    - debug:
        msg: "{{ ansible_ssh_host }}"
      when: inventory_hostname in groups['webservers']

3.What it says? Have a look :)

TASK [debug] ***********************************************************************************************************************************************************
Thursday 10 December 2020  13:01:07 +0530 (0:00:03.153)       0:00:03.363 *****
ok: [node1] => {
    "msg": "192.168.1.186"
}

This is how we can execute tasks on specific nodes using the --limit or -l option

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNgoc TranView Question on Stackoverflow
Solution 1 - PythontrkochView Answer on Stackoverflow
Solution 2 - PythonArbab NazarView Answer on Stackoverflow
Solution 3 - PythonDonn LeeView Answer on Stackoverflow
Solution 4 - PythonseumasmacView Answer on Stackoverflow
Solution 5 - PythonbillkwView Answer on Stackoverflow
Solution 6 - PythonMahadevView Answer on Stackoverflow