diff --git a/lib/ansible/plugins/__init__.py b/lib/ansible/plugins/__init__.py
index f5a6f112a8..9e2229e8c9 100644
--- a/lib/ansible/plugins/__init__.py
+++ b/lib/ansible/plugins/__init__.py
@@ -373,6 +373,7 @@ class PluginLoader:
     def all(self, *args, **kwargs):
         ''' instantiates all plugins with the same arguments '''
 
+        path_only = kwargs.pop('path_only', False)
         class_only = kwargs.pop('class_only', False)
         all_matches = []
         found_in_cache = True
@@ -385,6 +386,10 @@ class PluginLoader:
             if '__init__' in name:
                 continue
 
+            if path_only:
+                yield path
+                continue
+
             if path not in self._module_cache:
                 self._module_cache[path] = self._load_module_source(name, path)
                 found_in_cache = False
diff --git a/lib/ansible/plugins/action/__init__.py b/lib/ansible/plugins/action/__init__.py
index c58a7a205e..540fcf0b8b 100644
--- a/lib/ansible/plugins/action/__init__.py
+++ b/lib/ansible/plugins/action/__init__.py
@@ -38,6 +38,7 @@ from ansible.executor.module_common import modify_module
 from ansible.module_utils._text import to_bytes, to_native, to_text
 from ansible.module_utils.json_utils import _filter_non_json_lines
 from ansible.parsing.utils.jsonify import jsonify
+from ansible.playbook.play_context import MAGIC_VARIABLE_MAPPING
 from ansible.release import __version__
 
 
@@ -670,6 +671,32 @@ class ActionBase(with_metaclass(ABCMeta, object)):
                 display.warning(w)
             data = json.loads(filtered_output)
             data['_ansible_parsed'] = True
+            if 'ansible_facts' in data and isinstance(data['ansible_facts'], dict):
+                remove_keys = set()
+                fact_keys = set(data['ansible_facts'].keys())
+                # first we add all of our magic variable names to the set of
+                # keys we want to remove from facts
+                for magic_var in MAGIC_VARIABLE_MAPPING:
+                    remove_keys.update(fact_keys.intersection(MAGIC_VARIABLE_MAPPING[magic_var]))
+                # next we remove any connection plugin specific vars
+                for conn_path in self._shared_loader_obj.connection_loader.all(path_only=True):
+                    try:
+                        conn_name = os.path.splitext(os.path.basename(conn_path))[0]
+                        re_key = re.compile('^ansible_%s_' % conn_name)
+                        for fact_key in fact_keys:
+                            if re_key.match(fact_key):
+                                remove_keys.add(fact_key)
+                    except AttributeError:
+                        pass
+                # finally, we search for interpreter keys to remove
+                re_interp = re.compile('^ansible_.*_interpreter$')
+                for fact_key in fact_keys:
+                    if re_interp.match(fact_key):
+                        remove_keys.add(fact_key)
+                # then we remove them (except for ssh host keys)
+                for r_key in remove_keys:
+                    if not r_key.startswith('ansible_ssh_host_key_'):
+                        del data['ansible_facts'][r_key]
         except ValueError:
             # not valid json, lets try to capture error
             data = dict(failed=True, _ansible_parsed=False)