web-dev-qa-db-fra.com

Comment exécuter Ansible sans spécifier l'inventaire mais directement l'hôte?

Je veux exécuter Ansible en Python sans spécifier le fichier d'inventaire via (ANSIBLE_Host) mais simplement en:

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

En réalité, je peux le faire facilement en tissu, mais je me demande simplement comment faire cela en Python. D'autre part, la documentation de l'API Ansible pour python n'est pas vraiment complète.

59
Ngoc Tran

Étonnamment, l’astuce consiste à ajouter un ,

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

ou

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

Le paramètre Host précédant le , peut être un nom d'hôte ou une adresse IPv4/v6.

132
trkoch

Je sais que cette question est vraiment ancienne, mais je pense que ce petit truc pourrait être utile aux futurs utilisateurs qui ont besoin d'aide pour cela:

ansible-playbook -i 10.254.3.133, site.yml

si vous courez pour l'hôte local:

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

Le truc, c'est qu'après l'adresse IP/le nom du DNS, placez la virgule à l'intérieur des guillemets et exige «hosts: all» dans votre classeur.

J'espère que cela aidera. 

29
Arbab Nazar

Vous pouvez le faire avec:

hosts = ["webserver1","webserver2"]

webInventory = ansible.inventory.Inventory(hosts)

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

Ce qui est dans les hôtes devient votre inventaire et vous pouvez le rechercher avec un motif (ou faire "tout").

6
seumasmac

Je devais également piloter le Ansible Python API , et préférerais passer les hôtes sous forme d'arguments plutôt que de conserver un inventaire. J'ai utilisé un fichier temporaire pour contourner les exigences d'Ansible, ce qui peut être utile aux autres:

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()
1
billwanjohi

Dans mon cas, je ne voulais pas avoir hosts: all dans mon livre de jeu, car il serait mauvais que quelqu'un le gère et oublie d'inclure -i 10.254.3.133,

C'était ma solution (ansible 2.6):

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

Et puis, dans le livre de jeu:

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

Il s'agit d'un cas d'utilisation spécial lorsque je dois provisionner un hôte et que je ne veux pas/n'ai pas besoin de l'ajouter à l'inventaire.

0
Donn Lee

Ce n'est pas une réponse complète, mais il existe une discussion sur ce sujet dans ce fil de discussion . À la fin du premier article de ce fil de discussion, il est suggéré de créer un script wrapper bash pour ansible-playbook, ce qui est un peu un bidouillage, mais qui fonctionne.

J'ai également envisagé l'utilisation de «ansible-pull» et la création d'un plugin d'inventaire ansible. Je suis également intéressé à trouver la réponse à cette question et je continuerai à l'actualiser à mesure que je trouverai plus d'informations.

0
bnsmith

Il ne semble pas y avoir de moyen direct de donner un motif. C'est mon bidouillage pour le résoudre.

echo fldn[3789:3799].mysite.com >test; ansible all -i test -m ping
0
Abhijith