Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bootstrapping ansible prerequisites with the script module. python required?

Tags:

ansible

Goal: Given a Debian server without python installed (and a few other missing ansible prerequisites), use ansible to get them installed so I can then use the normal ansible modules (almost all of which require python) to provision the server.

According to the ansible documentation for the "script" module, "This module does not require python on the remote system, much like the raw module.". However, based on my tests, it seems like the script module does in fact attempt to run python on the remote system, at least if the sudo option is true. I believe I can get this to work with the script module as long as I don't enable ansible's sudo option, but then I need my remote user to have sudo permission without a password prompt or my script is just going to hang waiting for interactive entry of the sudo password.

So my question is: A) What's the deal with the "script" module. Does it require python on the remote system or not?

and B) Is there a better way to achieve my larger goal which is fully automated deployment without any manual steps before ansible itself can be used?

Here's my output of ansible-playbook -vvv which shows clear it is running /usr/bin/python on the remote system, and there is no file there because python is not yet installed.

TASK: [install ansible prerequisites]
*****************************************  <10.9.8.31> ESTABLISH
CONNECTION FOR USER: plyons <10.9.8.31> EXEC ['ssh', '-C', '-tt',
'-q', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s',
'-o', 'ControlPath=/Users/plyons/.ansible/cp/ansible-
ssh-%h-%p-%r', '-o', 'StrictHostKeyChecking=no', '-o',
'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications
=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o',
'PasswordAuthentication=no', '-o', 'ConnectTimeout=10',
'10.9.8.31', "/bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-
tmp-1396233547.35-182235573044157 && chmod a+rx $HOME/.ansible/tmp
/ansible-tmp-1396233547.35-182235573044157 && echo
$HOME/.ansible/tmp/ansible-tmp-1396233547.35-182235573044157'"]
<10.9.8.31> PUT
/var/folders/n4/8skjkv9s5hbc4t5r0tr0xrk80000gn/T/tmpT1Vh6e TO
/home/plyons/.ansible/tmp/ansible-
tmp-1396233547.35-182235573044157/stat <10.9.8.31> EXEC ['ssh',
'-C', '-tt', '-q', '-o', 'ControlMaster=auto', '-o',
'ControlPersist=60s', '-o', 'ControlPath=/Users/plyons/.ansible/cp
/ansible-ssh-%h-%p-%r', '-o', 'StrictHostKeyChecking=no', '-o',
'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications
=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o',
'PasswordAuthentication=no', '-o', 'ConnectTimeout=10',
'10.9.8.31', '/bin/sh -c \'sudo -k && sudo -H -S -p "[sudo via
ansible, key=hyplatqjmvybpfqtukjegkibbuyrnoqj] password: " -u root
/bin/sh -c \'"\'"\'echo SUDO-SUCCESS-
hyplatqjmvybpfqtukjegkibbuyrnoqj; /usr/bin/python
/home/plyons/.ansible/tmp/ansible-
tmp-1396233547.35-182235573044157/stat\'"\'"\'\'']

Here's my playbook task:

tasks:
  -
    name: install ansible prerequisites
    script: ansible_prereqs.sh creates=/root/.ansible_prereqs_installed

And that ansible_prereqs.sh script:

#!/bin/sh
#install ansible prereqs manually or all apt-based ansible commands will fail
# http://euphonious-intuition.com/2013/01/bootstrapping-a-cluster-with-ansible-debian-6-and-oracle-java-7/
apt-get update
apt-get install -y python python-apt python-pycurl sshpass
touch /root/.ansible_prereqs_installed
like image 502
Peter Lyons Avatar asked Mar 31 '14 03:03

Peter Lyons


2 Answers

OK, further testing leads me to understand that @DomaNitro is correct in that it's not the script module itself per-say that requires python, but the creates option in particular, because that uses a stat python script.

However, things still seem to work fine because in the initial check for the creates marker file, ansible will do: /usr/bin/python /home/plyons/.ansible/tmp/ansible-tmp-1396271950.37-134911276396535/stat, which will fail because /usr/bin/python is not present, but that's fine because we want the script to run anyway.

Once my ansible_prereqs.sh script runs, ansible's stat module will start working because /usr/bin/python is now installed, so subsequent reruns will see the marker file exists and bypass the script.

So I don't need to implement the creates logic in my shell script code. Here's my final working playbook:

---
-
  hosts: all
  gather_facts: no
  sudo: yes
  tasks:
    -
      name: install ansible prerequisites
      script: ansible_prereqs.sh creates=/root/.ansible_prereqs_installed

And here's the script it runs ansible_prereqs.sh:

#!/bin/bash
set -e
apt-get -qq update
apt-get -qq --yes install python python-apt python-pycurl sshpass
touch /root/.ansible_prereqs_installed

Here's some ansible-playbook -vvv output with explanatory comments added.

<10.9.8.31> ESTABLISH CONNECTION FOR USER: plyons

