Q: Executing ansible playbook AttributeError: 'str' object has no attribute 'set_playbook_basedir' Hello, 
I have a two part question.
First Part:
I'm trying to execute a playbook from a python script that downloads a playbook and executes it. I know the playbook works because i've tested it. However, when i try to execute the playbook with python code I get a no attribute error 'set_playbook_basedir' not quite sure where this is coming from. Here is the full error output.
[ec2-user@ip-172-30-199-190 scripts]$ sudo python /var/lib/cloud/instance/scripts/part-001
/usr/lib64/python2.7/dist-packages/Crypto/Util/number.py:57: PowmInsecureWarning: Not using mpz_powm_sec.  You should rebuild using libgmp >= 5 to avoid timing attack vulnerability.
  _warn("Not using mpz_powm_sec.  You should rebuild using libgmp >= 5 to avoid timing attack vulnerability.", PowmInsecureWarning)
/bin/bash: line 0: export: `=': not a valid identifier
/bin/bash: line 0: export: `3': not a valid identifier
~/vision_provis/storm.yml
Traceback (most recent call last):
  File "/var/lib/cloud/instance/scripts/part-001", line 71, in <module>
    fatal: destination path 'vision_provis' already exists and is not an empty directory.
check=True)
  File "/usr/local/lib/python2.7/site-packages/ansible/playbook/__init__.py", line 169, in __init__
    self.inventory.set_playbook_basedir(self.basedir)
AttributeError: 'str' object has no attribute 'set_playbook_basedir'


#!/usr/bin/python
import ansible.runner
from ansible.playbook import PlayBook
from ansible import inventory
from ansible import callbacks
import json
import subprocess
import os
from ansible import utils
import time

def shell_command_execute(cmd):
    try:
        subprocess.Popen(['/bin/bash', '-c', cmd])
    except:
        print 'There seems to be an error'
repo = "https://github.com/zukeru/vision_provis.git"
playbook = "storm.yml"


echo_bash_profile = "export CLOUD_ENVIRONMENT=integration|export CLOUD_MONITOR_BUCKET=0|export CLOUD_APP=ES-test-storm-deploy-DEV--_yV_cyE-|export CLOUD_STACK=infra|export CLOUD_CLUSTER=0|export CLOUD_AUTO_SCALE_GROUP=0|export CLOUD_LAUNCH_CONFIG=0|export EC2_REGION=us-west-2|export CLOUD_DEV_PHASE=0|export CLOUD_REVISION=0|export CLOUD_DOMAIN=0|export SG_GROUP=ES-test-storm-deploy-DEV--qtv6a_Uj"

for commands in echo_bash_profile.split('|'):
    command_to_send = 'echo "' + commands + '" >> /home/ec2-user/.bash_profile'
    shell_command_execute(commands)
    shell_command_execute(command_to_send)

var_user_data = "export SHARDS = 3"

for commands in var_user_data.split('|'):
    echo_bash_profile_passed = 'echo "' + commands  + '" >> /home/ec2-user/.bash_profile'
    shell_command_execute(commands)
    shell_command_execute(echo_bash_profile_passed)

command_remove = 'rm -rf /home/ec2-user/'+repo
shell_command_execute(command_remove)

command = 'cd /home/ec2-user/; git clone ' + repo
shell_command_execute(command)

folder = repo.split('/')[4].replace('.git','')
full_path = '/home/ec2-user/' + folder + '/' + playbook

time.sleep(6)

# setting callbacks
stats = callbacks.AggregateStats()
playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY)
runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY)

print full_path
# creating the playbook instance to run, based on "test.yml" file
pb = PlayBook(playbook = full_path,
                               stats = stats,
                               callbacks = playbook_cb,
                               runner_callbacks = runner_cb,
                               inventory = "localhost",
                               check=True)
# running the playbook
pr = pb.run()

# print the summary of results for each host
#print json.dumps(pr, sort_keys=True, indent=4, separators=(',', ': '))

The Second Problem is:
This script is actually being passed as base64 encoded aws user-data and its executing but it doesn't seem to recognize that it is python. Here is the cloud-init-output.log
Complete!
Cloud-init v. 0.7.6 running 'modules:final' at Wed, 29 Jul 2015 00:17:16 +0000. Up 103.79 seconds.
/var/lib/cloud/instance/scripts/part-001: line 3: import: command not found
/var/lib/cloud/instance/scripts/part-001: line 4: import: command not found
/var/lib/cloud/instance/scripts/part-001: line 5: import: command not found
/var/lib/cloud/instance/scripts/part-001: line 6: import: command not found
/var/lib/cloud/instance/scripts/part-001: line 7: import: command not found
/var/lib/cloud/instance/scripts/part-001: line 8: import: command not found
/var/lib/cloud/instance/scripts/part-001: line 10: syntax error near unexpected token `('
/var/lib/cloud/instance/scripts/part-001: line 10: `def shell_command_execute(cmd):'
Jul 29 00:17:16 cloud-init[1958]: util.py[WARNING]: Failed running /var/lib/cloud/instance/scripts/part-001 [2]
Jul 29 00:17:16 cloud-init[1958]: cc_scripts_user.py[WARNING]: Failed to run module scripts-user (scripts in /var/lib/cloud/instance/scripts)
Jul 29 00:17:16 cloud-init[1958]: util.py[WARNING]: Running module scripts-user (<module 'cloudinit.config.cc_scripts_user' from '/usr/lib/python2.7/dist-packages/cloudinit/config/cc_scripts_user.pyc'>) failed
Jul 29 00:17:16 cloud-init[1958]: templater.py[WARNING]: Cheetah not available as the default renderer for unknown template, reverting to the basic renderer.
Cloud-init v. 0.7.6 finished at Wed, 29 Jul 2015 00:17:16 +0000. Datasource DataSourceEc2.  Up 103.97 seconds


A: I can't reproduce your issues, but my best guess is that:
1) You need to initialize your playbook with an Inventory object instead of a string: 
from ansible.inventory import Inventory
pb = PlayBook(playbook = full_path,
              stats = stats,
              callbacks = playbook_cb,
              runner_callbacks = runner_cb,
              inventory = Inventory(["localhost"]),
              check=True)

2) Your python script needs to be prefixed with an indication to bash that it should be executed by python. Just put the following shebang at the top of your python script: 
#! /usr/bin/env python

Alternatively, you may run your script with:
python /var/lib/cloud/instance/scripts/part-001

instead of just: 
/var/lib/cloud/instance/scripts/part-001

