# Use pyenv for selecting the python version
         if [[ -d "/opt/pyenv" ]]; then
             # set_python_version = pyver "${python//[a-zA-Z]/}"
-            echo "---> Setting up pyenv"
+            echo "Setup pyenv:"
             export PYENV_ROOT="/opt/pyenv"
             export PATH="$PYENV_ROOT/bin:$PATH"
             pyenv versions
 
--- /dev/null
+---
+issues:
+  - |
+    Error: openstack: command not found
+fixes:
+  - |
+    Use lf-activate-venv to install openstack deps
+
+    Using python-tools-install.sh for the pre/post build is not recommended
+    approach for installing python dependencies since this installs the
+    dependencies with `--user` option (removed in I821a86ac3b54f284e8).
+
+    Instead use lf-activate-venv to setup an venv and pull in the required
+    dependencies and save the path of the virtualenv in a temp file that
+    can be checked before attempting to create a venv.
 
 
 set -eux -o pipefail
 
+# shellcheck disable=SC1090
+source ~/lf-env.sh
+
+if [ -f "/tmp/.os_lf_venv" ]; then
+    os_lf_venv=$(cat "/tmp/.os_lf_venv")
+fi
+
+if [ -d "${os_lf_venv}" ] && [ -f "${os_lf_venv}/bin/openstack" ]; then
+    echo "Re-use existing venv: ${os_lf_venv}"
+    PATH=$os_lf_venv/bin:$PATH
+else
+    lf-activate-venv --python python3 python-openstackclient
+fi
 error=false
 
 verify_images()
 
 
 # shellcheck disable=SC1090
 source ~/lf-env.sh
-lf-activate-venv --python python3.8 lftools
+lf-activate-venv --python python3 lftools
 
 # Ensure we fail the job if any steps fail
 # Disable 'globbing'
 
 # Removes openstack images older than X days in the cloud
 echo "---> Cleanup old images"
 
+# shellcheck disable=SC1090
+source ~/lf-env.sh
+
+set -x
+# Check if openstack venv was previously created
+if [ -f "/tmp/.os_lf_venv" ]; then
+    os_lf_venv=$(cat "/tmp/.os_lf_venv")
+fi
+
+if [ -d "${os_lf_venv}" ] && [ -f "${os_lf_venv}/bin/openstack" ]; then
+    echo "Re-use existing venv: ${os_lf_venv}"
+    PATH=$os_lf_venv/bin:$PATH
+else
+    lf-activate-venv --python python3 "cryptography<3.4" \
+        "lftools[openstack]" \
+        kubernetes \
+        "niet~=1.4.2" \
+        python-heatclient \
+        python-openstackclient \
+        python-magnumclient \
+        setuptools \
+        "openstacksdk<0.99" \
+        yq
+fi
+
 os_cloud="${OS_CLOUD:-vex}"
 os_image_cleanup_age="${OS_IMAGE_CLEANUP_AGE:-30}"
 
 
     return 1
 }
 
+# shellcheck disable=SC1090
+source ~/lf-env.sh
+# Check if openstack venv was previously created
+if [ -f "/tmp/.os_lf_venv" ]; then
+    os_lf_venv=$(cat "/tmp/.os_lf_venv")
+fi
+
+if [ -d "${os_lf_venv}" ] && [ -f "${os_lf_venv}/bin/openstack" ]; then
+    echo "Re-use existing venv: ${os_lf_venv}"
+    PATH=$os_lf_venv/bin:$PATH
+else
+    lf-activate-venv --python python3 \
+        kubernetes \
+        python-heatclient \
+        python-openstackclient \
+        python-magnumclient
+fi
+
 #########################
 ## FETCH ACTIVE BUILDS ##
 #########################
 
 # Scans OpenStack for orphaned ports
 echo "---> Orphaned ports"
 
+# shellcheck disable=SC1090
+source ~/lf-env.sh
+
 os_cloud="${OS_CLOUD:-vex}"
 
+# Check if openstack venv was previously created
+if [ -f "/tmp/.os_lf_venv" ]; then
+    os_lf_venv=$(cat "/tmp/.os_lf_venv")
+fi
+
+if [ -d "${os_lf_venv}" ] && [ -f "${os_lf_venv}/bin/openstack" ]; then
+    echo "Re-use existing venv: ${os_lf_venv}"
+    PATH=$os_lf_venv/bin:$PATH
+else
+    lf-activate-venv --python python3 \
+        python-heatclient \
+        python-openstackclient
+fi
+
 set -eux -o pipefail
 
 mapfile -t os_ports_ts < <(openstack --os-cloud "$os_cloud" port list \
 
     return 1
 }
 
