diff --git a/ansible/group_vars/all/openstack b/ansible/group_vars/all/openstack
index f40c3bbad..85c69aae5 100644
--- a/ansible/group_vars/all/openstack
+++ b/ansible/group_vars/all/openstack
@@ -29,3 +29,11 @@ openstack_auth_env:
   OS_AUTH_URL: "{{ lookup('env', 'OS_AUTH_URL') }}"
   OS_INTERFACE: "{{ lookup('env', 'OS_INTERFACE') }}"
   OS_IDENTITY_API_VERSION: "{{ lookup('env', 'OS_IDENTITY_API_VERSION') }}"
+
+# List of parameters required in openstack_auth when openstack_auth_type is
+# password.
+openstack_auth_password_required_params:
+  - "project_name"
+  - "username"
+  - "password"
+  - "auth_url"
diff --git a/ansible/ipa-images.yml b/ansible/ipa-images.yml
index 331f0fe0b..d9a52081c 100644
--- a/ansible/ipa-images.yml
+++ b/ansible/ipa-images.yml
@@ -1,6 +1,20 @@
 ---
 - name: Ensure Ironic Python Agent (IPA) images are downloaded and registered
   hosts: controllers[0]
+  pre_tasks:
+    - name: Validate OpenStack password authentication parameters
+      fail:
+        msg: >
+          Required OpenStack authentication parameter {{ item }} is
+          {% if item in openstack_auth %}empty{% else %}not present{% endif %}
+          in openstack_auth. Have you sourced the environment file?
+      when:
+        - "{{ openstack_auth_type == 'password' }}"
+        - "{{ item not in openstack_auth or not openstack_auth[item] }}"
+      with_items: "{{ openstack_auth_password_required_params }}"
+      tags:
+        - config-validation
+
   roles:
     - role: ipa-images
       ipa_images_venv: "{{ ansible_env['PWD'] }}/shade-venv"
diff --git a/ansible/overcloud-introspection-rules-dell-lldp-workaround.yml b/ansible/overcloud-introspection-rules-dell-lldp-workaround.yml
index 609a3cd3c..6cc68b65a 100644
--- a/ansible/overcloud-introspection-rules-dell-lldp-workaround.yml
+++ b/ansible/overcloud-introspection-rules-dell-lldp-workaround.yml
@@ -56,6 +56,19 @@
     inspector_rule_var_lldp_switch_port_interface: "{{ inspector_lldp_switch_port_interface }}"
 
   pre_tasks:
+    - name: Validate OpenStack password authentication parameters
+      fail:
+        msg: >
+          Required OpenStack authentication parameter {{ item }} is
+          {% if item in openstack_auth %}empty{% else %}not present{% endif %}
+          in openstack_auth. Have you sourced the environment file?
+      when:
+        - "{{ openstack_auth_type == 'password' }}"
+        - "{{ item not in openstack_auth or not openstack_auth[item] }}"
+      with_items: "{{ openstack_auth_password_required_params }}"
+      tags:
+        - config-validation
+
     # We build up the rules using a 2-step process. First we build a list of
     # relevant switch hosts and their interface configuration (in list form).
     # This allows us to use with_subelements in the next task to iterate over
diff --git a/ansible/overcloud-introspection-rules.yml b/ansible/overcloud-introspection-rules.yml
index 5cc1f1231..a4df75f88 100644
--- a/ansible/overcloud-introspection-rules.yml
+++ b/ansible/overcloud-introspection-rules.yml
@@ -4,6 +4,20 @@
   hosts: controllers[0]
   vars:
     venv: "{{ ansible_env.PWD }}/shade-venv"
+  pre_tasks:
+    - name: Validate OpenStack password authentication parameters
+      fail:
+        msg: >
+          Required OpenStack authentication parameter {{ item }} is
+          {% if item in openstack_auth %}empty{% else %}not present{% endif %}
+          in openstack_auth. Have you sourced the environment file?
+      when:
+        - "{{ openstack_auth_type == 'password' }}"
+        - "{{ item not in openstack_auth or not openstack_auth[item] }}"
+      with_items: "{{ openstack_auth_password_required_params }}"
+      tags:
+        - config-validation
+
   roles:
     - role: openstackclient
       openstackclient_venv: "{{ venv }}"
diff --git a/ansible/provision-net.yml b/ansible/provision-net.yml
index 1565567f7..fe89061b2 100644
--- a/ansible/provision-net.yml
+++ b/ansible/provision-net.yml
@@ -4,6 +4,20 @@
   hosts: controllers[0]
   vars:
     venv: "{{ ansible_env.PWD }}/shade-venv"
+  pre_tasks:
+    - name: Validate OpenStack password authentication parameters
+      fail:
+        msg: >
+          Required OpenStack authentication parameter {{ item }} is
+          {% if item in openstack_auth %}empty{% else %}not present{% endif %}
+          in openstack_auth. Have you sourced the environment file?
+      when:
+        - "{{ openstack_auth_type == 'password' }}"
+        - "{{ item not in openstack_auth or not openstack_auth[item] }}"
+      with_items: "{{ openstack_auth_password_required_params }}"
+      tags:
+        - config-validation
+
   roles:
     - role: neutron-net
       neutron_net_venv: "{{ venv }}"
diff --git a/ansible/test-project.yml b/ansible/test-project.yml
index 8c0ee7b7c..459f009a0 100644
--- a/ansible/test-project.yml
+++ b/ansible/test-project.yml
@@ -20,6 +20,19 @@
     test_ssh_key_type: rsa
 
   pre_tasks:
+    - name: Validate OpenStack password authentication parameters
+      fail:
+        msg: >
+          Required OpenStack authentication parameter {{ item }} is
+          {% if item in openstack_auth %}empty{% else %}not present{% endif %}
+          in openstack_auth. Have you sourced the environment file?
+      when:
+        - "{{ openstack_auth_type == 'password' }}"
+        - "{{ item not in openstack_auth or not openstack_auth[item] }}"
+      with_items: "{{ openstack_auth_password_required_params }}"
+      tags:
+        - config-validation
+
     - name: Check whether an SSH key exists on the controller
       stat:
         path: "{{ test_ssh_private_key_path }}"