From 9755c924bee5976a894aba4ff2d438899c1bcc45 Mon Sep 17 00:00:00 2001
From: Mark Goddard <mark@stackhpc.com>
Date: Thu, 9 Jan 2020 17:03:28 +0000
Subject: [PATCH] CentOS 8: Support variable image tag suffix

For the CentOS 7 to 8 transition, we will have a period where both
CentOS 7 and 8 images are available. We differentiate these images via a
tag - the CentOS 8 images will have a tag of train-centos8 (or
master-centos8 temporarily).

To achieve this, and maintain backwards compatibility for the
openstack_release variable, we introduce a new 'openstack_tag' variable.
This variable is based on openstack_release, but has a suffix of
'openstack_tag_suffix', which is empty except on CentOS 8 where it has a
value of '-centos8'.

Change-Id: I12ce4661afb3c255136cdc1aabe7cbd25560d625
Partially-Implements: blueprint centos-rhel-8
---
 ansible/group_vars/all.yml                             | 4 ++++
 ansible/roles/aodh/defaults/main.yml                   | 2 +-
 ansible/roles/barbican/defaults/main.yml               | 2 +-
 ansible/roles/bifrost/defaults/main.yml                | 2 +-
 ansible/roles/blazar/defaults/main.yml                 | 2 +-
 ansible/roles/ceilometer/defaults/main.yml             | 2 +-
 ansible/roles/ceph/defaults/main.yml                   | 2 +-
 ansible/roles/chrony/defaults/main.yml                 | 2 +-
 ansible/roles/cinder/defaults/main.yml                 | 2 +-
 ansible/roles/cloudkitty/defaults/main.yml             | 2 +-
 ansible/roles/collectd/defaults/main.yml               | 2 +-
 ansible/roles/common/defaults/main.yml                 | 2 +-
 ansible/roles/congress/defaults/main.yml               | 2 +-
 ansible/roles/cyborg/defaults/main.yml                 | 2 +-
 ansible/roles/designate/defaults/main.yml              | 2 +-
 ansible/roles/elasticsearch/defaults/main.yml          | 4 ++--
 ansible/roles/etcd/defaults/main.yml                   | 2 +-
 ansible/roles/freezer/defaults/main.yml                | 2 +-
 ansible/roles/glance/defaults/main.yml                 | 2 +-
 ansible/roles/gnocchi/defaults/main.yml                | 2 +-
 ansible/roles/grafana/defaults/main.yml                | 2 +-
 ansible/roles/haproxy/defaults/main.yml                | 4 ++--
 ansible/roles/heat/defaults/main.yml                   | 2 +-
 ansible/roles/horizon/defaults/main.yml                | 2 +-
 ansible/roles/influxdb/defaults/main.yml               | 2 +-
 ansible/roles/ironic/defaults/main.yml                 | 2 +-
 ansible/roles/iscsi/defaults/main.yml                  | 2 +-
 ansible/roles/kafka/defaults/main.yml                  | 2 +-
 ansible/roles/karbor/defaults/main.yml                 | 2 +-
 ansible/roles/keystone/defaults/main.yml               | 2 +-
 ansible/roles/kibana/defaults/main.yml                 | 2 +-
 ansible/roles/kuryr/defaults/main.yml                  | 2 +-
 ansible/roles/magnum/defaults/main.yml                 | 2 +-
 ansible/roles/manila/defaults/main.yml                 | 2 +-
 ansible/roles/mariadb/defaults/main.yml                | 4 ++--
 ansible/roles/masakari/defaults/main.yml               | 2 +-
 ansible/roles/memcached/defaults/main.yml              | 2 +-
 ansible/roles/mistral/defaults/main.yml                | 2 +-
 ansible/roles/monasca/defaults/main.yml                | 2 +-
 ansible/roles/mongodb/defaults/main.yml                | 2 +-
 ansible/roles/multipathd/defaults/main.yml             | 2 +-
 ansible/roles/murano/defaults/main.yml                 | 2 +-
 ansible/roles/neutron/defaults/main.yml                | 2 +-
 ansible/roles/nova-cell/defaults/main.yml              | 2 +-
 ansible/roles/nova/defaults/main.yml                   | 2 +-
 ansible/roles/octavia/defaults/main.yml                | 2 +-
 ansible/roles/openvswitch/defaults/main.yml            | 2 +-
 ansible/roles/ovs-dpdk/defaults/main.yml               | 2 +-
 ansible/roles/panko/defaults/main.yml                  | 2 +-
 ansible/roles/placement/defaults/main.yml              | 2 +-
 ansible/roles/prometheus/defaults/main.yml             | 2 +-
 ansible/roles/qdrouterd/defaults/main.yml              | 2 +-
 ansible/roles/qinling/defaults/main.yml                | 2 +-
 ansible/roles/rabbitmq/defaults/main.yml               | 2 +-
 ansible/roles/rally/defaults/main.yml                  | 2 +-
 ansible/roles/redis/defaults/main.yml                  | 4 ++--
 ansible/roles/sahara/defaults/main.yml                 | 2 +-
 ansible/roles/searchlight/defaults/main.yml            | 2 +-
 ansible/roles/senlin/defaults/main.yml                 | 2 +-
 ansible/roles/skydive/defaults/main.yml                | 4 ++--
 ansible/roles/solum/defaults/main.yml                  | 2 +-
 ansible/roles/storm/defaults/main.yml                  | 2 +-
 ansible/roles/swift/defaults/main.yml                  | 2 +-
 ansible/roles/tacker/defaults/main.yml                 | 2 +-
 ansible/roles/telegraf/defaults/main.yml               | 2 +-
 ansible/roles/tempest/defaults/main.yml                | 2 +-
 ansible/roles/trove/defaults/main.yml                  | 2 +-
 ansible/roles/vitrage/defaults/main.yml                | 2 +-
 ansible/roles/vmtp/defaults/main.yml                   | 2 +-
 ansible/roles/watcher/defaults/main.yml                | 2 +-
 ansible/roles/zookeeper/defaults/main.yml              | 2 +-
 ansible/roles/zun/defaults/main.yml                    | 2 +-
 etc/kolla/globals.yml                                  | 6 ++++++
 releasenotes/notes/openstack-tag-bfe4e862ade8549b.yaml | 8 ++++++++
 tests/templates/globals-default.j2                     | 6 ++----
 75 files changed, 96 insertions(+), 80 deletions(-)
 create mode 100644 releasenotes/notes/openstack-tag-bfe4e862ade8549b.yaml

diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml
index fecbaa9cf4..bfd84de9e3 100644
--- a/ansible/group_vars/all.yml
+++ b/ansible/group_vars/all.yml
@@ -483,6 +483,10 @@ admin_protocol: "{{ 'https' if kolla_enable_tls_internal | bool else 'http' }}"
 # OpenStack options
 ####################
 openstack_release: "master"
+# Docker image tag used by default.
+openstack_tag: "{{ openstack_release ~ openstack_tag_suffix }}"
+# TODO(mgoddard): Set to an empty string when CentOS 7 is no longer supported.
+openstack_tag_suffix: "{{ '' if kolla_base_distro != 'centos' or ansible_distribution_major_version == '7' else  '-centos8' }}"
 openstack_logging_debug: "False"
 
 openstack_region_name: "RegionOne"
diff --git a/ansible/roles/aodh/defaults/main.yml b/ansible/roles/aodh/defaults/main.yml
index 1d30a1ae5d..b36722d18d 100644
--- a/ansible/roles/aodh/defaults/main.yml
+++ b/ansible/roles/aodh/defaults/main.yml
@@ -75,7 +75,7 @@ aodh_enabled_notification_topics: "{{ aodh_notification_topics | selectattr('ena
 # Docker
 ####################
 aodh_install_type: "{{ kolla_install_type }}"
-aodh_tag: "{{ openstack_release }}"
+aodh_tag: "{{ openstack_tag }}"
 
 aodh_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ aodh_install_type }}-aodh-api"
 aodh_api_tag: "{{ aodh_tag }}"
