diff --git a/.gitignore b/.gitignore
index c34739832c6501104c9c8bce9c31e87dfd9bcfb0..0ec5d2de89a943c903c3975bf607b72a6604fbb0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,8 @@ extra_vars.json
 .config
 .config.old
 
+ansible.cfg
+
 scripts/kconfig/.mconf-cfg
 scripts/workflows/fstests/lib/__pycache__/
 scripts/workflows/blktests/lib/__pycache__/
diff --git a/MAINTAINERS b/MAINTAINERS
index 045d8c96208ef8f3f1c5d74d023a5117529511cf..6df6709fb59d14ba486050d2ce961923b292ec73 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -72,6 +72,10 @@ M:	Daniel Gomez <da.gomez@samsung.com>
 L:	kdevops@lists.linux.dev
 S:	Maintained
 T:	git https://github.com/linux-kdevops/kdevops.git
+F:	ansible.cfg
+F:	kconfigs/Kconfig.ansible_cfg
+F:	playbooks/ansible_cfg.yml
+F:	playbooks/roles/ansible_cfg
 F:	scripts/ansible_av.py
 F:	scripts/ansible.Makefile
 
diff --git a/Makefile b/Makefile
index 14e647dcd45190ff51dd42627f58826998f07781..fa8761bcb6bc2c612ef7bff4f904c94ca258d523 100644
--- a/Makefile
+++ b/Makefile
@@ -190,9 +190,17 @@ include scripts/gen-nodes.Makefile
 	make -f scripts/build.Makefile help                             ;\
 	false)
 
+
+PHONY += ansible.cfg
+ansible.cfg:
+	@$(Q)ansible-playbook $(ANSIBLE_VERBOSE) --connection=local \
+		--inventory localhost, \
+		$(KDEVOPS_PLAYBOOKS_DIR)/ansible_cfg.yml \
+		--extra-vars=@./.extra_vars_auto.yaml
+
 PHONY += $(EXTRA_VAR_INPUTS) $(EXTRA_VAR_INPUTS_LAST)
 
-$(KDEVOPS_EXTRA_VARS): .config $(EXTRA_VAR_INPUTS) $(EXTRA_VAR_INPUTS_LAST)
+$(KDEVOPS_EXTRA_VARS): .config ansible.cfg $(EXTRA_VAR_INPUTS) $(EXTRA_VAR_INPUTS_LAST)
 
 playbooks/secret.yml:
 	@if [[ "$(CONFIG_KDEVOPS_REG_TWOLINE_REGCODE)" == "" ]]; then \
@@ -204,7 +212,7 @@ playbooks/secret.yml:
 	@echo "$(CONFIG_KDEVOPS_REG_TWOLINE_REGCODE_VAR): $(CONFIG_KDEVOPS_REG_TWOLINE_REGCODE)" >> $@
 
 ifeq (y,$(CONFIG_KDEVOPS_ENABLE_DISTRO_EXTRA_ADDONS))
-$(KDEVOPS_EXTRA_ADDON_DEST): .config $(KDEVOPS_EXTRA_ADDON_SOURCE)
+$(KDEVOPS_EXTRA_ADDON_DEST): .config ansible.cfg $(KDEVOPS_EXTRA_ADDON_SOURCE)
 	$(Q)cp $(KDEVOPS_EXTRA_ADDON_SOURCE) $(KDEVOPS_EXTRA_ADDON_DEST)
 endif
 
@@ -215,7 +223,7 @@ include scripts/bringup.Makefile
 endif
 
 DEFAULT_DEPS += $(KDEVOPS_HOSTS)
-$(KDEVOPS_HOSTS): .config $(KDEVOPS_HOSTS_TEMPLATE)
+$(KDEVOPS_HOSTS): .config ansible.cfg $(KDEVOPS_HOSTS_TEMPLATE)
 	$(Q)ansible-playbook $(ANSIBLE_VERBOSE) --connection=local \
 		--inventory localhost, \
 		$(KDEVOPS_PLAYBOOKS_DIR)/gen_hosts.yml \
@@ -223,7 +231,7 @@ $(KDEVOPS_HOSTS): .config $(KDEVOPS_HOSTS_TEMPLATE)
 		--extra-vars=@./extra_vars.yaml
 
 DEFAULT_DEPS += $(KDEVOPS_NODES)
-$(KDEVOPS_NODES) $(KDEVOPS_VAGRANT): .config $(KDEVOPS_NODES_TEMPLATE)
+$(KDEVOPS_NODES) $(KDEVOPS_VAGRANT): .config ansible.cfg $(KDEVOPS_NODES_TEMPLATE)
 	$(Q)ansible-playbook $(ANSIBLE_VERBOSE) --connection=local \
 		--inventory localhost, \
 		$(KDEVOPS_PLAYBOOKS_DIR)/gen_nodes.yml \
@@ -253,6 +261,7 @@ mrproper:
 	$(Q)rm -f $(KDEVOPS_NODES)
 	$(Q)rm -f $(KDEVOPS_HOSTFILE) $(KDEVOPS_MRPROPER)
 	$(Q)rm -f .config .config.old extra_vars.yaml $(KCONFIG_YAMLCFG)
