diff --git a/ansible/inventory/all-in-one b/ansible/inventory/all-in-one
index ab6eceeb2772a77e26ac20e25033d4e6abd4393f..1c3fe57c2659f5db581667a8c26ac6819ee75922 100644
--- a/ansible/inventory/all-in-one
+++ b/ansible/inventory/all-in-one
@@ -93,6 +93,9 @@ nova
 [nova-scheduler:children]
 nova
 
+[nova-spicehtml5proxy:children]
+nova
+
 # Neutron
 [neutron-server:children]
 neutron
diff --git a/ansible/inventory/multinode b/ansible/inventory/multinode
index 63b9af66fa3b77d8a43777270f4025414703c020..847fd8e50331c10376f185c0ba1b750680fa8b35 100644
--- a/ansible/inventory/multinode
+++ b/ansible/inventory/multinode
@@ -102,6 +102,9 @@ nova
 [nova-scheduler:children]
 nova
 
+[nova-spicehtml5proxy:children]
+nova
+
 # Neutron
 [neutron-server:children]
 control
diff --git a/ansible/roles/haproxy/templates/haproxy.cfg.j2 b/ansible/roles/haproxy/templates/haproxy.cfg.j2
index aa214f73798d98d2a2396e69add33357d69cfd7f..85f7a11a69580d90aa652b4ccfffbf40f0122448 100644
--- a/ansible/roles/haproxy/templates/haproxy.cfg.j2
+++ b/ansible/roles/haproxy/templates/haproxy.cfg.j2
@@ -89,11 +89,19 @@ listen nova_metadata
   server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + api_interface]['ipv4']['address'] }}:{{ nova_metadata_port }} check inter 2000 rise 2 fall 5
 {% endfor %}
 
+{% if nova_console == 'novnc' %}
 listen nova_novncproxy
   bind {{ kolla_internal_address }}:{{ nova_novncproxy_port }}
 {% for host in groups['nova-novncproxy'] %}
   server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + api_interface]['ipv4']['address'] }}:{{ nova_novncproxy_port }} check inter 2000 rise 2 fall 5
 {% endfor %}
+{% elif nova_console == 'spice' %}
+listen nova_spicehtml5proxy
+  bind {{ kolla_internal_address }}:{{ nova_spicehtml5proxy_port }}
+{% for host in groups['nova-spicehtml5proxy'] %}
+  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + api_interface]['ipv4']['address'] }}:{{ nova_spicehtml5proxy_port }} check inter 2000 rise 2 fall 5
+{% endfor %}
+{% endif %}
 {% endif %}
 
 {% if enable_neutron | bool %}
diff --git a/ansible/roles/nova/defaults/main.yml b/ansible/roles/nova/defaults/main.yml
index 2e88679498df8c5b103b2af3372fcf65a847a2de..11365dc22d7796f8012c1e452d7a3dc6b838e4a5 100644
--- a/ansible/roles/nova/defaults/main.yml
+++ b/ansible/roles/nova/defaults/main.yml
@@ -41,6 +41,10 @@ nova_novncproxy_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{
 nova_novncproxy_tag: "{{ openstack_release }}"
 nova_novncproxy_image_full: "{{ nova_novncproxy_image }}:{{ nova_novncproxy_tag }}"
 
+nova_spicehtml5proxy_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ kolla_install_type }}-nova-spicehtml5proxy"
+nova_spicehtml5proxy_tag: "{{ openstack_release }}"
+nova_spicehtml5proxy_image_full: "{{ nova_spicehtml5proxy_image }}:{{ nova_spicehtml5proxy_tag }}"
+
 nova_scheduler_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ kolla_install_type }}-nova-scheduler"
 nova_scheduler_tag: "{{ openstack_release }}"
 nova_scheduler_image_full: "{{ nova_scheduler_image }}:{{ nova_scheduler_tag }}"
diff --git a/ansible/roles/nova/tasks/config.yml b/ansible/roles/nova/tasks/config.yml
index 29f308e5dfe3c9bc6787bb001c1da46f59502e1f..d72c0dbf99f90582ba4d1e0187f9ef466ae571de 100644
--- a/ansible/roles/nova/tasks/config.yml
+++ b/ansible/roles/nova/tasks/config.yml
@@ -161,13 +161,47 @@
       - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
       - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
     config_dest: "{{ node_config_directory }}/{{ service_name }}/nova.conf"
-  when: inventory_hostname in groups['nova-novncproxy']
+  when:
+    - inventory_hostname in groups['nova-novncproxy']
+    - nova_console == 'novnc'
 
 - name: Copying Nova Novncproxy JSON configuration file
   template:
     src: "roles/nova/templates/nova-novncproxy.json.j2"
     dest: "{{ node_config_directory }}/nova-novncproxy/config.json"
-  when: inventory_hostname in groups['nova-novncproxy']
+  when:
+    - inventory_hostname in groups['nova-novncproxy']
+    - nova_console == 'novnc'
+
+- include: ../../config.yml
+  vars:
+    service_name: "nova-spicehtml5proxy"
+    config_source:
+      - "roles/{{ project_name }}/templates/nova.conf.j2"
+      - "/etc/kolla/config/global.conf"
+      - "/etc/kolla/config/database.conf"
+      - "/etc/kolla/config/messaging.conf"
+      - "/etc/kolla/config/{{ project_name }}.conf"
+      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
+    config_template_dest:
+      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
+      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
+      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
+      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
+      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
+      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
+    config_dest: "{{ node_config_directory }}/{{ service_name }}/nova.conf"
+  when:
+    - inventory_hostname in groups['nova-spicehtml5proxy']
+    - nova_console == 'spice'
+
+- name: Copying Nova spicehtml5proxy JSON configuration file
+  template:
+    src: "roles/nova/templates/nova-spicehtml5proxy.json.j2"
+    dest: "{{ node_config_directory }}/nova-spicehtml5proxy/config.json"
+  when:
+    - inventory_hostname in groups['nova-spicehtml5proxy']
+    - nova_console == 'spice'
 
 - name: Ensuring config directory exists
   file:
diff --git a/ansible/roles/nova/tasks/start.yml b/ansible/roles/nova/tasks/start.yml
index 0d8c22cc8423505f69d3df0e617dff19a6fbff64..84bf107772f6239a970a47434b2d5eeb05a2e0bb 100644
--- a/ansible/roles/nova/tasks/start.yml
+++ b/ansible/roles/nova/tasks/start.yml
@@ -110,7 +110,9 @@
       - "{{ node_config_directory }}/nova-novncproxy/:{{ container_config_directory }}/:ro"
     env:
       KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
-  when: inventory_hostname in groups['nova-novncproxy']
+  when:
+    - inventory_hostname in groups['nova-novncproxy']
+    - nova_console == 'novnc'
 
 - name: Starting Nova-scheduler container
   docker:
@@ -133,6 +135,29 @@
       KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
   when: inventory_hostname in groups['nova-scheduler']
 
+- name: Starting Nova-spicehtml5proxy container
+  docker:
+    tty: True
+    net: host
+    pull: "{{ docker_pull_policy }}"
+    restart_policy: "{{ docker_restart_policy }}"
+    restart_policy_retry: "{{ docker_restart_policy_retry }}"
+    state: reloaded
+    registry: "{{ docker_registry }}"
+    username: "{{ docker_registry_username }}"
+    password: "{{ docker_registry_password }}"
+    insecure_registry: "{{ docker_insecure_registry }}"
+    name: nova_spicehtml5proxy
+    image: "{{ nova_spicehtml5proxy_image_full }}"
+    volumes:
+      - "/var/lib/kolla/dev/log:/dev/log"
+      - "{{ node_config_directory }}/nova-spicehtml5proxy/:{{ container_config_directory }}/:ro"
+    env:
+      KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
+  when:
+    - inventory_hostname in groups['nova-spicehtml5proxy']
+    - nova_console == 'spice'
+
 - name: Starting Nova-compute container
   docker:
     tty: True
diff --git a/ansible/roles/nova/templates/nova.conf.j2 b/ansible/roles/nova/templates/nova.conf.j2
index 6192a2a6e25f415800a2b4ae53b18ac642d7ab51..eae040fdf597462ffafb09356205daca4b39b6e6 100644
--- a/ansible/roles/nova/templates/nova.conf.j2
+++ b/ansible/roles/nova/templates/nova.conf.j2
@@ -32,6 +32,17 @@ linuxnet_interface_driver = nova.network.linux_net.BridgeInterfaceDriver
 
 allow_resize_to_same_host = true
 
+{% if enable_ironic | bool %}
+compute_driver = nova.virt.ironic.IronicDriver
+scheduler_host_manager = nova.scheduler.ironic_host_manager.IronicHostManager
+ram_allocation_ratio = 1.0
+reserved_host_memory_mb = 0
+compute_manager = ironic.nova.compute.manager.ClusteredComputeManager
+scheduler_use_baremetal_filters = True
+{% else %}
+compute_driver = libvirt.LibvirtDriver
+{% endif %}
+
 memcached_servers = {% for host in groups['memcached'] %}{{ hostvars[host]['ansible_' + api_interface]['ipv4']['address'] }}:{{ memcached_port }}{% if not loop.last %},{% endif %}{% endfor %}
 
 
@@ -39,14 +50,14 @@ memcached_servers = {% for host in groups['memcached'] %}{{ hostvars[host]['ansi
 my_ip = {{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}
 
 {% if nova_console == 'novnc' %}
+novncproxy_host = {{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}
+novncproxy_port = {{ nova_novncproxy_port }}
 [vnc]
 vncserver_listen = {{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}
 vncserver_proxyclient_address = {{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}
 {% if inventory_hostname in groups['compute'] %}
 novncproxy_base_url = http://{{ kolla_internal_address }}:{{ nova_novncproxy_port }}/vnc_auto.html
 {% endif %}
-novncproxy_host = {{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}
-novncproxy_port = {{ nova_novncproxy_port }}
 {% elif nova_console == 'spice' %}
 [vnc]
 # We have to turn off vnc to use spice
@@ -58,18 +69,7 @@ server_proxyclient_address = {{ hostvars[inventory_hostname]['ansible_' + api_in
 html5proxy_base_url = http://{{ kolla_internal_address }}:{{ nova_spicehtml5proxy_port }}/spice_auto.html
 {% endif %}
 html5proxy_host = {{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}
-html5proxy_port = {{ nova_html5proxy_port }}
-{% endif %}
-
-{% if enable_ironic | bool %}
-compute_driver = nova.virt.ironic.IronicDriver
-scheduler_host_manager = nova.scheduler.ironic_host_manager.IronicHostManager
-ram_allocation_ratio = 1.0
-reserved_host_memory_mb = 0
-compute_manager = ironic.nova.compute.manager.ClusteredComputeManager
-scheduler_use_baremetal_filters = True
-{% else %}
-compute_driver = libvirt.LibvirtDriver
+html5proxy_port = {{ nova_spicehtml5proxy_port }}
 {% endif %}
 
 {% if enable_ironic | bool %}
diff --git a/etc/kolla/config/nova/nova-spicehtml5proxy.conf b/etc/kolla/config/nova/nova-spicehtml5proxy.conf
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391