diff --git a/ansible/roles/barbican/defaults/main.yml b/ansible/roles/barbican/defaults/main.yml
index 9ea7f5ae62..8181b95e31 100644
--- a/ansible/roles/barbican/defaults/main.yml
+++ b/ansible/roles/barbican/defaults/main.yml
@@ -50,7 +50,7 @@ barbican_database_address: "{{ database_address | put_address_in_context('url')
 # Docker
 ####################
 barbican_install_type: "{{ kolla_install_type }}"
-barbican_tag: "{{ openstack_release }}"
+barbican_tag: "{{ openstack_tag }}"
 
 barbican_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ barbican_install_type }}-barbican-api"
 barbican_api_tag: "{{ barbican_tag }}"
diff --git a/ansible/roles/bifrost/defaults/main.yml b/ansible/roles/bifrost/defaults/main.yml
index cd963b70c8..6be3d6cf83 100644
--- a/ansible/roles/bifrost/defaults/main.yml
+++ b/ansible/roles/bifrost/defaults/main.yml
@@ -5,7 +5,7 @@ project_name: "bifrost"
 # Docker
 ####################
 bifrost_install_type: "{{ kolla_install_type }}"
-bifrost_tag: "{{ openstack_release }}"
+bifrost_tag: "{{ openstack_tag }}"
 
 bifrost_deploy_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ bifrost_install_type }}-bifrost-deploy"
 bifrost_deploy_tag: "{{ bifrost_tag }}"
diff --git a/ansible/roles/blazar/defaults/main.yml b/ansible/roles/blazar/defaults/main.yml
index 4343348641..88ff8c66b6 100644
--- a/ansible/roles/blazar/defaults/main.yml
+++ b/ansible/roles/blazar/defaults/main.yml
@@ -46,7 +46,7 @@ blazar_database_address: "{{ database_address | put_address_in_context('url') }}
 # Docker
 ####################
 blazar_install_type: "{{ kolla_install_type }}"
-blazar_tag: "{{ openstack_release }}"
+blazar_tag: "{{ openstack_tag }}"
 
 blazar_manager_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ blazar_install_type }}-blazar-manager"
 blazar_manager_tag: "{{ blazar_tag }}"
diff --git a/ansible/roles/ceilometer/defaults/main.yml b/ansible/roles/ceilometer/defaults/main.yml
index 327b736f58..842f831eb0 100644
--- a/ansible/roles/ceilometer/defaults/main.yml
+++ b/ansible/roles/ceilometer/defaults/main.yml
@@ -37,7 +37,7 @@ ceilometer_services:
 # Docker
 ####################
 ceilometer_install_type: "{{ kolla_install_type }}"
-ceilometer_tag: "{{ openstack_release }}"
+ceilometer_tag: "{{ openstack_tag }}"
 
 ceilometer_notification_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ ceilometer_install_type }}-ceilometer-notification"
 ceilometer_notification_tag: "{{ ceilometer_tag }}"
diff --git a/ansible/roles/ceph/defaults/main.yml b/ansible/roles/ceph/defaults/main.yml
index e54fc224cf..a1d407af7e 100644
--- a/ansible/roles/ceph/defaults/main.yml
+++ b/ansible/roles/ceph/defaults/main.yml
@@ -22,7 +22,7 @@ ceph_services:
 # Docker
 ####################
 ceph_install_type: "{{ kolla_install_type }}"
-ceph_tag: "{{ openstack_release }}"
+ceph_tag: "{{ openstack_tag }}"
 
 ceph_mds_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ ceph_install_type }}-ceph-mds"
 ceph_mds_tag: "{{ ceph_tag }}"
diff --git a/ansible/roles/chrony/defaults/main.yml b/ansible/roles/chrony/defaults/main.yml
index 0c70003c96..a6de54e3c4 100644
--- a/ansible/roles/chrony/defaults/main.yml
+++ b/ansible/roles/chrony/defaults/main.yml
@@ -18,7 +18,7 @@ chrony_bindaddress: "{{ kolla_internal_vip_address }}"
 ####################
 chrony_install_type: "{{ kolla_install_type }}"
 chrony_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ chrony_install_type }}-chrony"
-chrony_tag: "{{ openstack_release }}"
+chrony_tag: "{{ openstack_tag }}"
 chrony_image_full: "{{ chrony_image }}:{{ chrony_tag }}"
 
 chrony_dimensions: "{{ default_container_dimensions }}"
diff --git a/ansible/roles/cinder/defaults/main.yml b/ansible/roles/cinder/defaults/main.yml
index 36c8d3c073..1957430768 100644
--- a/ansible/roles/cinder/defaults/main.yml
+++ b/ansible/roles/cinder/defaults/main.yml
@@ -101,7 +101,7 @@ cinder_database_address: "{{ database_address | put_address_in_context('url') }}
 # Docker
 ####################
 cinder_install_type: "{{ kolla_install_type }}"
-cinder_tag: "{{ openstack_release }}"
+cinder_tag: "{{ openstack_tag }}"
 
 cinder_volume_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ cinder_install_type }}-cinder-volume"
 cinder_volume_tag: "{{ cinder_tag }}"
diff --git a/ansible/roles/cloudkitty/defaults/main.yml b/ansible/roles/cloudkitty/defaults/main.yml
index d23ec2a121..97c1736249 100644
--- a/ansible/roles/cloudkitty/defaults/main.yml
+++ b/ansible/roles/cloudkitty/defaults/main.yml
@@ -41,7 +41,7 @@ cloudkitty_database_address: "{{ database_address | put_address_in_context('url'
 # Docker
 ####################
 cloudkitty_install_type: "{{ kolla_install_type }}"
-cloudkitty_tag: "{{ openstack_release }}"
+cloudkitty_tag: "{{ openstack_tag }}"
 
 cloudkitty_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ cloudkitty_install_type }}-cloudkitty-api"
 cloudkitty_api_tag: "{{ cloudkitty_tag }}"
diff --git a/ansible/roles/collectd/defaults/main.yml b/ansible/roles/collectd/defaults/main.yml
index 1957c9270f..134de1b117 100644
--- a/ansible/roles/collectd/defaults/main.yml
+++ b/ansible/roles/collectd/defaults/main.yml
@@ -16,7 +16,7 @@ collectd_services:
 ####################
 collectd_install_type: "{{ kolla_install_type }}"
 collectd_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ collectd_install_type }}-collectd"
-collectd_tag: "{{ openstack_release }}"
+collectd_tag: "{{ openstack_tag }}"
 collectd_image_full: "{{ collectd_image }}:{{ collectd_tag }}"
 
 collectd_dimensions: "{{ default_container_dimensions }}"
diff --git a/ansible/roles/common/defaults/main.yml b/ansible/roles/common/defaults/main.yml
index 4d2b46041c..1b947b0caf 100644
--- a/ansible/roles/common/defaults/main.yml
+++ b/ansible/roles/common/defaults/main.yml
@@ -49,7 +49,7 @@ fluentd_elasticsearch_ssl_verify: "true"
 # Docker
 ####################
 common_install_type: "{{ kolla_install_type }}"
-common_tag: "{{ openstack_release }}"
+common_tag: "{{ openstack_tag }}"
 
 cron_dimensions: "{{ default_container_dimensions }}"
 kolla_toolbox_dimensions: "{{ default_container_dimensions }}"
diff --git a/ansible/roles/congress/defaults/main.yml b/ansible/roles/congress/defaults/main.yml
index 0837ad7d94..b1251ba423 100644
--- a/ansible/roles/congress/defaults/main.yml
+++ b/ansible/roles/congress/defaults/main.yml
@@ -48,7 +48,7 @@ congress_database_address: "{{ database_address | put_address_in_context('url')
 # Docker
 ####################
 congress_install_type: "{{ kolla_install_type }}"
-congress_tag: "{{ openstack_release }}"
+congress_tag: "{{ openstack_tag }}"
 
 congress_policy_engine_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ congress_install_type }}-congress-policy-engine"
 congress_policy_engine_tag: "{{ congress_tag }}"