+	$(Q)rm -f ansible.cfg
 	$(Q)rm -f playbooks/secret.yml $(KDEVOPS_EXTRA_ADDON_DEST)
 	$(Q)rm -rf include
 	$(Q)rm -rf guestfs
diff --git a/ansible.cfg b/ansible.cfg
deleted file mode 100644
index 08350e0cf0f33e650801f4d8a2b450c77ef22a97..0000000000000000000000000000000000000000
--- a/ansible.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-[defaults]
-display_skipped_hosts = no
-retries = 2000
-deprecation_warnings=False
-stdout_callback=debug
diff --git a/kconfigs/Kconfig.ansible_cfg b/kconfigs/Kconfig.ansible_cfg
new file mode 100644
index 0000000000000000000000000000000000000000..0aa95bfaa6dfd6947f61b1b9da2cf55c16cd95ce
--- /dev/null
+++ b/kconfigs/Kconfig.ansible_cfg
@@ -0,0 +1,103 @@
+menu "Ansible Callback Plugin Configuration"
+choice
+	prompt "Ansible Callback Plugin"
+	default ANSIBLE_CFG_CALLBACK_PLUGIN_DEBUG
+
+config ANSIBLE_CFG_CALLBACK_PLUGIN_DEBUG
+	bool "Ansible Debug Callback Plugin"
+	help
+	  Debug: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/debug_module.html
+
+config ANSIBLE_CFG_CALLBACK_PLUGIN_DENSE
+	bool "Ansible Dense Callback Plugin"
+	help
+	  Dense: https://docs.ansible.com/ansible/latest/collections/community/general/dense_callback.html
+
+endchoice
+
+config ANSIBLE_CFG_CALLBACK_PLUGIN_STRING
+	string
+	output yaml
+	default "debug" if ANSIBLE_CFG_CALLBACK_PLUGIN_DEBUG
+	default "dense" if ANSIBLE_CFG_CALLBACK_PLUGIN_DENSE
+
+config ANSIBLE_CFG_CALLBACK_PLUGIN_CHECK_MODE_MARKERS
+	bool "check_mode_markers"
+	output yaml
+	default n
+	help
+	  Toggle to control displaying markers when running in check mode.
+	  https://docs.ansible.com/ansible/latest/collections/community/general/dense_callback.html#parameter-check_mode_markers
+
+config ANSIBLE_CFG_CALLBACK_PLUGIN_DISPLAY_FAILED_STDERR
+	bool "display_failed_stderr"
+	output yaml
+	default n
+	help
+	  Toggle to control whether failed and unreachable tasks are displayed to STDERR (vs. STDOUT).
+	  https://docs.ansible.com/ansible/latest/collections/community/general/dense_callback.html#parameter-display_failed_stderr
+
+config ANSIBLE_CFG_CALLBACK_PLUGIN_DISPLAY_OK_HOSTS
+	bool "display_ok_hosts"
+	output yaml
+	default y
+	help
+	  Toggle to control displaying ‘ok’ task/host results in a task.
+	  https://docs.ansible.com/ansible/latest/collections/community/general/dense_callback.html#parameter-display_ok_hosts
+
+config ANSIBLE_CFG_CALLBACK_PLUGIN_DISPLAY_SKIPPED_HOSTS
+	bool "display_skipped_hosts"
+	output yaml
+	default n
+	help
+	  Toggle to control displaying skipped task/host results in a task.
+	  https://docs.ansible.com/ansible/latest/collections/community/general/dense_callback.html#parameter-display_skipped_hosts
+
+config ANSIBLE_CFG_CALLBACK_PLUGIN_SHOW_CUSTOM_STATS
+	bool "show_custom_stats"
+	output yaml
+	default n
+	help
+	  This adds the custom stats set via the set_stats plugin to the play recap
+	  https://docs.ansible.com/ansible/latest/collections/community/general/dense_callback.html#parameter-show_custom_stats
+
+config ANSIBLE_CFG_CALLBACK_PLUGIN_SHOW_PER_HOST_START
+	bool "show_per_host_start"
+	output yaml
+	default n
+	help
+	  This adds output that shows when a task is started to execute for each host
+	  https://docs.ansible.com/ansible/latest/collections/community/general/dense_callback.html#parameter-show_per_host_start
+
+config ANSIBLE_CFG_CALLBACK_PLUGIN_SHOW_TASK_PATH_ON_FAILURE
+	bool "show_task_path_on_failure"
+	output yaml
+	default n
+	help
+	  When a task fails, display the path to the file containing the failed task and
+	  the line number. This information is displayed automatically for every task when
+	  running with -vv or greater verbosity.
+	  https://docs.ansible.com/ansible/latest/collections/community/general/dense_callback.html#parameter-show_task_path_on_failure
+endmenu
+
+config ANSIBLE_CFG_DEPRECATION_WARNINGS
+	bool "deprecation_warnings"
+	output yaml
+	default y
+	help
+	  Toggle to control the showing of deprecation warnings
+	  https://docs.ansible.com/ansible/latest/reference_appendices/config.html#deprecation-warnings
+
+if DISTRO_OPENSUSE
+
+config ANSIBLE_CFG_RECONNECTION_RETRIES
+	string "reconnection_retries"
+	output yaml
+	default 2000
+	help
+	  Number of attempts to connect.
+	  Ansible retries connections only if it gets an SSH error with a return code of 255.
+	  Any errors with return codes other than 255 indicate an issue with program execution.
+	  https://docs.ansible.com/ansible/latest/collections/ansible/builtin/ssh_connection.html#parameter-reconnection_retries
+
+endif # DISTRO_OPENSUSE
diff --git a/kconfigs/Kconfig.kdevops b/kconfigs/Kconfig.kdevops
index c613ff20c193e717413d983af99bb97069988044..35e9758d789255721c522636ada49f84710e042f 100644
--- a/kconfigs/Kconfig.kdevops
+++ b/kconfigs/Kconfig.kdevops
@@ -195,3 +195,7 @@ endmenu
 menu "Kernel continous integration configuration"
 source "kconfigs/Kconfig.kernel-ci"
 endmenu
