I'm pretty new to Ansible, but it seemed a better tool than a bash script for installing programs from source on remote servers...

Starting from my working-but-fragile bash script, I made an Ansible script to git clone, configure and compile what I need. However some of these sources are large, so I wanted to include the --depth 1 parameter. This is a problem because the CentOS 7 version of git is 1.8.3 and Ansible ignores the depth command if it can't use at least git 1.9.1. Obviously for non-system use, I wouldn't mind having the latest git 2.15 anyway so...

To make a newer version of git available than is on yum's base/extras/updates repos, I found the IUS repository which has a "safe replacement" package for a few things including git. Helpfully there's an Ansible task set to install their repo. Here's the relevant task:

- name: install IUS release package
       name: "https://{{ ius_distribution_abbrev }}{{ ansible_distribution_major_version }}.iuscommunity.org/ius-release.rpm"
       state: present
   when: ansible_os_family == 'RedHat'

Ansible however fails this task:

fatal: [MY_REMOTE_IP_ADDRESS]: FAILED! => {"changed": false, "failed": true,
"msg": "Failed to validate the SSL certificate for centos7.iuscommunity.org:443. 
Make sure your managed systems have a valid CA certificate installed. 
You can use validate_certs=False if you do not need to confirm the servers
identity but this is unsafe and not recommended. Paths checked for this 
platform: /etc/ssl/certs, /etc/pki/ca-trust/extracted/pem, 
/etc/pki/tls/certs, /usr/share/ca-certificates/cacert.org, /etc/ansible. 
The exception msg was: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:579)."}

Both yum's ca-certificates and python-urllib3 packages are installed and on the latest version from the yum repos.

Per this comment on github, it seems that Ansible can't handle SNI to get the right SSL certificate without python 2.7.9+. But CentOS 7 ships with python 2.7.5. You can't upgrade it because get_url has the same issue with SSL and so you would have to download the python source with validate_certs=no.

Worse, even when I did that, used make altinstall to put python 2.7.14 in /usr/local/bin/ without touching the OS python and then set ansible_python_interpreter: /usr/local/bin/python2.7, (at least allowing get_url to work) I'm then locked out of yum for the duration of the playbook because yum can't handle the newer version of python Ansible is trying to run it with.

  • Is there a way to make this all work together properly without removing a security feature?
  • Is Ansible the wrong tool for CentOS 7 because of the python version and yum?
  • Update: ansible_python_interpreter can be changed to the system python and back immediately before/after yum module tasks to avoid the inability to call yum when using updated Python versions for other Ansible modules. – TheAtomicOption Dec 27 '17 at 18:47

While it's true that the version of python reported there doesn't have SNI support, I thought that RedHat backported it. But anyways, if not, you can do that yourself:

yum -y install gcc python-devel libffi-devel openssl-devel
pip install pyopenssl ndg-httpsclient pyasn1

(This works for requests at least, I'm not sure about Ansible.)

On a broader note:

But CentOS 7 ships with python 2.7.5. You can't upgrade it because get_url has the same issue with SSL and so you would have to download the python source with validate_certs=no.

That's only the case if the server you're downloading Python from relies on SNI. I imagine most of their mirrors do not.

But really, you shouldn't be compiling Python on every individual server. You should do it once, either on a machine that you freeze into an image that you launch further machines off of, or you package it as an rpm and the machines just download that and install it. This allows you to control the download process.

Even simpler: download the package on your desktop (via verified https). Copy it to your file storage. Download from there onto your servers. There's no need to download directly from python.org every time, and it's more reliable to have a local copy anyways.


I suggest that you do not reinvent the wheel and use a ansible galaxy role that has already solved the issues you are reporting.

One could use Geerlingguys git role to install the latest git on CentOS7. It is possible to install this by issuing ansible-galaxy install geerlingguy.git and subsequently include geerlingguy.git in the roles in order to apply the role on the nodes.

  • 2
    Looking at the tasks in your link, it uses get_url to retrieve the git source which means while it may be a work around for git specifically, (if that repository doesn't use SNI to get a certificate), it doesn't answer my question of how to work securely with Ansible more generally, without breaking yum. Your answer is good advice though, and I'll be trying this today. – TheAtomicOption Nov 27 '17 at 17:14

Failure to validate SSL certificate seems to be happening widely across Linux distributions. Therefore I will post a solution (general idea) which worked for me. The surface problem seems to be that Python is not able to recognize the certificate bundle file. Meanwhile, commandline curl can recognize SSL certificate and download file. The path to the certificate bundle differs depending on your Linux distribution.

In my case,

Ansible version: 2.10, Debian distribution

after certificate was added by

- name: Add the intermediate certificate to certificate bundle
  command: update-ca-certificates

Then, specify the SSL_CERT_FILE variable to the certificate bundle.

- name: download a file
    url: "url"
    dest: "destination"
  environment:                                           # Explicitly specify SSL_CERT_FILE here.
    SSL_CERT_FILE: /etc/ssl/certs/ca-certificates.crt     

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.