diff --git a/ansible/roles/cyborg/defaults/main.yml b/ansible/roles/cyborg/defaults/main.yml
index c2c79b3145..8ac32a075e 100644
--- a/ansible/roles/cyborg/defaults/main.yml
+++ b/ansible/roles/cyborg/defaults/main.yml
@@ -35,7 +35,7 @@ cyborg_database_address: "{{ database_address | put_address_in_context('url') }}
 # Docker
 ####################
 cyborg_install_type: "{{ kolla_install_type }}"
-cyborg_tag: "{{ openstack_release }}"
+cyborg_tag: "{{ openstack_tag }}"
 
 cyborg_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ cyborg_install_type }}-cyborg-api"
 cyborg_api_tag: "{{ cyborg_tag }}"
diff --git a/ansible/roles/designate/defaults/main.yml b/ansible/roles/designate/defaults/main.yml
index 162746f620..3c761f1931 100644
--- a/ansible/roles/designate/defaults/main.yml
+++ b/ansible/roles/designate/defaults/main.yml
@@ -78,7 +78,7 @@ designate_database_address: "{{ database_address | put_address_in_context('url')
 # Docker
 ####################
 designate_install_type: "{{ kolla_install_type }}"
-designate_tag: "{{ openstack_release }}"
+designate_tag: "{{ openstack_tag }}"
 
 designate_central_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ designate_install_type }}-designate-central"
 designate_central_tag: "{{ designate_tag }}"
diff --git a/ansible/roles/elasticsearch/defaults/main.yml b/ansible/roles/elasticsearch/defaults/main.yml
index 4d57b85c0d..b8aa2fc960 100644
--- a/ansible/roles/elasticsearch/defaults/main.yml
+++ b/ansible/roles/elasticsearch/defaults/main.yml
@@ -67,11 +67,11 @@ elasticsearch_curator_hard_retention_period_days: 60
 ####################
 elasticsearch_install_type: "{{ kolla_install_type }}"
 elasticsearch_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ elasticsearch_install_type }}-elasticsearch"
-elasticsearch_tag: "{{ openstack_release }}"
+elasticsearch_tag: "{{ openstack_tag }}"
 elasticsearch_image_full: "{{ elasticsearch_image }}:{{ elasticsearch_tag }}"
 
 elasticsearch_curator_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ elasticsearch_install_type }}-elasticsearch-curator"
-elasticsearch_curator_tag: "{{ openstack_release }}"
+elasticsearch_curator_tag: "{{ openstack_tag }}"
 elasticsearch_curator_image_full: "{{ elasticsearch_curator_image }}:{{ elasticsearch_curator_tag }}"
 
 elasticsearch_dimensions: "{{ default_container_dimensions }}"
diff --git a/ansible/roles/etcd/defaults/main.yml b/ansible/roles/etcd/defaults/main.yml
index 3b9d8f05ab..723a2065b8 100644
--- a/ansible/roles/etcd/defaults/main.yml
+++ b/ansible/roles/etcd/defaults/main.yml
@@ -28,7 +28,7 @@ etcd_services:
 ####################
 etcd_install_type: "{{ kolla_install_type }}"
 etcd_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ etcd_install_type }}-etcd"
-etcd_tag: "{{ openstack_release }}"
+etcd_tag: "{{ openstack_tag }}"
 etcd_image_full: "{{ etcd_image }}:{{ etcd_tag }}"
 etcd_dimensions: "{{ default_container_dimensions }}"
 
diff --git a/ansible/roles/freezer/defaults/main.yml b/ansible/roles/freezer/defaults/main.yml
index a701ff82ab..1d558d0604 100644
--- a/ansible/roles/freezer/defaults/main.yml
+++ b/ansible/roles/freezer/defaults/main.yml
@@ -44,7 +44,7 @@ freezer_es_port:
 # Docker
 ####################
 freezer_install_type: "{{ kolla_install_type }}"
-freezer_tag: "{{ openstack_release }}"
+freezer_tag: "{{ openstack_tag }}"
 
 freezer_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ freezer_install_type }}-freezer-api"
 freezer_api_tag: "{{ freezer_tag }}"
diff --git a/ansible/roles/glance/defaults/main.yml b/ansible/roles/glance/defaults/main.yml
index 2c661535c3..4b9cd6177c 100644
--- a/ansible/roles/glance/defaults/main.yml
+++ b/ansible/roles/glance/defaults/main.yml
@@ -106,7 +106,7 @@ haproxy_glance_api_server_timeout: "6h"
 # Docker
 ####################
 glance_install_type: "{{ kolla_install_type }}"
-glance_tag: "{{ openstack_release }}"
+glance_tag: "{{ openstack_tag }}"
 
 glance_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ glance_install_type }}-glance-api"
 glance_api_tag: "{{ glance_tag }}"
diff --git a/ansible/roles/gnocchi/defaults/main.yml b/ansible/roles/gnocchi/defaults/main.yml
index b16c6f0a87..758e1de128 100644
--- a/ansible/roles/gnocchi/defaults/main.yml
+++ b/ansible/roles/gnocchi/defaults/main.yml
@@ -76,7 +76,7 @@ gnocchi_database_address: "{{ database_address | put_address_in_context('url') }
 # Docker
 ####################
 gnocchi_install_type: "{{ kolla_install_type }}"
-gnocchi_tag: "{{ openstack_release }}"
+gnocchi_tag: "{{ openstack_tag }}"
 
 gnocchi_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ gnocchi_install_type }}-gnocchi-api"
 gnocchi_api_tag: "{{ gnocchi_tag }}"
diff --git a/ansible/roles/grafana/defaults/main.yml b/ansible/roles/grafana/defaults/main.yml
index 7589142a53..1a901c56e2 100644
--- a/ansible/roles/grafana/defaults/main.yml
+++ b/ansible/roles/grafana/defaults/main.yml
@@ -59,7 +59,7 @@ grafana_data_sources:
 ##########
 grafana_install_type: "{{ kolla_install_type }}"
 grafana_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ grafana_install_type }}-grafana"
-grafana_tag: "{{ openstack_release }}"
+grafana_tag: "{{ openstack_tag }}"
 grafana_image_full: "{{ grafana_image }}:{{ grafana_tag }}"
 grafana_admin_username: "admin"
 
diff --git a/ansible/roles/haproxy/defaults/main.yml b/ansible/roles/haproxy/defaults/main.yml
index 8b526c4688..d882ede15f 100644
--- a/ansible/roles/haproxy/defaults/main.yml
+++ b/ansible/roles/haproxy/defaults/main.yml
@@ -25,12 +25,12 @@ haproxy_services:
 ####################
 keepalived_install_type: "{{ kolla_install_type }}"
 keepalived_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ keepalived_install_type }}-keepalived"
-keepalived_tag: "{{ openstack_release }}"
+keepalived_tag: "{{ openstack_tag }}"
 keepalived_image_full: "{{ keepalived_image }}:{{ keepalived_tag }}"
 
 haproxy_install_type: "{{ kolla_install_type }}"
 haproxy_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ haproxy_install_type }}-haproxy"
-haproxy_tag: "{{ openstack_release }}"
+haproxy_tag: "{{ openstack_tag }}"
 haproxy_image_full: "{{ haproxy_image }}:{{ haproxy_tag }}"
 
 syslog_server: "{{ api_interface_address }}"
diff --git a/ansible/roles/heat/defaults/main.yml b/ansible/roles/heat/defaults/main.yml
index 02b7a77a4d..cd68e14bde 100644
--- a/ansible/roles/heat/defaults/main.yml
+++ b/ansible/roles/heat/defaults/main.yml
@@ -62,7 +62,7 @@ heat_database_address: "{{ database_address | put_address_in_context('url') }}:{
 # Docker
 ####################
 heat_install_type: "{{ kolla_install_type }}"
-heat_tag: "{{ openstack_release }}"
+heat_tag: "{{ openstack_tag }}"
 
 heat_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ heat_install_type }}-heat-api"
 heat_api_tag: "{{ heat_tag }}"
