diff --git a/changelogs/fragments/9096-alternatives-add-family-parameter.yml b/changelogs/fragments/9096-alternatives-add-family-parameter.yml
new file mode 100644
index 0000000000..a0b021f892
--- /dev/null
+++ b/changelogs/fragments/9096-alternatives-add-family-parameter.yml
@@ -0,0 +1,2 @@
+minor_changes:
+  - alternatives - add ``family`` parameter that allows to utilize the ``--family`` option available in RedHat version of update-alternatives (https://github.com/ansible-collections/community.general/issues/5060, https://github.com/ansible-collections/community.general/pull/9096).
diff --git a/plugins/modules/alternatives.py b/plugins/modules/alternatives.py
index da578276fa..d049c82b11 100644
--- a/plugins/modules/alternatives.py
+++ b/plugins/modules/alternatives.py
@@ -39,7 +39,11 @@ options:
     description:
       - The path to the real executable that the link should point to.
     type: path
-    required: true
+  family:
+    description:
+      - The family groups similar alternatives. This option is available only on RHEL-based distributions.
+    type: str
+    version_added: 10.1.0
   link:
     description:
       - The path to the symbolic link that should point to the real executable.
@@ -98,6 +102,12 @@ EXAMPLES = r'''
     name: java
     path: /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java
 
+- name: Select java-11-openjdk.x86_64 family
+  community.general.alternatives:
+    name: java
+    family: java-11-openjdk.x86_64
+  when: ansible_os_family == 'RedHat'
+
 - name: Alternatives link created
   community.general.alternatives:
     name: hadoop-conf
@@ -182,17 +192,25 @@ class AlternativesModule(object):
             subcommands_parameter = self.module.params['subcommands']
             priority_parameter = self.module.params['priority']
             if (
-                self.path not in self.current_alternatives or
-                (priority_parameter is not None and self.current_alternatives[self.path].get('priority') != priority_parameter) or
-                (subcommands_parameter is not None and (
-                    not all(s in subcommands_parameter for s in self.current_alternatives[self.path].get('subcommands')) or
-                    not all(s in self.current_alternatives[self.path].get('subcommands') for s in subcommands_parameter)
-                ))
+                self.path is not None and (
+                    self.path not in self.current_alternatives or
+                    (priority_parameter is not None and self.current_alternatives[self.path].get('priority') != priority_parameter) or
+                    (subcommands_parameter is not None and (
+                        not all(s in subcommands_parameter for s in self.current_alternatives[self.path].get('subcommands')) or
+                        not all(s in self.current_alternatives[self.path].get('subcommands') for s in subcommands_parameter)
+                    ))
+                )
             ):
                 self.install()
 
             # Check if we need to set the preference
-            if self.mode_selected and self.current_path != self.path:
+            is_same_path = self.path is not None and self.current_path == self.path
+            is_same_family = False
+            if self.current_path is not None and self.current_path in self.current_alternatives:
+                current_alternative = self.current_alternatives[self.current_path]
+                is_same_family = current_alternative.get('family') == self.family
+
+            if self.mode_selected and not (is_same_path or is_same_family):
                 self.set()
 
             # Check if we need to reset to auto
@@ -213,6 +231,8 @@ class AlternativesModule(object):
             self.module.fail_json(msg='Needed to install the alternative, but unable to do so as we are missing the link')
 
         cmd = [self.UPDATE_ALTERNATIVES, '--install', self.link, self.name, self.path, str(self.priority)]
+        if self.family is not None:
+            cmd.extend(["--family", self.family])
 
         if self.module.params['subcommands'] is not None:
             subcommands = [['--slave', subcmd['link'], subcmd['name'], subcmd['path']] for subcmd in self.subcommands]
@@ -228,6 +248,7 @@ class AlternativesModule(object):
             self.result['diff']['after'] = dict(
                 state=AlternativeState.PRESENT,
                 path=self.path,
+                family=self.family,
                 priority=self.priority,
                 link=self.link,
             )
@@ -248,9 +269,15 @@ class AlternativesModule(object):
             self.result['diff']['after'] = dict(state=AlternativeState.ABSENT)
 
     def set(self):
-        cmd = [self.UPDATE_ALTERNATIVES, '--set', self.name, self.path]
+        # Path takes precedence over family as it is more specific
+        if self.path is None:
+            arg = self.family
+        else:
+            arg = self.path
+
+        cmd = [self.UPDATE_ALTERNATIVES, '--set', self.name, arg]
         self.result['changed'] = True
-        self.messages.append("Set alternative '%s' for '%s'." % (self.path, self.name))
+        self.messages.append("Set alternative '%s' for '%s'." % (arg, self.name))
 
         if not self.module.check_mode:
             self.module.run_command(cmd, check_rc=True)
@@ -277,6 +304,10 @@ class AlternativesModule(object):
     def path(self):
         return self.module.params.get('path')
 
+    @property
+    def family(self):
+        return self.module.params.get('family')
+
     @property
     def link(self):
         return self.module.params.get('link') or self.current_link
@@ -321,7 +352,7 @@ class AlternativesModule(object):
         current_link_regex = re.compile(r'^\s*link \w+ is (.*)$', re.MULTILINE)
         subcmd_path_link_regex = re.compile(r'^\s*(?:slave|follower) (\S+) is (.*)$', re.MULTILINE)
 
-        alternative_regex = re.compile(r'^(\/.*)\s-\s(?:family\s\S+\s)?priority\s(\d+)((?:\s+(?:slave|follower).*)*)', re.MULTILINE)
+        alternative_regex = re.compile(r'^(\/.*)\s-\s(?:family\s(\S+)\s)?priority\s(\d+)((?:\s+(?:slave|follower).*)*)', re.MULTILINE)
         subcmd_regex = re.compile(r'^\s+(?:slave|follower) (.*): (.*)$', re.MULTILINE)
 
         match = current_mode_regex.search(display_output)
@@ -346,9 +377,10 @@ class AlternativesModule(object):
         if not subcmd_path_map and self.subcommands:
             subcmd_path_map = {s['name']: s['link'] for s in self.subcommands}
 
-        for path, prio, subcmd in alternative_regex.findall(display_output):
+        for path, family, prio, subcmd in alternative_regex.findall(display_output):
             self.current_alternatives[path] = dict(
                 priority=int(prio),
+                family=family,
                 subcommands=[dict(
                     name=name,
                     path=spath,
@@ -383,7 +415,8 @@ def main():
     module = AnsibleModule(
         argument_spec=dict(
             name=dict(type='str', required=True),
-            path=dict(type='path', required=True),
+            path=dict(type='path'),
+            family=dict(type='str'),
             link=dict(type='path'),
             priority=dict(type='int'),
             state=dict(
@@ -398,6 +431,7 @@ def main():
             )),
         ),
         supports_check_mode=True,
+        required_one_of=[('path', 'family')]
     )
 
     AlternativesModule(module)
diff --git a/tests/integration/targets/alternatives/tasks/main.yml b/tests/integration/targets/alternatives/tasks/main.yml
index 81d6a7b0df..cd86b085d4 100644
--- a/tests/integration/targets/alternatives/tasks/main.yml
+++ b/tests/integration/targets/alternatives/tasks/main.yml
@@ -58,6 +58,12 @@
     - include_tasks: remove_links.yml
     - include_tasks: tests_state.yml
 
+  # Test for the family parameter
+  - block:
+      - include_tasks: remove_links.yml
+      - include_tasks: tests_family.yml
+    when: ansible_os_family == 'RedHat'
+
   # Cleanup
   always:
     - include_tasks: remove_links.yml
diff --git a/tests/integration/targets/alternatives/tasks/tests_family.yml b/tests/integration/targets/alternatives/tasks/tests_family.yml
new file mode 100644
index 0000000000..ac4eadebe1
--- /dev/null
+++ b/tests/integration/targets/alternatives/tasks/tests_family.yml
@@ -0,0 +1,65 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Add an alternative with a family
+  alternatives:
+    name: dummy
+    path: /usr/bin/dummy1
+    link: /usr/bin/dummy
+    family: family1
+    priority: 100
+    state: selected
+
+- name: Ensure that the alternative has family assigned
+  shell: 'grep family1 {{ alternatives_dir }}/dummy'
+
+- name: Add two alternatives with different families
+  alternatives:
+    name: dummy
+    path: '/usr/bin/dummy{{ item.n }}'
+    link: /usr/bin/dummy
+    family: family2
+    priority: "{{ item.priority }}"
+    state: present
+  loop:
+    - { n: 2, priority: 20 }
+    - { n: 3, priority: 10 }
+    - { n: 4, priority: 5 }
+
+# Here we select the whole family of alternatives
+- name: Set family as an alternatives
+  alternatives:
+    name: dummy
+    family: family2
+    state: selected
+
+- name: Ensure manual mode
+  shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^manual"'
+
+- name: Execute the current dummy command
+  shell: dummy
+  register: cmd
+
+# Despite the fact that there is alternative with higher priority (/usr/bin/dummy1),
+# it is not chosen as it doesn't belong to the selected family
+- name: Ensure that the alternative from the selected family is used
+  assert:
+    that:
+      - cmd.stdout == "dummy2"
+
+- name: Remove the alternative with the highest priority that belongs to the family
+  alternatives:
+    name: dummy
+    path: '/usr/bin/dummy2'
+    state: absent
+
+- name: Execute the current dummy command
+  shell: dummy
+  register: cmd
+
+- name: Ensure that the next alternative is selected as having the highest priority from the family
+  assert:
+    that:
+      - cmd.stdout == "dummy3"