web-dev-qa-db-fra.com

Exécuter ansible-playbook en utilisant Python

Comment puis-je exécuter un playbook dans le script python? Quel est l'équivalent de ce qui suit en utilisant le module ansible en python:

ansible -i hosts dbservers -m setup
ansible-playbook -i hosts -vvvv -k site.yml

Je regardais leur documentation dans http://docs.ansible.com/developing_api.html mais ils ont des exemples très limités.

27
helloworld2013

Avis de dépréciation: ce message ne fonctionne pas depuis ansible 2. L'API a été modifiée.

Ceci est couvert dans la documentation Ansible sous "API Python".

Par exemple, ansible -i hosts dbservers -m setup Est implémenté via:

import ansible.runner

runner = ansible.runner.Runner(
   module_name='setup',
   module_args='',
   pattern='dbservers',
)
dbservers_get_facts = runner.run()

Il y a un tas de paramètres non documentés dans la méthode __init__ De Runner (de ansible.runner). Il y a trop nombreux pour être listés en ligne , mais j'ai inclus certains des paramètres dans ce post pour deviner ce que vous recherchez spécifiquement.

class Runner(object):
    ''' core API interface to ansible '''

    # see bin/ansible for how this is used...

    def __init__(self,
        Host_list=C.DEFAULT_Host_LIST,      # ex: /etc/ansible/hosts, legacy usage
        module_path=None,                   # ex: /usr/share/ansible
        module_name=C.DEFAULT_MODULE_NAME,  # ex: copy
        module_args=C.DEFAULT_MODULE_ARGS,  # ex: "src=/tmp/a dest=/tmp/b"
        ...
        pattern=C.DEFAULT_PATTERN,          # which hosts?  ex: 'all', 'acme.example.org'
        remote_user=C.DEFAULT_REMOTE_USER,  # ex: 'username'
        remote_pass=C.DEFAULT_REMOTE_PASS,  # ex: 'password123' or None if using key
        remote_port=None,                   # if SSH on different ports
        private_key_file=C.DEFAULT_PRIVATE_KEY_FILE, # if not using keys/passwords
        Sudo_pass=C.DEFAULT_Sudo_PASS,      # ex: 'password123' or None
        ...
        Sudo=False,                         # whether to run Sudo or not
        Sudo_user=C.DEFAULT_Sudo_USER,      # ex: 'root'
        module_vars=None,                   # a playbooks internals thing
        play_vars=None,                     #
        play_file_vars=None,                #
        role_vars=None,                     #
        role_params=None,                   #
        default_vars=None,                  #
        extra_vars=None,                    # extra vars specified with he playbook(s)
        is_playbook=False,                  # running from playbook or not?
        inventory=None,                     # reference to Inventory object
        ...
        su=False,                           # Are we running our command via su?
        su_user=None,                       # User to su to when running command, ex: 'root'
        su_pass=C.DEFAULT_SU_PASS,
        vault_pass=None,
        ...
        ):

Par exemple, la commande ci-dessus qui spécifie un utilisateur Sudo et passe serait:

runner = ansible.runner.Runner(
   module_name='setup',
   module_args='',
   pattern='dbservers',
   remote_user='some_user'
   remote_pass='some_pass_or_python_expression_that_returns_a_string'
)

Pour les playbooks, regardez dans playbook.PlayBook , qui prend un ensemble similaire d'initialiseurs:

class PlayBook(object):
    '''
    runs an ansible playbook, given as a datastructure or YAML filename.
    ...
    '''

    # *****************************************************

    def __init__(self,
        playbook         = None,
        Host_list        = C.DEFAULT_Host_LIST,
        module_path      = None,
        .... 

et peut être exécuté avec la méthode .run(). par exemple.:

from ansible.playbook import PlayBook
pb = PlayBook(playbook='/path/to/book.yml, --other initializers--)
pb.run()

une utilisation plus robuste peut être trouvée dans le fichier ansible-playbook .

Pour autant que je sache, la traduction des playbooks en Python est un peu plus compliquée, mais la documentation listée ci-dessus devrait vous couvrir et vous pouvez réutiliser l'analyseur YAML intégré à Ansible pour convertir les playbooks en variables .

37
user559633

J'ai répondu à la question ici Publier ceci ici car les liens de publication sont découragés dans la communauté. J'espère que ça aide.

La documentation manque étonnamment et vous devrez commencer ici

Cela étant dit, voici un script rapide que j'ai piraté ensemble qui parvient à exécuter un playbook.

#!/usr/bin/env python

import os
import sys
from collections import namedtuple

from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import Inventory
from ansible.executor.playbook_executor import PlaybookExecutor

loader = DataLoader()

inventory = Inventory(loader=loader, sources='/home/slotlocker/hosts2')
variable_manager = VariableManager(loader=loader, inventory=inventory)
playbook_path = '/home/slotlocker/ls.yml'

if not os.path.exists(playbook_path):
    print '[INFO] The playbook does not exist'
    sys.exit()

Options = namedtuple('Options', ['listtags', 'listtasks', 'listhosts', 'syntax', 'connection','module_path', 'forks', 'remote_user', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user', 'verbosity', 'check','diff'])
options = Options(listtags=False, listtasks=False, listhosts=False, syntax=False, connection='ssh', module_path=None, forks=100, remote_user='slotlocker', private_key_file=None, ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=True, become_method='Sudo', become_user='root', verbosity=None, check=False, diff=False)

variable_manager.extra_vars = {'hosts': 'mywebserver'} # This can accomodate various other command line arguments.`

passwords = {}

pbex = PlaybookExecutor(playbooks=[playbook_path], inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords)

results = pbex.run()
11
Phani Kumar

Juste une mise à jour de code rapide qui fonctionne sur 2.8.3,

from ansible import context
from ansible.cli import CLI
from ansible.module_utils.common.collections import ImmutableDict
from ansible.executor.playbook_executor import PlaybookExecutor
from ansible.parsing.dataloader import DataLoader
from ansible.inventory.manager import InventoryManager
from ansible.vars.manager import VariableManager

loader = DataLoader()

context.CLIARGS = ImmutableDict(tags={}, listtags=False, listtasks=False, listhosts=False, syntax=False, connection='ssh',
                    module_path=None, forks=100, remote_user='xxx', private_key_file=None,
                    ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=True,
                    become_method='Sudo', become_user='root', verbosity=True, check=False, start_at_task=None)

inventory = InventoryManager(loader=loader, sources=('/xxx/inventory_file',))

variable_manager = VariableManager(loader=loader, inventory=inventory, version_info=CLI.version_info(gitinfo=False))

pbex = PlaybookExecutor(playbooks=['/xxx/playbook.yml'], inventory=inventory, variable_manager=variable_manager, loader=loader, passwords={})

results = pbex.run()
0
vigilander