diff --git a/ansible/roles/horizon/defaults/main.yml b/ansible/roles/horizon/defaults/main.yml
index ab00feeb33..cc26f9a8e3 100644
--- a/ansible/roles/horizon/defaults/main.yml
+++ b/ansible/roles/horizon/defaults/main.yml
@@ -82,7 +82,7 @@ horizon_database_address: "{{ database_address | put_address_in_context('url') }
 ####################
 horizon_install_type: "{{ kolla_install_type }}"
 horizon_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ horizon_install_type }}-horizon"
-horizon_tag: "{{ openstack_release }}"
+horizon_tag: "{{ openstack_tag }}"
 horizon_image_full: "{{ horizon_image }}:{{ horizon_tag }}"
 
 horizon_dimensions: "{{ default_container_dimensions }}"
diff --git a/ansible/roles/influxdb/defaults/main.yml b/ansible/roles/influxdb/defaults/main.yml
index 35b0802d2f..f18f152160 100644
--- a/ansible/roles/influxdb/defaults/main.yml
+++ b/ansible/roles/influxdb/defaults/main.yml
@@ -30,7 +30,7 @@ influxdb_enable_tsi: True
 ####################
 influxdb_install_type: "{{ kolla_install_type }}"
 influxdb_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ influxdb_install_type }}-influxdb"
-influxdb_tag: "{{ openstack_release }}"
+influxdb_tag: "{{ openstack_tag }}"
 influxdb_image_full: "{{ influxdb_image }}:{{ influxdb_tag }}"
 influxdb_dimensions: "{{ default_container_dimensions }}"
 
diff --git a/ansible/roles/ironic/defaults/main.yml b/ansible/roles/ironic/defaults/main.yml
index d28a700082..aa966e2bee 100644
--- a/ansible/roles/ironic/defaults/main.yml
+++ b/ansible/roles/ironic/defaults/main.yml
@@ -92,7 +92,7 @@ ironic_inspector_database_address: "{{ database_address | put_address_in_context
 # Docker
 ####################
 ironic_install_type: "{{ kolla_install_type }}"
-ironic_tag: "{{ openstack_release }}"
+ironic_tag: "{{ openstack_tag }}"
 
 ironic_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ ironic_install_type }}-ironic-api"
 ironic_api_tag: "{{ ironic_tag }}"
diff --git a/ansible/roles/iscsi/defaults/main.yml b/ansible/roles/iscsi/defaults/main.yml
index 9b13ddcf03..7bba9e2c01 100644
--- a/ansible/roles/iscsi/defaults/main.yml
+++ b/ansible/roles/iscsi/defaults/main.yml
@@ -26,7 +26,7 @@ iscsi_services:
 # Docker
 ####################
 iscsi_install_type: "{{ kolla_install_type }}"
-iscsi_tag: "{{ openstack_release }}"
+iscsi_tag: "{{ openstack_tag }}"
 
 iscsid_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ iscsi_install_type }}-iscsid"
 iscsid_tag: "{{ iscsi_tag }}"
diff --git a/ansible/roles/kafka/defaults/main.yml b/ansible/roles/kafka/defaults/main.yml
index 720da8bb2b..f242cece41 100644
--- a/ansible/roles/kafka/defaults/main.yml
+++ b/ansible/roles/kafka/defaults/main.yml
@@ -27,7 +27,7 @@ kafka_broker_count: "{{ groups['kafka'] | length }}"
 ####################
 kafka_install_type: "{{ kolla_install_type }}"
 kafka_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ kafka_install_type }}-kafka"
-kafka_tag: "{{ openstack_release }}"
+kafka_tag: "{{ openstack_tag }}"
 kafka_image_full: "{{ kafka_image }}:{{ kafka_tag }}"
 kafka_dimensions: "{{ default_container_dimensions }}"
 
diff --git a/ansible/roles/karbor/defaults/main.yml b/ansible/roles/karbor/defaults/main.yml
index 6c6c3282b6..83146ec06e 100644
--- a/ansible/roles/karbor/defaults/main.yml
+++ b/ansible/roles/karbor/defaults/main.yml
@@ -48,7 +48,7 @@ karbor_database_address: "{{ database_address | put_address_in_context('url') }}
 # Docker
 ####################
 karbor_install_type: "{{ kolla_install_type }}"
-karbor_tag: "{{ openstack_release }}"
+karbor_tag: "{{ openstack_tag }}"
 
 karbor_protection_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ karbor_install_type }}-karbor-protection"
 karbor_protection_tag: "{{ karbor_tag }}"
diff --git a/ansible/roles/keystone/defaults/main.yml b/ansible/roles/keystone/defaults/main.yml
index a9f992912a..e78768d284 100644
--- a/ansible/roles/keystone/defaults/main.yml
+++ b/ansible/roles/keystone/defaults/main.yml
@@ -71,7 +71,7 @@ keystone_groupname: "keystone"
 # Docker
 ####################
 keystone_install_type: "{{ kolla_install_type }}"
-keystone_tag: "{{ openstack_release }}"
+keystone_tag: "{{ openstack_tag }}"
 
 keystone_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ keystone_install_type }}-keystone"
 keystone_service_tag: "{{ keystone_tag }}"
diff --git a/ansible/roles/kibana/defaults/main.yml b/ansible/roles/kibana/defaults/main.yml
index 3f2559d6b5..004756a90f 100644
--- a/ansible/roles/kibana/defaults/main.yml
+++ b/ansible/roles/kibana/defaults/main.yml
@@ -50,7 +50,7 @@ kibana_default_index_options:
 ####################
 kibana_install_type: "{{ kolla_install_type }}"
 kibana_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ kibana_install_type }}-kibana"
-kibana_tag: "{{ openstack_release }}"
+kibana_tag: "{{ openstack_tag }}"
 kibana_image_full: "{{ kibana_image }}:{{ kibana_tag }}"
 kibana_dimensions: "{{ default_container_dimensions }}"
 
diff --git a/ansible/roles/kuryr/defaults/main.yml b/ansible/roles/kuryr/defaults/main.yml
index 398ca3a75a..ae0529626e 100644
--- a/ansible/roles/kuryr/defaults/main.yml
+++ b/ansible/roles/kuryr/defaults/main.yml
@@ -26,7 +26,7 @@ kuryr_services:
 ####################
 kuryr_install_type: "{{ kolla_install_type }}"
 kuryr_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ kuryr_install_type }}-kuryr-libnetwork"
-kuryr_tag: "{{ openstack_release }}"
+kuryr_tag: "{{ openstack_tag }}"
 kuryr_image_full: "{{ kuryr_image }}:{{ kuryr_tag }}"
 
 kuryr_default_volumes:
diff --git a/ansible/roles/magnum/defaults/main.yml b/ansible/roles/magnum/defaults/main.yml
index 89e4983a3a..ae4f47e05e 100644
--- a/ansible/roles/magnum/defaults/main.yml
+++ b/ansible/roles/magnum/defaults/main.yml
@@ -53,7 +53,7 @@ default_docker_volume_type: ""
 # Docker
 ####################
 magnum_install_type: "{{ kolla_install_type }}"
-magnum_tag: "{{ openstack_release }}"
+magnum_tag: "{{ openstack_tag }}"
 
 magnum_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ magnum_install_type }}-magnum-api"
 magnum_api_tag: "{{ magnum_tag }}"
diff --git a/ansible/roles/manila/defaults/main.yml b/ansible/roles/manila/defaults/main.yml
index e6ca925350..dce3bd8433 100644
--- a/ansible/roles/manila/defaults/main.yml
+++ b/ansible/roles/manila/defaults/main.yml
@@ -72,7 +72,7 @@ manila_database_address: "{{ database_address | put_address_in_context('url') }}
 ## Docker
 #####################
 manila_install_type: "{{ kolla_install_type }}"
-manila_tag: "{{ openstack_release }}"
+manila_tag: "{{ openstack_tag }}"
 
 manila_share_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ manila_install_type }}-manila-share"
 manila_share_tag: "{{ manila_tag }}"
