diff --git a/ansible/roles/common/defaults/main.yml b/ansible/roles/common/defaults/main.yml
index 937c4f2789..8c41d59af1 100644
--- a/ansible/roles/common/defaults/main.yml
+++ b/ansible/roles/common/defaults/main.yml
@@ -79,6 +79,7 @@ kolla_toolbox_default_volumes:
   - "/dev/:/dev/"
   - "/run/:/run/:shared"
   - "kolla_logs:/var/log/kolla/"
+  - "/run/openvswitch:/run/openvswitch:shared"
 cron_default_volumes:
   - "{{ node_config_directory }}/cron/:{{ container_config_directory }}/:ro"
   - "/etc/localtime:/etc/localtime:ro"
diff --git a/ansible/roles/ovn/tasks/bootstrap.yml b/ansible/roles/ovn/tasks/bootstrap.yml
index d43e7affba..99d65b6f01 100644
--- a/ansible/roles/ovn/tasks/bootstrap.yml
+++ b/ansible/roles/ovn/tasks/bootstrap.yml
@@ -1,45 +1,33 @@
 ---
 - name: Create br-int bridge on OpenvSwitch
   become: true
-  command: >
-    docker exec openvswitch_vswitchd ovs-vsctl --may-exist
-    add-br br-int -- set Bridge br-int fail-mode=secure
-  when: inventory_hostname in groups['ovn-controller']
+  kolla_toolbox:
+    user: root
+    module_name: openvswitch_bridge
+    module_args:
+      bridge: br-int
+      state: present
+      fail_mode: secure
 
-- name: Set OVN encapsulation settings
-  become: true
-  command: >
-    docker exec openvswitch_vswitchd ovs-vsctl set Open_vSwitch .
-    external_ids:ovn-encap-ip={{ tunnel_interface_address }}
-    external_ids:ovn-encap-type=geneve
-    external_ids:ovn-remote={{ ovn_sb_connection }}
-  when: inventory_hostname in groups['ovn-controller']
-
-- name: Set OVN bridge mappings
+- name: Configure OVN in OVSDB
   vars:
     ovn_mappings: "{% for bridge in neutron_bridge_name.split(',') %}physnet{{ loop.index0 + 1 }}:{{ bridge }}{% if not loop.last %},{% endif %}{% endfor %}"
+    ovn_cms_opts: "{{ 'enable-chassis-as-gw' if inventory_hostname in groups['ovn-controller-network'] else '' }}"
   become: true
-  command: docker exec openvswitch_vswitchd ovs-vsctl set Open_vSwitch . external_ids:ovn-bridge-mappings={{ ovn_mappings }}
-  when:
-    - inventory_hostname in groups["ovn-controller-network"]
-      or (inventory_hostname in groups["ovn-controller-compute"] and computes_need_external_bridge | bool)
-
-- name: Enable chassis as gateway
-  become: true
-  command: docker exec openvswitch_vswitchd ovs-vsctl set Open_vSwitch . external-ids:ovn-cms-options="enable-chassis-as-gw"
-  when: inventory_hostname in groups["ovn-controller-network"]
-
-- name: Ensure chassis as gateway is disabled where required
-  become: true
-  command: docker exec openvswitch_vswitchd ovs-vsctl remove Open_vSwitch . external-ids ovn-cms-options
-  when:
-    - inventory_hostname in groups["openvswitch"]
-    - inventory_hostname not in groups["ovn-controller-network"]
-
-- name: Set OVN remote probe interval
-  become: true
-  command: >
-    docker exec openvswitch_vswitchd ovs-vsctl set Open_vSwitch .
-    external_ids:ovn-remote-probe-interval={{ ovn_remote_probe_interval }}
-  when:
-    - inventory_hostname in groups["ovn-controller"]
+  kolla_toolbox:
+    user: root
+    module_name: openvswitch_db
+    module_args:
+      table: Open_vSwitch
+      record: .
+      col: external_ids
+      key: "{{ item.name }}"
+      value: "{{ item.value }}"
+      state: "{{ item.state | default('present') }}"
+  loop:
+    - { name: ovn-encap-ip, value: "{{ tunnel_interface_address }}" }
+    - { name: ovn-encap-type, value: geneve }
+    - { name: ovn-remote, value: "{{ ovn_sb_connection }}" }
+    - { name: ovn-remote-probe-interval, value: "{{ ovn_remote_probe_interval }}" }
+    - { name: ovn-bridge-mappings, value: "{{ ovn_mappings if ovn_mappings != '' else omit }}", state: "{{ 'present' if (inventory_hostname in groups['ovn-controller-network'] or computes_need_external_bridge | bool) else 'absent' }}" }
+    - { name: ovn-cms-options, value: "{{ ovn_cms_opts }}", state: "{{ 'present' if ovn_cms_opts != '' else 'absent' }}" }
diff --git a/ansible/roles/ovn/tasks/deploy.yml b/ansible/roles/ovn/tasks/deploy.yml
index d0b36cb78b..3356de912e 100644
--- a/ansible/roles/ovn/tasks/deploy.yml
+++ b/ansible/roles/ovn/tasks/deploy.yml
@@ -4,6 +4,7 @@
 - import_tasks: check-containers.yml
 
 - import_tasks: bootstrap.yml
+  when: inventory_hostname in groups['ovn-controller']
 
 - name: Flush handlers
   meta: flush_handlers
diff --git a/ansible/roles/ovn/tasks/upgrade.yml b/ansible/roles/ovn/tasks/upgrade.yml
index d0b36cb78b..49edff81e3 100644
--- a/ansible/roles/ovn/tasks/upgrade.yml
+++ b/ansible/roles/ovn/tasks/upgrade.yml
@@ -3,7 +3,5 @@
 
 - import_tasks: check-containers.yml
 
-- import_tasks: bootstrap.yml
-
 - name: Flush handlers
   meta: flush_handlers