+# shellcheck disable=SC1090
+source ~/lf-env.sh
+
+# Check if openstack venv was previously created
+if [ -f "/tmp/.os_lf_venv" ]; then
+    os_lf_venv=$(cat "/tmp/.os_lf_venv")
+fi
+
+if [ -d "${os_lf_venv}" ] && [ -f "${os_lf_venv}/bin/openstack" ]; then
+    echo "Re-use existing venv: ${os_lf_venv}"
+    PATH=$os_lf_venv/bin:$PATH
+else
+    lf-activate-venv --python python3 "cryptography<3.4" \
+        "lftools[openstack]" \
+        kubernetes \
+        "niet~=1.4.2" \
+        python-heatclient \
+        python-openstackclient \
+        python-magnumclient \
+        setuptools \
+        "openstacksdk<0.99" \
+        yq
+fi
 ##########################
 ## FETCH ACTIVE MINIONS ##
 ##########################
 
 
     return 1
 }
+
+# shellcheck disable=SC1090
+source ~/lf-env.sh
+
+# Check if openstack venv was previously created
+if [ -f "/tmp/.os_lf_venv" ]; then
+    os_lf_venv=$(cat "/tmp/.os_lf_venv")
+fi
+
+if [ -d "${os_lf_venv}" ] && [ -f "${os_lf_venv}/bin/openstack" ]; then
+    echo "Re-use existing venv: ${os_lf_venv}"
+    PATH=$os_lf_venv/bin:$PATH
+else
+    lf-activate-venv --python python3 "cryptography<3.4" \
+        "lftools[openstack]" \
+        kubernetes \
+        "niet~=1.4.2" \
+        python-heatclient \
+        python-openstackclient \
+        python-magnumclient \
+        setuptools \
+        "openstacksdk<0.99" \
+        yq
+fi
+
 set -x
 #########################
 ## FETCH ACTIVE BUILDS ##
 
 
 set -eux -o pipefail
 
+# shellcheck disable=SC1090
+source ~/lf-env.sh
+# Check if openstack venv was previously created
+if [ -f "/tmp/.os_lf_venv" ]; then
+    os_lf_venv=$(cat "/tmp/.os_lf_venv")
+fi
+
+if [ -d "${os_lf_venv}" ] && [ -f "${os_lf_venv}/bin/openstack" ]; then
+    echo "Re-use existing venv: ${os_lf_venv}"
+    PATH=$os_lf_venv/bin:$PATH
+else
+    lf-activate-venv --python python3 "cryptography<3.4" \
+        "lftools[openstack]" \
+        kubernetes \
+        "niet~=1.4.2" \
+        python-heatclient \
+        python-openstackclient \
+        python-magnumclient \
+        setuptools \
+        "openstacksdk<0.99" \
+        yq
+fi
 mapfile -t os_volumes < <(openstack --os-cloud "$os_cloud" volume list -f value -c ID --status Available)
 
 if [ ${#os_volumes[@]} -eq 0 ]; then
 
 
 set -eux -o pipefail
 
+# shellcheck disable=SC1090
+source ~/lf-env.sh
+
+# Check if openstack venv was previously created
+if [ -f "/tmp/.os_lf_venv" ]; then
+    os_lf_venv=$(cat "/tmp/.os_lf_venv")
+fi
+
+if [ -d "${os_lf_venv}" ] && [ -f "${os_lf_venv}/bin/openstack" ]; then
+    echo "Re-use existing venv: ${os_lf_venv}"
+    PATH=$os_lf_venv/bin:$PATH
+else
+    lf-activate-venv --python python3 "cryptography<3.4" \
+        "lftools[openstack]" \
+        kubernetes \
+        "niet~=1.4.2" \
+        python-heatclient \
+        python-openstackclient \
+        python-magnumclient \
+        setuptools \
+        "openstacksdk<0.99" \
+        yq
+fi
+
 os_cloud="${OS_CLOUD:-vex}"
 fixed_network="${FIXED_NETWORK}"
 fixed_subnet="${FIXED_SUBNET}"
 
 echo "---> Protect in-use images"
 os_cloud="${OS_CLOUD:-vex}"
 
+# shellcheck disable=SC1090
+source ~/lf-env.sh
+
+# Check if openstack venv was previously created
+if [ -f "/tmp/.os_lf_venv" ]; then
+    os_lf_venv=$(cat "/tmp/.os_lf_venv")
+fi
+
+if [ -d "${os_lf_venv}" ] && [ -f "${os_lf_venv}/bin/openstack" ]; then
+    echo "Re-use existing venv: ${os_lf_venv}"
+    PATH=$os_lf_venv/bin:$PATH
+else
+    lf-activate-venv --python python3 \
+        python-heatclient \
+        python-openstackclient
+fi
+
 images=()
 while read -r -d $'\n' ; do
     images+=("$REPLY")
 
     done
 }
 
+# shellcheck disable=SC1090
+source ~/lf-env.sh
+
+# Check if openstack venv was previously created
+if [ -f "/tmp/.os_lf_venv" ]; then
+    os_lf_venv=$(cat "/tmp/.os_lf_venv")
+fi
+
+if [ -d "${os_lf_venv}" ] && [ -f "${os_lf_venv}/bin/openstack" ]; then
+    echo "Re-use existing venv: ${os_lf_venv}"
+    PATH=$os_lf_venv/bin:$PATH
+else
+    lf-activate-venv --python python3 \
+        python-heatclient \
+        python-openstackclient
+fi
+
 # IP Addresses are returned as a space separated list so word splitting is ok
 # shellcheck disable=SC2207
 ip_addresses=($(openstack --os-cloud "$os_cloud" stack show -f json -c outputs "$stack_name" |
 
 
 set -eux -o pipefail
 
+# shellcheck disable=SC1090
+source ~/lf-env.sh
+
+# Check if openstack venv was previously created
+if [ -f "/tmp/.os_lf_venv" ]; then
+    os_lf_venv=$(cat "/tmp/.os_lf_venv")
+fi
+
+if [ -d "${os_lf_venv}" ] && [ -f "${os_lf_venv}/bin/openstack" ]; then
+    echo "Re-use existing venv: ${os_lf_venv}"
+    PATH=$os_lf_venv/bin:$PATH
+else
+    lf-activate-venv --python python3 "cryptography<3.4" \
+        "lftools[openstack]" \
+        kubernetes \
+        "niet~=1.4.2" \
+        python-heatclient \
+        python-openstackclient \
+        python-magnumclient \
+        setuptools \
+        "openstacksdk<0.99" \
+        yq
+fi
 openstack --os-cloud "$os_cloud" limits show --absolute
 
 pushd "$stack_template_dir" || exit 1
 
 # shellcheck disable=SC1090
 source ~/lf-env.sh
 
-lf-activate-venv lftools[openstack] python-openstackclient
+# Check if openstack venv was previously created
+if [ -f "/tmp/.os_lf_venv" ]; then
+    os_lf_venv=$(cat "/tmp/.os_lf_venv")
+fi
+
+if [ -d "${os_lf_venv}" ] && [ -f "${os_lf_venv}/bin/openstack" ]; then
+    echo "Re-use existing venv: ${os_lf_venv}"
+    PATH=$os_lf_venv/bin:$PATH
+else
+    lf-activate-venv --python python3 lftools[openstack] \
+        python-heatclient \
+        python-openstackclient
+fi
 
 echo "INFO: Retrieving stack cost for: $OS_STACK_NAME"
 if ! lftools openstack --os-cloud "$OS_CLOUD" stack cost "$OS_STACK_NAME" > stack-cost; then
 # Delete the stack even if the stack-cost script fails
 lftools openstack --os-cloud "$OS_CLOUD" stack delete "$OS_STACK_NAME" \
     | echo "INFO: $(cat)"
-
 
 if [[ -f ~/lf-env.sh ]]; then
     source ~/lf-env.sh
     lf-activate-venv --python "$python" lftools
+    # Save the virtualenv path
+    echo "$lf_venv" > "/tmp/.os_lf_venv"
 elif [[ -d /opt/pyenv ]]; then
-    echo "---> Setting up pyenv"
+    echo "Setup up pyenv"
     export PYENV_ROOT="/opt/pyenv"
     export PATH="$PYENV_ROOT/bin:$PATH"
     pyenv versions