diff --git a/ansible/roles/mariadb/defaults/main.yml b/ansible/roles/mariadb/defaults/main.yml
index ff4a641893..9677efda40 100644
--- a/ansible/roles/mariadb/defaults/main.yml
+++ b/ansible/roles/mariadb/defaults/main.yml
@@ -53,7 +53,7 @@ external_haproxy_members: "{% for host in groups['mariadb'] %}server {{ host }}
 ####################
 mariadb_install_type: "{{ kolla_install_type }}"
 mariadb_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ mariadb_install_type }}-mariadb"
-mariadb_tag: "{{ openstack_release }}"
+mariadb_tag: "{{ openstack_tag }}"
 mariadb_image_full: "{{ mariadb_image }}:{{ mariadb_tag }}"
 mariadb_dimensions: "{{ default_container_dimensions }}"
 
@@ -73,7 +73,7 @@ mariadb_service: "{{ mariadb_services['mariadb'] }}"
 # Backups
 ####################
 mariabackup_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ mariadb_install_type }}-mariadb"
-mariabackup_tag: "{{ openstack_release }}"
+mariabackup_tag: "{{ openstack_tag }}"
 mariabackup_image_full: "{{ mariabackup_image }}:{{ mariabackup_tag }}"
 
 mariadb_backup_host: "{{ groups['mariadb'][0] }}"
diff --git a/ansible/roles/masakari/defaults/main.yml b/ansible/roles/masakari/defaults/main.yml
index 00d1723bb1..72c6592c15 100644
--- a/ansible/roles/masakari/defaults/main.yml
+++ b/ansible/roles/masakari/defaults/main.yml
@@ -48,7 +48,7 @@ masakari_database_address: "{{ database_address | put_address_in_context('url')
 # Docker
 ####################
 masakari_install_type: "{{ kolla_install_type }}"
-masakari_tag: "{{ openstack_release }}"
+masakari_tag: "{{ openstack_tag }}"
 
 masakari_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ masakari_install_type }}-masakari-api"
 masakari_api_tag: "{{ masakari_tag }}"
diff --git a/ansible/roles/memcached/defaults/main.yml b/ansible/roles/memcached/defaults/main.yml
index 0fc550288f..126cc83c7e 100644
--- a/ansible/roles/memcached/defaults/main.yml
+++ b/ansible/roles/memcached/defaults/main.yml
@@ -32,7 +32,7 @@ haproxy_members: "{% for host in groups['memcached'] %}server {{ hostvars[host][
 ####################
 memcached_install_type: "{{ kolla_install_type }}"
 memcached_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ memcached_install_type }}-memcached"
-memcached_tag: "{{ openstack_release }}"
+memcached_tag: "{{ openstack_tag }}"
 memcached_image_full: "{{ memcached_image }}:{{ memcached_tag }}"
 memcached_dimensions: "{{ default_container_dimensions }}"
 
diff --git a/ansible/roles/mistral/defaults/main.yml b/ansible/roles/mistral/defaults/main.yml
index 321daab5e9..0d46597007 100644
--- a/ansible/roles/mistral/defaults/main.yml
+++ b/ansible/roles/mistral/defaults/main.yml
@@ -55,7 +55,7 @@ mistral_database_address: "{{ database_address | put_address_in_context('url') }
 # Docker
 ####################
 mistral_install_type: "{{ kolla_install_type }}"
-mistral_tag: "{{ openstack_release }}"
+mistral_tag: "{{ openstack_tag }}"
 
 mistral_engine_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ mistral_install_type }}-mistral-engine"
 mistral_engine_tag: "{{ mistral_tag }}"
diff --git a/ansible/roles/monasca/defaults/main.yml b/ansible/roles/monasca/defaults/main.yml
index c0eb7bc139..b5c08e7a28 100644
--- a/ansible/roles/monasca/defaults/main.yml
+++ b/ansible/roles/monasca/defaults/main.yml
@@ -201,7 +201,7 @@ monasca_grafana_data_sources:
 
 # NOTE(dszumski): Binary support for Monasca images is not yet available in Kolla
 monasca_install_type: "{{ kolla_install_type }}"
-monasca_tag: "{{ openstack_release }}"
+monasca_tag: "{{ openstack_tag }}"
 
 monasca_agent_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ monasca_install_type }}-monasca-agent"
 monasca_agent_tag: "{{ monasca_tag }}"
diff --git a/ansible/roles/mongodb/defaults/main.yml b/ansible/roles/mongodb/defaults/main.yml
index dbf332114d..489f9cafb2 100644
--- a/ansible/roles/mongodb/defaults/main.yml
+++ b/ansible/roles/mongodb/defaults/main.yml
@@ -23,7 +23,7 @@ mongodb_services:
 ####################
 mongodb_install_type: "{{ kolla_install_type }}"
 mongodb_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ mongodb_install_type }}-mongodb"
-mongodb_tag: "{{ openstack_release }}"
+mongodb_tag: "{{ openstack_tag }}"
 mongodb_image_full: "{{ mongodb_image }}:{{ mongodb_tag }}"
 mongodb_dimensions: "{{ default_container_dimensions }}"
 
diff --git a/ansible/roles/multipathd/defaults/main.yml b/ansible/roles/multipathd/defaults/main.yml
index 7f42d3f1a2..243834f3a9 100644
--- a/ansible/roles/multipathd/defaults/main.yml
+++ b/ansible/roles/multipathd/defaults/main.yml
@@ -17,7 +17,7 @@ multipathd_services:
 ####################
 multipathd_install_type: "{{ kolla_install_type }}"
 multipathd_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ multipathd_install_type }}-multipathd"
-multipathd_tag: "{{ openstack_release }}"
+multipathd_tag: "{{ openstack_tag }}"
 multipathd_image_full: "{{ multipathd_image }}:{{ multipathd_tag }}"
 
 multipathd_default_volumes:
diff --git a/ansible/roles/murano/defaults/main.yml b/ansible/roles/murano/defaults/main.yml
index 81df8a3fcb..9616fade74 100644
--- a/ansible/roles/murano/defaults/main.yml
+++ b/ansible/roles/murano/defaults/main.yml
@@ -41,7 +41,7 @@ murano_database_address: "{{ database_address | put_address_in_context('url') }}
 # Docker
 ####################
 murano_install_type: "{{ kolla_install_type }}"
-murano_tag: "{{ openstack_release }}"
+murano_tag: "{{ openstack_tag }}"
 
 murano_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ murano_install_type }}-murano-api"
 murano_api_tag: "{{ murano_tag }}"
diff --git a/ansible/roles/neutron/defaults/main.yml b/ansible/roles/neutron/defaults/main.yml
index d88b725e99..48a98caa94 100644
--- a/ansible/roles/neutron/defaults/main.yml
+++ b/ansible/roles/neutron/defaults/main.yml
@@ -172,7 +172,7 @@ neutron_database_address: "{{ database_address | put_address_in_context('url') }
 # Docker
 ####################
 neutron_install_type: "{{ kolla_install_type }}"
-neutron_tag: "{{ openstack_release }}"
+neutron_tag: "{{ openstack_tag }}"
 
 neutron_dhcp_agent_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ neutron_install_type }}-neutron-dhcp-agent"
 neutron_dhcp_agent_tag: "{{ neutron_tag }}"
diff --git a/ansible/roles/nova-cell/defaults/main.yml b/ansible/roles/nova-cell/defaults/main.yml
index 5fcb30a6c6..e79ca4e8e5 100644
--- a/ansible/roles/nova-cell/defaults/main.yml
+++ b/ansible/roles/nova-cell/defaults/main.yml
@@ -208,7 +208,7 @@ nova_cell_notify_rabbitmq_users:
 # Docker
 ####################
 nova_install_type: "{{ kolla_install_type }}"
-nova_tag: "{{ openstack_release }}"
+nova_tag: "{{ openstack_tag }}"
 
 nova_libvirt_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ nova_install_type }}-nova-libvirt"
 nova_libvirt_tag: "{{ nova_tag }}"
