Ansible version : 2.0.0.1
I've been looking around quite a bit now, and most documentation I find is either incomplete or deprecated (this post is for version 1.8.4, ie)
I'm trying to launch an Ansible playbook through the Python API. Ansible's documentation seem to be showing how to generate and play tasks, but not how to load and run a playbook yml file. I've been digging into the code to try to understand how to launch it, and I think I've done some progress, but I'm really hitting a wall. Here's what I have so far :
def createcluster(region, environment, cluster):
Options = namedtuple('Options', ['region','env', 'cluster'])
# initialize needed objects
variable_manager = VariableManager()
loader = DataLoader()
options = Options(region=region, env=environment, cluster=cluster)
options.listhosts = False
vault_password = getpass.getpass('Enter vault password :')
passwords = dict(vault_pass=vault_password)
#Getting hosts
hostsread = open('provisioning/inventory/hosts','r')
hosts = hostsread.read()
inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=hosts)
variable_manager.set_inventory(inventory)
#Create and load the playbook file
playbook = Playbook(loader)
playbook.load('provisioning/cluster.yml', variable_manager,loader)
#Create an executor to launch the playbook ?
executor = None
executor = PlaybookExecutor(playbook,inventory,variable_manager,loader,options,passwords)
try:
result = executor.run()
finally:
if executor is not None:
executor.cleanup()
I'm not sure at all about the executor part, and I keep getting a "AttributeError: 'Options' object has no attribute 'listhosts'" error when I try to launch the code (weirdly enough as it should just ignore its absence, I think (line 60))
How am I supposed to load a YML file and launch it through the Python API ? Am I on the good path or did I lose myself ? Why isn't Ansible better documented ? Why would 42 be the answer to 7*7 ?
Disclaimer
Posting for completion.
I had trouble setting verbosity for ansible 2.4. I will mainly talk about that.
TL;DR
Ansible use a global
Display
object in the__main__
file (the one you launch) if it doesn't exist some imports will create it.This is considered a bad practice and not PEP8 compliant (second bullet point)
Explanation part
versions: (I am using python virtualenv)
How is it used inside ansible
It is called in almost every file (108). Like so you have a new display in your entry point and then all other module will retrieve this first declared display.
Running with another verbosity
You just have to declare a Display object like so:
You can alternatively use this after:
display.verbosity = 1000
Problem
I wanted to be able to completely remove ansible output (negative value = no output)
Solving
I ended up creating a new class like so:
Then import it in my
__main__
fileAnd only after import all other modules
Example
Notes
listhosts=True, listtasks=False, listtags=False, syntax=False
import __main__
makes debugging impractical because when using debugger (in my case pudb), the__main__
file is the debugger file hencefrom __main__ import display
will never workhth
[Edit1]: added note
Here is an example with Ansible 2:
Tested with Python 2.7.10 and ansible 2.0.1.0
I wrote this without seeing you want version 2. Leaving it, though it isn't the correct answer.
This will work in 1.9. You can modify your createcluster() command to call it.