-
-
Save gwillem/4ba393dceb55e5ae276a87300f6b8e6f to your computer and use it in GitHub Desktop.
# Add this snippet to the top of your playbook. | |
# It will install python2 if missing (but checks first so no expensive repeated apt updates) | |
# gwillem@gmail.com | |
- hosts: all | |
gather_facts: False | |
tasks: | |
- name: install python 2 | |
raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal) |
based on geromegamez answers, you can make python3 the default adding this to your hosts file (inventory):
[all:vars]
ansible_python_interpreter=/usr/bin/python3
@mabushey here's what I'm doing (we need python3 for other things)
---
- hosts: all
gather_facts: true
vars:
pre_tasks:
- name: install python
raw: bash -c "test -e /usr/bin/python || (apt -qqy update && apt install -qqy python python-pip python3 python3-pip)"
register: output
changed_when: output.stdout != ""
tasks:
This seems to work for us on ubuntu stock and cloud images from various providers
I created many Digitalocean Droplets and all of them failed when tried to run ansible playbook (even after installing python with apt-get!). Adding this script made it works. Why?
Awesome!! Thanks
Thanks!
I spun up 4x new Ubuntu 17.04 VMs and tried to do the following:
pre_tasks:
- name: Install python2 for Ansible
raw: bash -c "test -e /usr/bin/python || (apt -qqy update && apt install -qqy python-minimal)"
register: output
changed_when: output.stdout != ""
- name: Install pip
apt:
name: python-pip
state: present
fatal: [209.222.2.256]: FAILED! => {"changed": false, "failed": true, "module_stderr": "Shared connection to 209.222.2.256 closed.\r\n", "module_stdout": "Traceback (most recent call last):\r\n File \"/root/.ansible/tmp/ansible-tmp-1505758704.28-42062379270360/apt.py\", line 17, in <module>\r\n import zipfile\r\nImportError: No module named zipfile\r\n", "msg": "MODULE FAILURE", "rc": 0}
The python installation worked, but the pip installation failed, as the apt module required zipfile
. I couldn't install pip using apt-get, and it was proving a pain to get it another way, so I swapped python-minimal
in the above for python
, which has the module, and it ran fine.
Using the suggestions above doesn't seem to be affecting the changed
status for me
---
- hosts: all
gather_facts: False
become: yes
pre_tasks:
- name: Install python for Ansible
raw: bash -c "test -e /usr/bin/python || (apt -qqy update && apt install -qqy python-minimal)"
register: output
changed_when: output.stdout != ""
- name: Gathering Facts
setup:
running it repeatedly keeps producing
PLAY [all] ***************************************************************************************************************************************************
TASK [Install python for Ansible]
changed: [xx.xx.xx.xxx]
Where are people putting this? I wanted to use it in an include
in roles/common/main.yml
, so that it can be shared between playbooks, but it seems to need to be in the playbook itself.
By the way, if you're using Vagrant, you can run shell provision before ansible. Here is my Vagrant file example:
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--cpus", "1"]
vb.customize ["modifyvm", :id, "--memory", "768"]
vb.name = "novoansible"
end
# Install python for ansible
config.vm.provision "shell", inline: <<-SHELL
test -e /usr/bin/python || (apt -qqy update && apt install -qqy python-minimal)
SHELL
end
Thanks a lot 😄
@DanLipsitt you can make a role for it however you will need to diasable fact gathering for every playbook you use it in, and use the setup module afther to gather facts.
Great work all. Just on the question of notifying Ansible when a change has occurred, I found the following worked correctly for me without having to resort to string comparison.
- name: Install Python
hosts: all
gather_facts: false
tasks:
- name: Install Python 2.x
raw: test -e /usr/bin/python || (apt update && apt install -y python-simplejson)
register: test
changed_when: test.stdout
Using Ansible 2.4.2.0 (macOS) against Ubuntu 16.04.3 (running on Digital Ocean).
Anyone have a good solution for proxies? (Raw doesn't use the environment.) I can use this.
- name: Install python2 for ansible
raw: export http_proxy=http://proxy.example.com:8000/; export https_proxy=http://proxy.example.com:8000/; test -e /usr/bin/python || (apt-get -y update && apt-get install -y python-minimal)
args:
executable: /bin/bash
register: test
changed_when: test.stdout
But I'd like to make the proxies optional.
@tlc, you could almost certainly use jinja expressions in what you pass to raw:
raw: |
{% if foo %}
http_proxy={{foo}}
{% endif %}
etc....
I use the following snippet, which can work across different distributions and only expects python
to be installed, which is mostly the case with default ubuntu
boxes:
pre_tasks:
- raw: which /usr/bin/python || which /usr/bin/python3
register: py_interpreter
changed_when: py_interpreter.stdout != ""
- set_fact:
ansible_python_interpreter: "{{ py_interpreter.stdout }}"
- name: Gathering Facts
setup: #aka gather_facts
Thanks @dpetukhov
ansible -i /path/to/inventory all -m raw -a "apt -y update && apt install -y python"
I needed to install also pyton-setuptools to avoid the error
raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal python-setuptools)
I don't know if that is possible but if CentOS or RHEL comes without python, I did this:
raw: test -e /usr/bin/python || (yum -y update && yum install -y python) || (apt -y update && apt install -y python-minimal)
gather_facts: False pre_tasks: - name: Install python for Ansible raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal) changed_when: False - setup: # aka gather_facts
works for me, thanks.
Thanks, a great help
does anyone know how to install python if the target machine has no internet access? Let's say I have python package located on my control machine, is there any way to copy the python package to target machine?
FWIW, I've got an ansible role based upon this thread that works for EL/RedHat/Debian/Ubuntu/FreeBSD. I just published it to ansible- galaxy. Would love for some feedback.
does anyone know how to install python if the target machine has no internet access? Let's say I have python package located on my control machine, is there any way to copy the python package to target machine?
I hope you've found a solution by now, but if not my suggestion would be to use 'local_action' and perform an scp or sftp command.
Lil' update, on ubuntu 18.04 installing python-minimal will prompt interactively for some libssl installation, which then sits there forever. Using test -e /usr/bin/python || (apt -y update && UCF_FORCE_CONFOLD=1 DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" -qq -y install python-minimal)
fixes this behavior.
Inspired by https://bugs.launchpad.net/ubuntu/+source/ansible/+bug/1833013/comments/6
Why is the raw
command necessary for this? I've been having trouble running this lately (likely due to @mahlingam's comment above), and I found that this seems to work for me:
- hosts: all
become: true
become_user: root
become_method: sudo
gather_facts: no
pre_tasks:
- name: Install python for Ansible
apt:
update_cache: yes
name:
- python-minimal
- setup: # aka gather_facts
tasks:
...
Just wondering if there's a reason not to do this
Just wondering if there's a reason not to do this
Yep, I think it's simply that a target server without python installed, is unable to run normal ansible task steps. Using 'raw' side-steps the need for python.
PS I think bootstrapping a Python 2 installation is now likely to be unnecessary, since Ansible 2.8+ will auto-detect a suitable Python interpreter to use anyway.
https://docs.ansible.com/ansible/latest/reference_appendices/interpreter_discovery.html
If anyone is looking for a solution for Ubuntu 20.04 - change python-minimal
to python2-minimal
.
On Ubuntu 16.04,
apt install python-minimal
installs: python python-minimal python2.7 python2.7-minimalOnly installing python2.7 does not get you
/usr/bin/python
, so this does not work for Ansible.