#Not sure exactly what this does, but presumably some basic
#bootstrap sanity checking
<10.9.8.31> EXEC ['ssh', '-C', '-tt',
'-q', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o',
'ControlPath=/Users/plyons/.ansible/cp/ansible-ssh-%h-%p-%r', '-o',
'StrictHostKeyChecking=no', '-o', 'KbdInteractiveAuthentication=no',
'-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-
keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o',
'ConnectTimeout=10', '10.9.8.31', "/bin/sh -c 'mkdir -p
$HOME/.ansible/tmp/ansible-tmp-1396273094.39-170062058638174 && chmod
a+rx $HOME/.ansible/tmp/ansible-tmp-1396273094.39-170062058638174 &&
echo $HOME/.ansible/tmp/ansible-tmp-1396273094.39-170062058638174'"]

#OK the "creates" option causes ansible to upload the "stat"
#python program
<10.9.8.31> PUT
/var/folders/n4/8skjkv9s5hbc4t5r0tr0xrk80000gn/T/tmp5CVz6i TO
/home/plyons/.ansible/tmp/ansible-
tmp-1396273094.39-170062058638174/stat

#Then ansible attempts to run it with /usr/bin/python
#This fails but ansible seems to proceed anyway, which is OK
<10.9.8.31> EXEC ['ssh', '-C', '-tt', '-q', '-o', 'ControlMaster=auto', '-o',
'ControlPersist=60s', '-o', 'ControlPath=/Users/plyons/.ansible/cp
/ansible-ssh-%h-%p-%r', '-o', 'StrictHostKeyChecking=no', '-o',
'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications
=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o',
'PasswordAuthentication=no', '-o', 'ConnectTimeout=10', '10.9.8.31',
'/bin/sh -c \'sudo -k && sudo -H -S -p "[sudo via ansible,
key=llljvkxiztigvqonzohgzwwekusxtprk] password: " -u root /bin/sh -c
\'"\'"\'echo SUDO-SUCCESS-llljvkxiztigvqonzohgzwwekusxtprk;
/usr/bin/python /home/plyons/.ansible/tmp/ansible-
tmp-1396273094.39-170062058638174/stat\'"\'"\'\'']

#Now ansible uploads my script
<10.9.8.31> PUT
/Users/plyons/projects/redacted/deploy/ansible_prereqs.sh
TO /home/plyons/.ansible/tmp/ansible-tmp-1396273094.39-170062058638174/ansible_prereqs.sh

#Then it marks it executable
<10.9.8.31> EXEC ['ssh', '-C',
'-tt', '-q', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s',
'-o', 'ControlPath=/Users/plyons/.ansible/cp/ansible-ssh-%h-%p-%r',
'-o', 'StrictHostKeyChecking=no', '-o',
'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications
=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o',
'PasswordAuthentication=no', '-o', 'ConnectTimeout=10', '10.9.8.31',
u'/bin/sh -c \'sudo -k && sudo -H -S -p "[sudo via ansible,
key=cgmwlvtjoxuighdqujwmmpvioiumveac] password: " -u root /bin/sh -c
\'"\'"\'echo SUDO-SUCCESS-cgmwlvtjoxuighdqujwmmpvioiumveac; chmod +rx
/home/plyons/.ansible/tmp/ansible-
tmp-1396273094.39-170062058638174/ansible_prereqs.sh\'"\'"\'\'']

#Then it runs it
<10.9.8.31> EXEC ['ssh', '-C', '-tt', '-q', '-o',
'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o',
'ControlPath=/Users/plyons/.ansible/cp/ansible-ssh-%h-%p-%r', '-o',
'StrictHostKeyChecking=no', '-o', 'KbdInteractiveAuthentication=no',
'-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-
keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o',
'ConnectTimeout=10', '10.9.8.31', u'/bin/sh -c \'sudo -k && sudo -H -S
-p "[sudo via ansible, key=cqqswbszbeabpclraxsxwzzatbolgmgf] password:
" -u root $SHELL -c \'"\'"\'echo SUDO-SUCCESS-
cqqswbszbeabpclraxsxwzzatbolgmgf; /home/plyons/.ansible/tmp/ansible-
tmp-1396273094.39-170062058638174/ansible_prereqs.sh \'"\'"\'\'']

#Then it deletes it
<10.9.8.31> EXEC ['ssh', '-C', '-tt',
'-q', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o',
'ControlPath=/Users/plyons/.ansible/cp/ansible-ssh-%h-%p-%r', '-o',
'StrictHostKeyChecking=no', '-o', 'KbdInteractiveAuthentication=no',
'-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-
keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o',
'ConnectTimeout=10', '10.9.8.31', "/bin/sh -c 'rm -rf
/home/plyons/.ansible/tmp/ansible-tmp-1396273094.39-170062058638174/
>/dev/null 2>&1'"]
like image 144
Peter Lyons Avatar answered Sep 25 '22 17:09

Peter Lyons


raw and scripts dont require python. I think the creates require python. To verify you can run

ansible -m script -a "ansible_prereqs.sh" 10.9.8.31 -vvvv

what you can do is shift the creates function to your script

#!/bin/sh
#install ansible prereqs manually or all apt-based ansible commands will fail
# http://euphonious-intuition.com/2013/01/bootstrapping-a-cluster-with-ansible-debian-6-and-oracle-java-7/
if [ ! -f /root/.ansible_prereqs_installed ]; then
        apt-get update
        apt-get install -y python python-apt python-pycurl sshpass
        touch /root/.ansible_prereqs_installed
        echo "CHANGE"
fi

And you can have your playbook something like this

tasks:
  -
    name: install ansible prerequisites
    script: ansible_prereqs.sh creates=/root/.ansible_prereqs_installed
    register: ans_preq
    changed_when: "'CHANGE' in ans_preq.stdout"

Hope that helps

like image 30
DomaNitro Avatar answered Sep 23 '22 17:09

DomaNitro