diff --git a/defaults/main.yml b/defaults/main.yml
index 23329f3fc1d15ce42064a2a0ed558776e990445b..99f43ab113b92c6484b94a74c8b5a5f5635c7ae5 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -15,12 +15,5 @@ common_utils:
   - screen
   - unzip
   - vim
-
-# The path to the python executable to use
-# If set and the path is executable, then it will be used.
-# Else if Python 2 is executable, use it.
-# Else if Python 3 is executable, use if.
-# Else, fail.
-ansible_python_interpreter:
 ...
 # vi: set ts=2 sts=2 sw=2 et ft=yaml: 
diff --git a/tasks/bootstrap.yml b/tasks/bootstrap.yml
index dec5621612bff4485b2eff523a2601084fdbede4..fcbba72aa82f5060a1091be3a2b44d4b9919391a 100644
--- a/tasks/bootstrap.yml
+++ b/tasks/bootstrap.yml
@@ -1,65 +1,17 @@
 ---
-- name: Bootstrap the host by selecting which Python interpreter to use, and other OS specific stuff
+- name: Bootstrap the host by making sure the host is pingable and installing OS specific requirements
   tags: bootstrap
   block:
-    # If ansible_python_interpreter is set and exists, use it.
-    # Elif python 2 exists, use it.
-    # Elif python 3 exists, use it.
-    # Else, fail.
-    - name: Figure out which version of Python to use
-      when: ansible_python_interpreter is not defined or not ansible_python_interpreter
-      block:
-        - name: Check if /usr/bin/python is executable
-          raw: 'test -x /usr/bin/python'
-          changed_when: false
-          failed_when: false
-          register: python_default
-        - name: Set 'ansible_python_interpreter' to /usr/bin/python
-          when: python_default.rc is defined and python_default.rc == 0
-          set_fact:
-            ansible_python_interpreter: /usr/bin/python
-
-        - name: Check if /usr/bin/python2 is executable
-          raw: 'test -x /usr/bin/python2'
-          changed_when: false
-          failed_when: false
-          register: python_2
-        - name: Set 'ansible_python_interpreter' to /usr/bin/python2
-          when: python_2.rc is defined and python_2.rc == 0
-          set_fact:
-            ansible_python_interpreter: /usr/bin/python2
-
-        - name: Check if /usr/bin/python3 is executable
-          raw: 'test -x /usr/bin/python3'
-          changed_when: false
-          failed_when: false
-          register: python_3
-        - name: Set 'ansible_python_interpreter' to /usr/bin/python3
-          when: python_3.rc is defined and python_3.rc == 0
-          set_fact:
-            ansible_python_interpreter: /usr/bin/python3
-
-#    - debug:
-#        var: ansible_python_interpreter
-
-    - name: Check if 'ansible_python_interpreter' is executable
-      raw: 'test -x {{ ansible_python_interpreter }}'
-      changed_when: false
+    - name: Check if the host is pingable
+      ping:
+      register: _can_ping
       failed_when: false
-      register: python_executable
-    - name: Assert that 'ansible_python_interpreter' is executable
-      assert:
-        that:
-          - ansible_python_interpreter is defined and ansible_python_interpreter
-          - python_executable.rc is defined and python_executable.rc == 0
 
-#    - name: Install Python
-#      raw: >
-#        (test -e /etc/redhat-release && yum install -y python)
-#        || (test -e /etc/debian_version && apt-get -y update && apt-get install -y python)
-#      when: result.rc is defined and result.rc == 1
+    - name: If the host is not pingable, find out why
+      include_tasks: tasks/diagnose-unpingable.yml
+      when: _can_ping.ping is not defined or _can_ping.ping != 'pong'
 
-    - name: Gather facts to determine host OS
+    - name: Gather minimal facts to determine host OS
       setup:
         gather_subset: min
 
@@ -74,7 +26,8 @@
             - vars/{{ ansible_os_family | lower }}.yml
           skip: true
 
