### Summary

This appears to be related to this change around action_groups: https://github.com/ansible/ansible/pull/74039

Before that, a module in a role could be set in `module_defaults`, but it doesn't work anymore. The action fails to resolve, as it's always trying to associate it with `ansible.builtin` rather than `ansible.legacy`, even when fully qualified.

Consider a role with `library/my_module.py` and a simple `tasks/main.yml`:

```yaml
- name: Try defaults
  module_defaults:
    my_module:
      data: hello
  block:

    - my_module:
```

```yaml
- name: Try defaults
  module_defaults:
    my_module:
      data: hello
  block:

    - ansible.legacy.my_module:
```

```yaml
- name: Try defaults
  module_defaults:
    ansible.legacy.my_module:
      data: hello
  block:

    - ansible.legacy.my_module:
```

```yaml
- name: Try defaults
  module_defaults:
    ansible.legacy.my_module:
      data: hello
  block:

    - my_module:
```

All permutations fail with the same error:

> ERROR! Could not resolve action ansible.builtin.my_module in module_defaults

EDIT to add:

I checked out commit 9af0d916768986f50647b11f896a7cdac1550230 (which as far as I can tell is the last commit before the linked PR was merged), and all of the above forms work except the last one, which fails with:

> fatal: [localhost]: FAILED! => {"changed": false, "msg": "missing required arguments: data"}


---

The changelog entry in that PR mentions:

> Fully qualified 'ansible.legacy' plugin names are not included implicitly in action_groups.

But I'm not sure if that's relevant, as no action groups are in play here. I couldn't find any way to make module defaults work for the module in the role.

### Issue Type

Bug Report

### Component Name

lib/ansible/playbook/base.py

### Ansible Version

```console
$ ansible --version
ansible [core 2.12.0.dev0] (devel 1fc1ab89ae) last updated 2021/07/17 12:29:56 (GMT -400)
  config file = None
  configured module search path = ['/home/briantist/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/briantist/code/ansible/ansible.core/lib/ansible
  ansible collection location = /home/briantist/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/briantist/code/ansible/ansible.core/bin/ansible
  python version = 3.6.9 (default, Jan 26 2021, 15:33:00) [GCC 8.4.0]
  jinja version = 3.0.1
  libyaml = True
```


### Configuration

```console
$ ansible-config dump --only-changed
[DEPRECATION WARNING]: Ansible will require Python 3.8 or newer on the controller starting with Ansible 2.12. Current version: 3.6.9 (default, Jan 26 2021, 15:33:00) [GCC 8.4.0]. This feature will be removed from
 ansible-core in version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
[WARNING]: You are running the development version of Ansible. You should only run Ansible from "devel" if you are modifying the Ansible engine, or trying out features under development. This is a rapidly
changing source of code and can become unstable at any point.
[DEPRECATION WARNING]: ANSIBLE_CALLBACK_WHITELIST option, normalizing names to new standard, use ANSIBLE_CALLBACKS_ENABLED instead. This feature will be removed from ansible-core in version 2.15. Deprecation
warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
CALLBACKS_ENABLED(env: ANSIBLE_CALLBACK_WHITELIST) = ['profile_tasks']
DEFAULT_FORKS(env: ANSIBLE_FORKS) = 30
INVENTORY_ENABLED(env: ANSIBLE_INVENTORY_ENABLED) = ['host_list', 'auto', 'ini', 'yaml', 'toml']
```


### OS / Environment

Ubuntu 18.04 in WSL2

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
Described in issue summary

### Expected Results

`module_defaults` work for modules in a role

### Actual Results

```console
ERROR! Could not resolve action ansible.builtin.my_module in module_defaults
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct
def _create_attrs(src_dict, dst_dict):
            '''
            Helper method which creates the attributes based on those in the
            source dictionary of attributes. This also populates the other
            attributes used to keep track of these attributes and via the
            getter/setter/deleter methods.
            '''
            keys = list(src_dict.keys())
            for attr_name in keys:
                value = src_dict[attr_name]
                if isinstance(value, Attribute):
                    if attr_name.startswith('_'):
                        attr_name = attr_name[1:]
                    
                    
                    
                    
                    method = "_get_attr_%s" % attr_name
                    if method in src_dict or method in dst_dict:
                        getter = partial(_generic_g_method, attr_name)
                    elif ('_get_parent_attribute' in dst_dict or '_get_parent_attribute' in src_dict) and value.inherit:
                        getter = partial(_generic_g_parent, attr_name)
                    else:
                        getter = partial(_generic_g, attr_name)
                    setter = partial(_generic_s, attr_name)
                    deleter = partial(_generic_d, attr_name)