+
+menu "Ansible Configuration"
+source "kconfigs/Kconfig.ansible_cfg"
+endmenu
diff --git a/playbooks/ansible_cfg.yml b/playbooks/ansible_cfg.yml
new file mode 100644
index 0000000000000000000000000000000000000000..872f2ee48d29377cd07cf8f75c37d7e32734d914
--- /dev/null
+++ b/playbooks/ansible_cfg.yml
@@ -0,0 +1,5 @@
+---
+- name: Ansible Configuration Role
+  hosts: localhost
+  roles:
+    - role: ansible_cfg
diff --git a/playbooks/roles/ansible_cfg/defaults/main.yml b/playbooks/roles/ansible_cfg/defaults/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c4787e5b1bb6d792b680f674dd6eac45a9860883
--- /dev/null
+++ b/playbooks/roles/ansible_cfg/defaults/main.yml
@@ -0,0 +1,10 @@
+---
+ansible_cfg_deprecation_warnings: true
+ansible_cfg_callback_plugin_string: debug
+ansible_cfg_callback_plugin_check_mode_markers: false
+ansible_cfg_callback_plugin_display_failed_stderr: false
+ansible_cfg_callback_plugin_display_ok_hosts: true
+ansible_cfg_callback_plugin_display_skipped_hosts: true
+ansible_cfg_callback_plugin_show_custom_stats: false
+ansible_cfg_callback_plugin_show_per_host_start: false
+ansible_cfg_callback_plugin_show_task_path_on_failure: false
diff --git a/playbooks/roles/ansible_cfg/tasks/main.yml b/playbooks/roles/ansible_cfg/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a85d525f21b1a8968e4da73df6882f57b83c32d2
--- /dev/null
+++ b/playbooks/roles/ansible_cfg/tasks/main.yml
@@ -0,0 +1,18 @@
+---
+- name: Import optional extra_args file
+  ansible.builtin.include_vars:
+    file: "{{ item }}"
+  with_first_found:
+    - files:
+        - "../extra_vars.yml"
+        - "../extra_vars.yaml"
+        - "../extra_vars.json"
+      skip: true
+  failed_when: false
+  tags: vars
+
+- name: Generate kdevops ansible.cfg
+  ansible.builtin.template:
+    src: "ansible.cfg.j2"
+    dest: "{{ topdir_path }}/ansible.cfg"
+    mode: '0755'
diff --git a/playbooks/roles/ansible_cfg/templates/ansible.cfg.j2 b/playbooks/roles/ansible_cfg/templates/ansible.cfg.j2
new file mode 100644
index 0000000000000000000000000000000000000000..e13931b5ce97807365a0e0caa0db921a3b2930d7
--- /dev/null
+++ b/playbooks/roles/ansible_cfg/templates/ansible.cfg.j2
@@ -0,0 +1,14 @@
+[defaults]
+deprecation_warnings = {{ ansible_cfg_deprecation_warnings }}
+stdout_callback = {{ ansible_cfg_callback_plugin_string }}
+check_mode_markers = {{ ansible_cfg_callback_plugin_check_mode_markers }}
+display_failed_stderr = {{ ansible_cfg_callback_plugin_display_failed_stderr }}
+display_ok_hosts = {{ ansible_cfg_callback_plugin_display_ok_hosts }}
+display_skipped_hosts = {{ ansible_cfg_callback_plugin_display_skipped_hosts }}
+show_custom_stats = {{ ansible_cfg_callback_plugin_show_custom_stats }}
+show_per_host_start = {{ ansible_cfg_callback_plugin_show_per_host_start }}
+show_task_path_on_failure = {{ ansible_cfg_callback_plugin_show_task_path_on_failure }}
+{% if ansible_facts['distribution'] == 'openSUSE' %}
+[connection]
+retries = {{ ansible_cfg_reconnection_retries }}
+{% endif %}