diff --git a/ansible/roles/nova/defaults/main.yml b/ansible/roles/nova/defaults/main.yml
index 2ccf0b0a55..633ea74c26 100644
--- a/ansible/roles/nova/defaults/main.yml
+++ b/ansible/roles/nova/defaults/main.yml
@@ -77,7 +77,7 @@ nova_api_database_address: "{{ database_address | put_address_in_context('url')
 # Docker
 ####################
 nova_install_type: "{{ kolla_install_type }}"
-nova_tag: "{{ openstack_release }}"
+nova_tag: "{{ openstack_tag }}"
 
 nova_super_conductor_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ nova_install_type }}-nova-conductor"
 nova_super_conductor_tag: "{{ nova_tag }}"
diff --git a/ansible/roles/octavia/defaults/main.yml b/ansible/roles/octavia/defaults/main.yml
index 1a424c03d4..cd2f49f67a 100644
--- a/ansible/roles/octavia/defaults/main.yml
+++ b/ansible/roles/octavia/defaults/main.yml
@@ -62,7 +62,7 @@ octavia_database_address: "{{ database_address | put_address_in_context('url') }
 # Docker
 ####################
 octavia_install_type: "{{ kolla_install_type }}"
-octavia_tag: "{{ openstack_release }}"
+octavia_tag: "{{ openstack_tag }}"
 
 octavia_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ octavia_install_type }}-octavia-api"
 octavia_api_tag: "{{ octavia_tag }}"
diff --git a/ansible/roles/openvswitch/defaults/main.yml b/ansible/roles/openvswitch/defaults/main.yml
index 7781356e21..9902a3ee96 100644
--- a/ansible/roles/openvswitch/defaults/main.yml
+++ b/ansible/roles/openvswitch/defaults/main.yml
@@ -38,7 +38,7 @@ openvswitch_services:
 # Docker
 ####################
 openvswitch_install_type: "{{ kolla_install_type }}"
-openvswitch_tag: "{{ openstack_release }}"
+openvswitch_tag: "{{ openstack_tag }}"
 
 openvswitch_db_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ openvswitch_install_type }}-openvswitch-db-server"
 openvswitch_db_tag: "{{ openvswitch_tag }}"
diff --git a/ansible/roles/ovs-dpdk/defaults/main.yml b/ansible/roles/ovs-dpdk/defaults/main.yml
index 4a1c21dcca..95333630f3 100644
--- a/ansible/roles/ovs-dpdk/defaults/main.yml
+++ b/ansible/roles/ovs-dpdk/defaults/main.yml
@@ -63,7 +63,7 @@ neutron_bridge_name: "br_dpdk"
 # Docker
 ####################
 ovsdpdk_install_type: "{{ kolla_install_type }}"
-ovsdpdk_tag: "{{ openstack_release }}"
+ovsdpdk_tag: "{{ openstack_tag }}"
 
 ovsdpdk_db_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ ovsdpdk_install_type }}-ovsdpdk-db"
 ovsdpdk_db_tag: "{{ ovsdpdk_tag }}"
diff --git a/ansible/roles/panko/defaults/main.yml b/ansible/roles/panko/defaults/main.yml
index 7eb75dda3c..3cf724818c 100644
--- a/ansible/roles/panko/defaults/main.yml
+++ b/ansible/roles/panko/defaults/main.yml
@@ -36,7 +36,7 @@ panko_database_mysql_address: "{{ database_address | put_address_in_context('url
 ####################
 panko_install_type: "{{ kolla_install_type }}"
 panko_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ panko_install_type }}-panko-api"
-panko_api_tag: "{{ openstack_release }}"
+panko_api_tag: "{{ openstack_tag }}"
 panko_api_image_full: "{{ panko_api_image }}:{{ panko_api_tag }}"
 panko_api_dimensions: "{{ default_container_dimensions }}"
 
diff --git a/ansible/roles/placement/defaults/main.yml b/ansible/roles/placement/defaults/main.yml
index e719db7a7c..9b984b5e84 100644
--- a/ansible/roles/placement/defaults/main.yml
+++ b/ansible/roles/placement/defaults/main.yml
@@ -34,7 +34,7 @@ placement_database_address: "{{ database_address | put_address_in_context('url')
 # Docker
 ####################
 placement_install_type: "{{ kolla_install_type }}"
-placement_tag: "{{ openstack_release }}"
+placement_tag: "{{ openstack_tag }}"
 
 placement_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ placement_install_type }}-placement-api"
 placement_api_tag: "{{ placement_tag }}"
diff --git a/ansible/roles/prometheus/defaults/main.yml b/ansible/roles/prometheus/defaults/main.yml
index c835ff05bb..b764202027 100644
--- a/ansible/roles/prometheus/defaults/main.yml
+++ b/ansible/roles/prometheus/defaults/main.yml
@@ -117,7 +117,7 @@ prometheus_blackbox_exporter_endpoints: []
 # Docker
 ####################
 prometheus_install_type: "{{ kolla_install_type }}"
-prometheus_tag: "{{ openstack_release }}"
+prometheus_tag: "{{ openstack_tag }}"
 
 prometheus_server_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ prometheus_install_type }}-prometheus-server"
 prometheus_server_tag: "{{ prometheus_tag }}"
diff --git a/ansible/roles/qdrouterd/defaults/main.yml b/ansible/roles/qdrouterd/defaults/main.yml
index 4c58d10d48..f2ad9ab41d 100644
--- a/ansible/roles/qdrouterd/defaults/main.yml
+++ b/ansible/roles/qdrouterd/defaults/main.yml
@@ -15,7 +15,7 @@ qdrouterd_services:
 ####################
 qdrouterd_install_type: "{{ kolla_install_type }}"
 qdrouterd_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ qdrouterd_install_type }}-qdrouterd"
-qdrouterd_tag: "{{ openstack_release }}"
+qdrouterd_tag: "{{ openstack_tag }}"
 qdrouterd_image_full: "{{ qdrouterd_image }}:{{ qdrouterd_tag }}"
 qdrouterd_dimensions: "{{ default_container_dimensions }}"
 
diff --git a/ansible/roles/qinling/defaults/main.yml b/ansible/roles/qinling/defaults/main.yml
index 3c503057d9..eddcad8397 100644
--- a/ansible/roles/qinling/defaults/main.yml
+++ b/ansible/roles/qinling/defaults/main.yml
@@ -41,7 +41,7 @@ qinling_database_address: "{{ database_address | put_address_in_context('url') }
 # Docker
 ####################
 qinling_install_type: "{{ kolla_install_type }}"
-qinling_tag: "{{ openstack_release }}"
+qinling_tag: "{{ openstack_tag }}"
 
 qinling_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ qinling_install_type }}-qinling-api"
 qinling_api_tag: "{{ qinling_tag }}"
diff --git a/ansible/roles/rabbitmq/defaults/main.yml b/ansible/roles/rabbitmq/defaults/main.yml
index 65a6fcc84f..2cae4fe66d 100644
--- a/ansible/roles/rabbitmq/defaults/main.yml
+++ b/ansible/roles/rabbitmq/defaults/main.yml
@@ -52,7 +52,7 @@ haproxy_outward_rabbitmq_server_timeout: "1h"
 ####################
 rabbitmq_install_type: "{{ kolla_install_type }}"
 rabbitmq_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ rabbitmq_install_type }}-rabbitmq"
-rabbitmq_tag: "{{ openstack_release }}"
+rabbitmq_tag: "{{ openstack_tag }}"
 rabbitmq_image_full: "{{ rabbitmq_image }}:{{ rabbitmq_tag }}"
 rabbitmq_dimensions: "{{ default_container_dimensions }}"
 
diff --git a/ansible/roles/rally/defaults/main.yml b/ansible/roles/rally/defaults/main.yml
index da93f0699b..83d0d50ed9 100644
--- a/ansible/roles/rally/defaults/main.yml
+++ b/ansible/roles/rally/defaults/main.yml
@@ -16,7 +16,7 @@ rally_services:
 ########
 rally_install_type: "{{ kolla_install_type }}"
 rally_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ rally_install_type }}-rally"
-rally_tag: "{{ openstack_release }}"
+rally_tag: "{{ openstack_tag }}"
 rally_image_full: "{{ rally_image }}:{{ rally_tag }}"
 rally_dimensions: "{{ default_container_dimensions }}"
 
diff --git a/ansible/roles/redis/defaults/main.yml b/ansible/roles/redis/defaults/main.yml
index 8cbe102895..4b05d88f94 100644
--- a/ansible/roles/redis/defaults/main.yml
+++ b/ansible/roles/redis/defaults/main.yml
@@ -22,11 +22,11 @@ redis_services:
 ####################
 redis_install_type: "{{ kolla_install_type }}"
 redis_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ redis_install_type }}-redis"
-redis_tag: "{{ openstack_release }}"
+redis_tag: "{{ openstack_tag }}"
 redis_image_full: "{{ redis_image }}:{{ redis_tag }}"
 
 redis_sentinel_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ redis_install_type }}-redis-sentinel"
-redis_sentinel_tag: "{{ openstack_release }}"
+redis_sentinel_tag: "{{ openstack_tag }}"
 redis_sentinel_image_full: "{{ redis_sentinel_image }}:{{ redis_tag }}"
 redis_dimensions: "{{ default_container_dimensions }}"
 redis_sentinel_dimensions: "{{ default_container_dimensions }}"
diff --git a/ansible/roles/sahara/defaults/main.yml b/ansible/roles/sahara/defaults/main.yml
index 758e89a8e3..e5804d8c27 100644
--- a/ansible/roles/sahara/defaults/main.yml
+++ b/ansible/roles/sahara/defaults/main.yml
@@ -42,7 +42,7 @@ sahara_database_address: "{{ database_address | put_address_in_context('url') }}
 # Docker
 ####################
 sahara_install_type: "{{ kolla_install_type }}"
-sahara_tag: "{{ openstack_release }}"
+sahara_tag: "{{ openstack_tag }}"
 
 sahara_engine_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ sahara_install_type }}-sahara-engine"
 sahara_engine_tag: "{{ sahara_tag }}"
diff --git a/ansible/roles/searchlight/defaults/main.yml b/ansible/roles/searchlight/defaults/main.yml
index 0874a955e2..bb74c4376b 100644
--- a/ansible/roles/searchlight/defaults/main.yml
+++ b/ansible/roles/searchlight/defaults/main.yml
@@ -37,7 +37,7 @@ searchlight_elasticsearch_url: "{{ kolla_internal_fqdn | put_address_in_context(
 # Docker
 ####################
 searchlight_install_type: "{{ kolla_install_type }}"
-searchlight_tag: "{{ openstack_release }}"
+searchlight_tag: "{{ openstack_tag }}"
 
 searchlight_listener_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ searchlight_install_type }}-searchlight-listener"
 searchlight_listener_tag: "{{ searchlight_tag }}"
diff --git a/ansible/roles/senlin/defaults/main.yml b/ansible/roles/senlin/defaults/main.yml
index 25a4889761..0d8f47ec6f 100644
--- a/ansible/roles/senlin/defaults/main.yml
+++ b/ansible/roles/senlin/defaults/main.yml
@@ -56,7 +56,7 @@ senlin_database_address: "{{ database_address | put_address_in_context('url') }}
 # Docker
 ####################
 senlin_install_type: "{{ kolla_install_type }}"
-senlin_tag: "{{ openstack_release }}"
+senlin_tag: "{{ openstack_tag }}"
 
 senlin_conductor_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ senlin_install_type }}-senlin-conductor"
 senlin_conductor_tag: "{{ senlin_tag }}"
diff --git a/ansible/roles/skydive/defaults/main.yml b/ansible/roles/skydive/defaults/main.yml
index 58a78c73e3..08b71d4327 100644
--- a/ansible/roles/skydive/defaults/main.yml
+++ b/ansible/roles/skydive/defaults/main.yml
@@ -34,11 +34,11 @@ skydive_services:
 ####################
 skydive_install_type: "{{ kolla_install_type }}"
 skydive_analyzer_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ skydive_install_type }}-skydive-analyzer"
-skydive_analyzer_tag: "{{ openstack_release }}"
+skydive_analyzer_tag: "{{ openstack_tag }}"
 skydive_analyzer_image_full: "{{ skydive_analyzer_image }}:{{ skydive_analyzer_tag }}"
 
 skydive_agent_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ skydive_install_type }}-skydive-agent"
-skydive_agent_tag: "{{ openstack_release }}"
+skydive_agent_tag: "{{ openstack_tag }}"
 skydive_agent_image_full: "{{ skydive_agent_image }}:{{ skydive_agent_tag }}"
 skydive_analyzer_dimensions: "{{ default_container_dimensions }}"
 skydive_agent_dimensions: "{{ default_container_dimensions }}"
diff --git a/ansible/roles/solum/defaults/main.yml b/ansible/roles/solum/defaults/main.yml
index 57e9763bde..d67146bc30 100644
--- a/ansible/roles/solum/defaults/main.yml
+++ b/ansible/roles/solum/defaults/main.yml
@@ -68,7 +68,7 @@ solum_database_address: "{{ database_address | put_address_in_context('url') }}:
 # Docker
 ####################
 solum_install_type: "{{ kolla_install_type }}"
-solum_tag: "{{ openstack_release }}"
+solum_tag: "{{ openstack_tag }}"
 
 solum_worker_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ solum_install_type }}-solum-worker"
 solum_worker_tag: "{{ solum_tag }}"
diff --git a/ansible/roles/storm/defaults/main.yml b/ansible/roles/storm/defaults/main.yml
index 901e939b7c..123e90dd7c 100644
--- a/ansible/roles/storm/defaults/main.yml
+++ b/ansible/roles/storm/defaults/main.yml
@@ -34,7 +34,7 @@ storm_nimbus_servers: "{% for host in groups['storm-nimbus'] %}'{{ 'api' | kolla
 ####################
 storm_install_type: "{{ kolla_install_type }}"
 storm_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ storm_install_type }}-storm"
-storm_tag: "{{ openstack_release }}"
+storm_tag: "{{ openstack_tag }}"
 storm_image_full: "{{ storm_image }}:{{ storm_tag }}"
 
 storm_worker_dimensions: "{{ default_container_dimensions }}"
diff --git a/ansible/roles/swift/defaults/main.yml b/ansible/roles/swift/defaults/main.yml
index 115f0da884..7d38df8833 100644
--- a/ansible/roles/swift/defaults/main.yml
+++ b/ansible/roles/swift/defaults/main.yml
@@ -21,7 +21,7 @@ swift_services:
 # Docker
 ####################
 swift_install_type: "{{ kolla_install_type }}"
-swift_tag: "{{ openstack_release }}"
+swift_tag: "{{ openstack_tag }}"
 
 swift_proxy_server_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ swift_install_type }}-swift-proxy-server"
 swift_proxy_server_tag: "{{ swift_tag }}"
diff --git a/ansible/roles/tacker/defaults/main.yml b/ansible/roles/tacker/defaults/main.yml
index 385602b921..08bb07b5ba 100644
--- a/ansible/roles/tacker/defaults/main.yml
+++ b/ansible/roles/tacker/defaults/main.yml
@@ -43,7 +43,7 @@ tacker_database_address: "{{ database_address | put_address_in_context('url') }}
 # Docker
 ########
 tacker_install_type: "{{ kolla_install_type }}"
-tacker_tag: "{{ openstack_release }}"
+tacker_tag: "{{ openstack_tag }}"
 
 tacker_server_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ tacker_install_type }}-tacker-server"
 tacker_server_tag: "{{ tacker_tag }}"
diff --git a/ansible/roles/telegraf/defaults/main.yml b/ansible/roles/telegraf/defaults/main.yml
index 5702b8c642..19b5fcc16e 100644
--- a/ansible/roles/telegraf/defaults/main.yml
+++ b/ansible/roles/telegraf/defaults/main.yml
@@ -16,7 +16,7 @@ telegraf_services:
 ####################
 telegraf_install_type: "{{ kolla_install_type }}"
 telegraf_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ telegraf_install_type }}-telegraf"