-    - include_tasks: '{{ item }}'
+    - name: Include OS specific bootstrap tasks
+      include_tasks: '{{ item }}'
       with_first_found:
         - tasks/bootstrap_{{ ansible_distribution | lower }}-{{ ansible_distribution_version | lower }}.yml
         - tasks/bootstrap_{{ ansible_distribution | lower }}-{{ ansible_distribution_release | lower }}.yml
diff --git a/tasks/diagnose-unpingable.yml b/tasks/diagnose-unpingable.yml
new file mode 100644
index 0000000000000000000000000000000000000000..960854b25004e53e1801196b0332196fd1410156
--- /dev/null
+++ b/tasks/diagnose-unpingable.yml
@@ -0,0 +1,32 @@
+#
+# This task list attempts to diagnose why a host is not pingable with Ansible's
+# built-in ping module. It is currently able to diagnose issues with Python
+# being unavailable, or Python being an unsupported version.
+#
+---
+# If the error has a defined error message and is not related to Python not
+# being found, then display that message
+- fail:
+    msg: '{{ _can_ping.msg }}'
+  when: _can_ping.msg is defined and (_can_ping.rc is not defined or _can_ping.rc != 127)
+
+# If the error is related to Python not being found, then try to find the
+# available Python interpreters
+- name: Python is not found
+  when: _can_ping.rc is defined and _can_ping.rc == 127
+  block:
+    - include_tasks: tasks/find-python-executable.yml
+    - fail:
+        msg: "Unable to find Python on {{ inventory_hostname }}.\n
+              Please set 'ansible_python_interpreter' to an executable Python interpreter.\n
+              The host has these available: ( {{ _python_interpreters | join(' , ') }} )"
+
+# This block is a catchall that runs whenever an unanticipated error occurs
+- name: Something Unexpected Happened
+  block:
+    - debug:
+        var: _can_ping
+    - fail:
+        msg: Something Unexpected Happened
+...
+# vi: set ts=2 sts=2 sw=2 et ft=yaml:
diff --git a/tasks/find-python-executable.yml b/tasks/find-python-executable.yml
new file mode 100644
index 0000000000000000000000000000000000000000..08b84f3e693f0af12feb83a1c579623ca533a2f0
--- /dev/null
+++ b/tasks/find-python-executable.yml
@@ -0,0 +1,21 @@
+#
+# This task list atempts to find all the available Python interpreters on a host
+# and build a list of them in a variable called '_python_interpreters'.
+#
+---
+- block:
+    # Initialize an empty list of available interpreters
+    - set_fact:
+        _python_interpreters: []
+
+    # Loop through the common interpreter paths, testing if they are available
+    - name: Find a usable Python interpreter
+      include_tasks: tasks/test-python-executable.yml
+      loop_control:
+        loop_var: _python_path
+      with_items:
+        - /usr/bin/python
+        - /usr/bin/python2
+        - /usr/bin/python3
+...
+# vi: set ts=2 sts=2 sw=2 et ft=yaml:
diff --git a/tasks/test-python-executable.yml b/tasks/test-python-executable.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2a219d550ff058f04607c3430fbe663807c38d85
--- /dev/null
+++ b/tasks/test-python-executable.yml
@@ -0,0 +1,22 @@
+#
+# This task list tests is a python interpreter path is executable, and appends
+# it to a list of executable paths if it is. Ansible has version requirements
+# for Python interpreters, but this task list doesn't check for those.
+#
+# Parameters:
+#   _python_path          An absolute path to a Python interpreter.
+#   _python_interpreters  A list to append executable paths to.
+#
+---
+- name: Check if '{{ _python_path }}' is executable
+  raw: 'test -x {{ _python_path }}'
+  changed_when: false
+  failed_when: false
+  register: __can_exec
+
+- name: If '{{ _python_path }}' is executable, append it to the list of available interpreters
+  set_fact:
+    _python_interpreters: "{{ _python_interpreters }} + [ '{{ _python_path }}' ]"
+  when: __can_exec.rc is defined and __can_exec.rc == 0
+...
+# vi: set ts=2 sts=2 sw=2 et ft=yaml: