diff --git a/playbooks/roles/create-venv/tasks/main.yaml b/playbooks/roles/create-venv/tasks/main.yaml
index 85350a248b..2fa84f6392 100644
--- a/playbooks/roles/create-venv/tasks/main.yaml
+++ b/playbooks/roles/create-venv/tasks/main.yaml
@@ -2,36 +2,53 @@
   assert:
     that: create_venv_path is defined
 
+- name: Ensure venv dir
+  file:
+    path: '{{ create_venv_path }}'
+    state: directory
+
 # Xenial's default pip will try to pull in packages that
 # aren't compatible with 3.5.  Cap them
-- name: Setup bionic era venv
+- name: Setup requirements for bionic
   when: ansible_distribution_version is version('16.04', '==')
-  pip:
-    name:
+  set_fact:
+    _venv_requirements:
       - pip<21
       - setuptools<51
-    state: latest
-    virtualenv: '{{ create_venv_path }}'
-    virtualenv_command: '/usr/bin/python3 -m venv'
 
 # Bionic's default pip will try to pull in packages that
 # aren't compatible with 3.6.  Cap them
-- name: Setup bionic era venv
+- name: Setup requirements for Bionic
   when: ansible_distribution_version is version('18.04', '==')
-  pip:
-    name:
+  set_fact:
+    _venv_requirements:
       - pip<22
       - setuptools<60
-    state: latest
-    virtualenv: '{{ create_venv_path }}'
-    virtualenv_command: '/usr/bin/python3 -m venv'
 
-- name: Setup later era venv
+- name: Setup requirements for later era
   when: ansible_distribution_version is version('20.04', '>=')
-  pip:
-    name:
+  set_fact:
+    _venv_requirements:
       - pip
       - setuptools
-    state: latest
+
+# This is used to timestamp the requirements-venv.txt file.  This
+# means we will run --upgrade on the venv once a day, but otherwise
+# leave it alone.
+- name: Get current day
+  shell: 'date +%Y-%m-%d'
+  register: _date
+
+- name: Write requirements
+  template:
+    src: requirements-venv.txt
+    dest: '{{ create_venv_path }}/requirements-venv.txt'
+  register: _venv_requirements_txt
+
+- name: Create or upgrade venv
+  when: _venv_requirements_txt.changed
+  pip:
+    requirements: '{{ create_venv_path }}/requirements-venv.txt'
+    extra_args: '--upgrade'
     virtualenv: '{{ create_venv_path }}'
     virtualenv_command: '/usr/bin/python3 -m venv'
diff --git a/playbooks/roles/create-venv/templates/requirements-venv.txt b/playbooks/roles/create-venv/templates/requirements-venv.txt
new file mode 100644
index 0000000000..ebc968a12e
--- /dev/null
+++ b/playbooks/roles/create-venv/templates/requirements-venv.txt
@@ -0,0 +1,4 @@
+# Update timestamp: {{ _date.stdout }}
+{% for r in _venv_requirements %}
+{{ r }}
+{% endfor %}