-telegraf_tag: "{{ openstack_release }}"
+telegraf_tag: "{{ openstack_tag }}"
 telegraf_image_full: "{{ telegraf_image }}:{{ telegraf_tag }}"
 telegraf_dimensions: "{{ default_container_dimensions }}"
 
diff --git a/ansible/roles/tempest/defaults/main.yml b/ansible/roles/tempest/defaults/main.yml
index 8b5847c4eb..9c0c72d0c4 100644
--- a/ansible/roles/tempest/defaults/main.yml
+++ b/ansible/roles/tempest/defaults/main.yml
@@ -16,7 +16,7 @@ tempest_services:
 ########
 tempest_install_type: "{{ kolla_install_type }}"
 tempest_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ tempest_install_type }}-tempest"
-tempest_tag: "{{ openstack_release }}"
+tempest_tag: "{{ openstack_tag }}"
 tempest_image_full: "{{ tempest_image }}:{{ tempest_tag }}"
 tempest_dimensions: "{{ default_container_dimensions }}"
 
diff --git a/ansible/roles/trove/defaults/main.yml b/ansible/roles/trove/defaults/main.yml
index 01e2b51ab5..eb5bda3535 100644
--- a/ansible/roles/trove/defaults/main.yml
+++ b/ansible/roles/trove/defaults/main.yml
@@ -48,7 +48,7 @@ trove_database_address: "{{ database_address | put_address_in_context('url') }}:
 # Docker
 ####################
 trove_install_type: "{{ kolla_install_type }}"
-trove_tag: "{{ openstack_release }}"
+trove_tag: "{{ openstack_tag }}"
 
 trove_conductor_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ trove_install_type }}-trove-conductor"
 trove_conductor_tag: "{{ trove_tag }}"
diff --git a/ansible/roles/vitrage/defaults/main.yml b/ansible/roles/vitrage/defaults/main.yml
index 48815f8fd4..5bedb44c50 100644
--- a/ansible/roles/vitrage/defaults/main.yml
+++ b/ansible/roles/vitrage/defaults/main.yml
@@ -54,7 +54,7 @@ vitrage_database_address: "{{ database_address | put_address_in_context('url') }
 ####################
 
 vitrage_install_type: "{{ kolla_install_type }}"
-vitrage_tag: "{{ openstack_release }}"
+vitrage_tag: "{{ openstack_tag }}"
 
 vitrage_graph_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ vitrage_install_type }}-vitrage-graph"
 vitrage_graph_tag: "{{ vitrage_tag }}"
diff --git a/ansible/roles/vmtp/defaults/main.yml b/ansible/roles/vmtp/defaults/main.yml
index 18f7a73bc7..76b039966f 100644
--- a/ansible/roles/vmtp/defaults/main.yml
+++ b/ansible/roles/vmtp/defaults/main.yml
@@ -15,7 +15,7 @@ vmtp_services:
 ####################
 vmtp_install_type: "{{ kolla_install_type }}"
 vmtp_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ vmtp_install_type }}-vmtp"
-vmtp_tag: "{{ openstack_release }}"
+vmtp_tag: "{{ openstack_tag }}"
 vmtp_image_full: "{{ vmtp_image }}:{{ vmtp_tag }}"
 vmtp_dimensions: "{{ default_container_dimensions }}"
 
diff --git a/ansible/roles/watcher/defaults/main.yml b/ansible/roles/watcher/defaults/main.yml
index 368b4fd947..0d59e473af 100644
--- a/ansible/roles/watcher/defaults/main.yml
+++ b/ansible/roles/watcher/defaults/main.yml
@@ -48,7 +48,7 @@ watcher_database_address: "{{ database_address | put_address_in_context('url') }
 # Docker
 ####################
 watcher_install_type: "{{ kolla_install_type }}"
-watcher_tag: "{{ openstack_release }}"
+watcher_tag: "{{ openstack_tag }}"
 
 watcher_engine_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ watcher_install_type }}-watcher-engine"
 watcher_engine_tag: "{{ watcher_tag }}"
diff --git a/ansible/roles/zookeeper/defaults/main.yml b/ansible/roles/zookeeper/defaults/main.yml
index 51d7cb8e5a..e657affcef 100644
--- a/ansible/roles/zookeeper/defaults/main.yml
+++ b/ansible/roles/zookeeper/defaults/main.yml
@@ -23,7 +23,7 @@ zookeeper_log_settings: 'INFO,ROLLINGFILE'
 ####################
 zookeeper_install_type: "{{ kolla_install_type }}"
 zookeeper_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ zookeeper_install_type }}-zookeeper"
-zookeeper_tag: "{{ openstack_release }}"
+zookeeper_tag: "{{ openstack_tag }}"
 zookeeper_image_full: "{{ zookeeper_image }}:{{ zookeeper_tag }}"
 zookeeper_dimensions: "{{ default_container_dimensions }}"
 
diff --git a/ansible/roles/zun/defaults/main.yml b/ansible/roles/zun/defaults/main.yml
index f522fd93c1..ee0584a7bf 100644
--- a/ansible/roles/zun/defaults/main.yml
+++ b/ansible/roles/zun/defaults/main.yml
@@ -59,7 +59,7 @@ zun_database_address: "{{ database_address | put_address_in_context('url') }}:{{
 ## Docker
 ####################
 zun_install_type: "{{ kolla_install_type }}"
-zun_tag: "{{ openstack_release }}"
+zun_tag: "{{ openstack_tag }}"
 
 zun_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ zun_install_type }}-zun-api"
 zun_api_tag: "{{ zun_tag }}"
diff --git a/etc/kolla/globals.yml b/etc/kolla/globals.yml
index 0988268b29..9dc85f3f46 100644
--- a/etc/kolla/globals.yml
+++ b/etc/kolla/globals.yml
@@ -20,6 +20,12 @@
 # Valid option is Docker repository tag
 #openstack_release: ""
 
+# Docker image tag used by default.
+#openstack_tag: "{{ openstack_release ~ openstack_tag_suffix }}"
+
+# Suffix applied to openstack_release to generate openstack_tag.
+#openstack_tag_suffix: "{{ '' if base_distro != 'centos' or ansible_distribution_major_version == '7' else  '-centos8' }}"
+
 # Location of configuration overrides
 #node_custom_config: "/etc/kolla/config"
 
diff --git a/releasenotes/notes/openstack-tag-bfe4e862ade8549b.yaml b/releasenotes/notes/openstack-tag-bfe4e862ade8549b.yaml
new file mode 100644
index 0000000000..869c5a758f
--- /dev/null
+++ b/releasenotes/notes/openstack-tag-bfe4e862ade8549b.yaml
@@ -0,0 +1,8 @@
+---
+features:
+  - |
+    Adds a new variable, ``openstack_tag``, which is used as the default Docker
+    image tag in place of ``openstack_release``. The default value is
+    ``openstack_release``, with a suffix set via ``openstack_tag_suffix``.
+    The suffix is empty except on CentOS 8 where it is set to ``-centos8``.
+    This allows for the availability of images based on CentOS 7 and 8.
diff --git a/tests/templates/globals-default.j2 b/tests/templates/globals-default.j2
index 2966bf4e52..c2c4bc9783 100644
--- a/tests/templates/globals-default.j2
+++ b/tests/templates/globals-default.j2
@@ -37,7 +37,7 @@ docker_namespace: "lokolla"
 # docker does not support referencing registry via an IPv6 address
 # see: https://github.com/moby/moby/issues/39033
 docker_registry: "primary:4000"
-openstack_release: "{{ build_image_tag }}"
+openstack_tag: "{{ build_image_tag }}"
 {% else %}
 # use docker hub images
 docker_namespace: "kolla"
@@ -48,9 +48,7 @@ docker_namespace: "kolla"
 # of docker systemd command only once
 docker_custom_option: "--insecure-registry primary:4000"
 {% endif %}
-{% if not is_previous_release %}
-openstack_release: "{{ zuul.branch | basename }}"
-{% else %}
+{% if is_previous_release %}
 openstack_release: "{{ previous_release }}"
 {% endif %}
 {% endif %}