##### SUMMARY

When setting `fact_path` in `ansible.cfg`, the configured path is used only for `gather_facts`; it has no effect when using `setup` as a task or when running `ansible -m setup` ad-hoc. This behavior is in fact [documented](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/setup_module.html#):

> The default fact_path can be specified in ansible.cfg for when setup is automatically called as part of gather_facts


This is particularly painful when the controller is running, say, FreeBSD, as they package Ansible with a default of `/usr/local/etc/ansible/facts.d` which differs greatly from Ansible's typical default of `/etc/ansible/facts.d`. Note that I do not think this is a FreeBSD packaging issue.

##### ISSUE TYPE
- Feature Request

##### COMPONENT NAME

setup

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes -->
```
ansible 2.10.2
  config file = /Users/jpm/.ansible.cfg
  configured module search path = ['/etc/ansible/library']
  ansible python module location = /private/tmp/an/env.v3/lib/python3.8/site-packages/ansible
  executable location = /private/tmp/an/env.v3/bin/ansible
  python version = 3.8.5 (default, Sep 27 2020, 11:38:54) [Clang 12.0.0 (clang-1200.0.32.2)]
```

##### CONFIGURATION
<!--- Paste verbatim output from "ansible-config dump --only-changed" between quotes -->
```
ANSIBLE_NOCOWS(/Users/jpm/.ansible.cfg) = True
ANSIBLE_SSH_ARGS(/Users/jpm/.ansible.cfg) = -o PasswordAuthentication=no -o ControlMaster=auto -o ControlPersist=60s -o ControlPath=/tmp/ansible-ssh-%h-%p-%r -o PreferredAuthentications=publickey,gssapi-with-mic,gssapi-keyex,hostbased
DEFAULT_ACTION_PLUGIN_PATH(/Users/jpm/.ansible.cfg) = ['/etc/ansible/jp.action_plugins']
DEFAULT_FACT_PATH(/Users/jpm/.ansible.cfg) = /tmp/jp/facts.d
DEFAULT_FILTER_PLUGIN_PATH(/Users/jpm/.ansible.cfg) = ['/etc/ansible/jp.filter_plugins']
DEFAULT_HOST_LIST(/Users/jpm/.ansible.cfg) = ['/etc/ansible/hosts']
DEFAULT_LOAD_CALLBACK_PLUGINS(/Users/jpm/.ansible.cfg) = True
DEFAULT_MANAGED_STR(/Users/jpm/.ansible.cfg) = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host}
DEFAULT_MODULE_PATH(/Users/jpm/.ansible.cfg) = ['/etc/ansible/library']
RETRY_FILES_ENABLED(/Users/jpm/.ansible.cfg) = False
```


##### OS / ENVIRONMENT
<!--- Provide all relevant information below, e.g. target OS versions, network device firmware, etc. -->

Linux, FreeBSD, MacOSX

##### STEPS TO REPRODUCE

1. Create an new directory (`/tmp/jp/facts.d`) and a fact file within
2. Run playbook
3. Run ad-hoc `setup`

<!--- Paste example playbooks or commands between quotes below -->
```yaml
- hosts: 127.0.0.1
  connection: local
  gather_facts: true
  tasks:
  - debug: msg='{{ ansible_local.hw.name }}'
```

<!--- HINT: You can paste gist.github.com links for larger files -->

##### EXPECTED RESULTS

I expect the ad-hoc `setup` to produce the same values as the setup invocation via `gather_facts`

##### ACTUAL RESULTS
<!--- Describe what actually happened. If possible run with extra verbosity (-vvvv) -->
```console
$ cat /tmp/jp/facts.d/hw.fact
{ "name" : "Jane Jolie" }

$ ansible-playbook test.yml
PLAY [127.0.0.1] ********************************************************************

TASK [Gathering Facts] **************************************************************
ok: [localhost]

TASK [debug] ************************************************************************
ok: [localhost] => {
    "msg": "Jane Jolie"
}
```

This does not work as expected:

```console
$ ansible 127.0.0.1 -c local -m setup -a filter=ansible_local
localhost | SUCCESS => {
    "ansible_facts": {
        "ansible_local": {}
    },
    "changed": false
}
```


#
#
#
#
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible import constants as C
from ansible import context
from ansible.errors import AnsibleParserError, AnsibleAssertionError
from ansible.module_utils._text import to_native
from ansible.module_utils.common.collections import is_sequence
from ansible.module_utils.six import binary_type, string_types, text_type
from ansible.playbook.attribute import FieldAttribute
from ansible.playbook.base import Base
from ansible.playbook.block import Block
from ansible.playbook.collectionsearch import CollectionSearch
from ansible.playbook.helpers import load_list_of_blocks, load_list_of_roles
from ansible.playbook.role import Role
from ansible.playbook.taggable import Taggable
from ansible.vars.manager import preprocess_vars
from ansible.utils.display import Display
display = Display()
__all__ = ['Play']
class Play(Base, Taggable, CollectionSearch):
    """
    A play is a language feature that represents a list of roles and/or