diff --git a/SOURCES/0001-Fix-final-fact-delegation-77008-77017.patch b/SOURCES/0001-Fix-final-fact-delegation-77008-77017.patch
new file mode 100644
index 0000000..0d8e994
--- /dev/null
+++ b/SOURCES/0001-Fix-final-fact-delegation-77008-77017.patch
@@ -0,0 +1,87 @@
+From ae35fc04c3a2068b1d37efe813d1c6938b4f2634 Mon Sep 17 00:00:00 2001
+From: Brian Coca <bcoca@users.noreply.github.com>
+Date: Wed, 16 Feb 2022 11:55:03 -0500
+Subject: [PATCH] Fix final fact delegation (#77008) (#77017)
+
+* fix facts delegation loop overwrite
+
+ partial revert of change to allow facts to be present in each loop iteration
+ was not needed in final results as result processing alreayd had the disctiontion
+ and ended up breaking the assumptions in the calling code.
+
+ fixes #76676
+
+(cherry picked from commit c9d3518d2f3812787e1627806b5fa93f8fae48a6)
+---
+ .../fragments/fix_fax_delegation_loops.yml    |  2 ++
+ lib/ansible/executor/task_executor.py         |  8 +------
+ .../delegate_to/delegate_facts_loop.yml       | 21 ++++++++++++++++++-
+ 3 files changed, 23 insertions(+), 8 deletions(-)
+ create mode 100644 changelogs/fragments/fix_fax_delegation_loops.yml
+
+diff --git a/changelogs/fragments/fix_fax_delegation_loops.yml b/changelogs/fragments/fix_fax_delegation_loops.yml
+new file mode 100644
+index 0000000000..d9e07bf110
+--- /dev/null
++++ b/changelogs/fragments/fix_fax_delegation_loops.yml
+@@ -0,0 +1,2 @@
++bugfixes:
++  - task_executor reverts the change to push facts into delegated vars on loop finalization as result managing code already handles this and was duplicating effort to wrong result.
+diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py
+index 1a7c666fea..05dcb96446 100644
+--- a/lib/ansible/executor/task_executor.py
++++ b/lib/ansible/executor/task_executor.py
+@@ -745,13 +745,7 @@ class TaskExecutor:
+ 
+         if 'ansible_facts' in result and self._task.action not in C._ACTION_DEBUG:
+             if self._task.action in C._ACTION_WITH_CLEAN_FACTS:
+-                if self._task.delegate_to and self._task.delegate_facts:
+-                    if '_ansible_delegated_vars' in variables:
+-                        variables['_ansible_delegated_vars'].update(result['ansible_facts'])
+-                    else:
+-                        variables['_ansible_delegated_vars'] = result['ansible_facts']
+-                else:
+-                    variables.update(result['ansible_facts'])
++                variables.update(result['ansible_facts'])
+             else:
+                 # TODO: cleaning of facts should eventually become part of taskresults instead of vars
+                 af = wrap_var(result['ansible_facts'])
+diff --git a/test/integration/targets/delegate_to/delegate_facts_loop.yml b/test/integration/targets/delegate_to/delegate_facts_loop.yml
+index 90a25676dd..28a1488de3 100644
+--- a/test/integration/targets/delegate_to/delegate_facts_loop.yml
++++ b/test/integration/targets/delegate_to/delegate_facts_loop.yml
+@@ -5,7 +5,6 @@
+         test: 123
+       delegate_to: "{{ item }}"
+       delegate_facts: true
+-      when: test is not defined
+       loop: "{{ groups['all'] | difference(['localhost']) }}"
+ 
+     - name: ensure we didnt create it on current host
+@@ -19,3 +18,23 @@
+           - "'test' in hostvars[item]"
+           - hostvars[item]['test'] == 123
+       loop: "{{ groups['all'] | difference(['localhost']) }}"
++
++
++- name: test that we don't polute whole group with one value
++  hosts: localhost
++  gather_facts: no
++  vars:
++    cluster_name: bleh
++  tasks:
++  - name: construct different fact per host in loop
++    set_fact:
++      vm_name: "{{ cluster_name }}-{{item}}"
++    delegate_to: "{{ item }}"
++    delegate_facts: True
++    with_items: "{{ groups['all'] }}"
++
++  - name: ensure the fact is personalized for each host
++    assert:
++      that:
++        - hostvars[item]['vm_name'].endswith(item)
++    loop: "{{ groups['all'] }}"
+-- 
+2.30.2
+
diff --git a/SPECS/ansible-core.spec b/SPECS/ansible-core.spec
index 9a23b6f..07024e2 100644
--- a/SPECS/ansible-core.spec
+++ b/SPECS/ansible-core.spec
@@ -35,7 +35,7 @@
 Name: ansible-core
 Summary: SSH-based configuration management, deployment, and task execution system
 Version: 2.12.2
-Release: 3.1%{?dist}
+Release: 4%{?dist}
 ExcludeArch: i686
 
 Group: Development/Libraries
@@ -50,6 +50,8 @@ Source3: pyparsing-6a844ee35ca5125490a28dbd6dd2d15b6498e605.tar.gz
 # Deps to build man pages
 Source5: straightplugin-6634ea8e1e89d5bb23804f50e676f196c52c46ed.tar.gz
 
+Patch0: 0001-Fix-final-fact-delegation-77008-77017.patch
+
 URL: http://ansible.com
 
 # We conflict old ansible, and any version of ansible-base.
@@ -116,6 +118,7 @@ developed for ansible.
 %setup -q -T -b 3 -n pyparsing-6a844ee35ca5125490a28dbd6dd2d15b6498e605
 %setup -q -T -b 5 -n straightplugin-6634ea8e1e89d5bb23804f50e676f196c52c46ed
 %setup -q -n ansible-%{commitId}
+%patch0 -p 1
 
 # Fix all Python shebangs recursively in ansible-test
 # -p preserves timestamps
@@ -206,6 +209,9 @@ cp -p lib/ansible_core.egg-info/PKG-INFO .
 %{python38_sitelib}/ansible_test
 
 %changelog
+* Tue Jul 19 2022 Dimitri Savineau <dsavinea@redhat.com> - 2.12.2-4
+- fix facts delegation loop overwrite (rhbz#2109263)
+
 * Thu Mar 10 2022 Dimitri Savineau <dsavinea@redhat.com> - 2.12.2-3.1
 - Rebuilt for rhel-8.6