Node roles with dynamic metadata mapping

For easy scale of any role in the cluster, there are some
dynamic metadata will be prepared for 'Environment' model
based on roles from the inventory:

* Automatically control master/slave relations for the:
    rabbitmq_cluster_role
    mysql_cluster_role
    redis_cluster_role

* Automatically control IDs as counters for the:
    keepalived_vip_priority
    cicd_database_id
    opencontrail_database_id

Change-Id: I4a893662d43c9cb1799ee2bc24d72a62afc00a56
Reviewed-on: https://review.gerrithub.io/377960
Reviewed-by: Dennis Dmitriev <dis.xcom@gmail.com>
Tested-by: Dennis Dmitriev <dis.xcom@gmail.com>
diff --git a/tcp_tests/environment/environment_inventory/virtual-devops-mcp-ocata-sl2.yaml b/tcp_tests/environment/environment_inventory/virtual-devops-mcp-ocata-sl2.yaml
index a5b3c1e..0d13301 100644
--- a/tcp_tests/environment/environment_inventory/virtual-devops-mcp-ocata-sl2.yaml
+++ b/tcp_tests/environment/environment_inventory/virtual-devops-mcp-ocata-sl2.yaml
@@ -80,8 +80,8 @@
       reclass_storage_name: openstack_control_node01
       roles:
       - openstack_control_leader
-      - openstack_designate
-      - openstack_designate_keystone
+      - features_designate
+      - features_designate_keystone
       - linux_system_codename_xenial
       interfaces:
         ens3:
@@ -93,7 +93,7 @@
       reclass_storage_name: openstack_control_node02
       roles:
       - openstack_control
-      - openstack_designate
+      - features_designate
       - linux_system_codename_xenial
       interfaces:
         ens3:
@@ -105,7 +105,7 @@
       reclass_storage_name: openstack_control_node03
       roles:
       - openstack_control
-      - openstack_designate
+      - features_designate
       - linux_system_codename_xenial
       interfaces:
         ens3:
@@ -117,7 +117,7 @@
       reclass_storage_name: openstack_database_node01
       roles:
       - openstack_database_leader
-      - openstack_designate_database
+      - features_designate_database
       - linux_system_codename_xenial
       interfaces:
         ens3:
@@ -129,7 +129,7 @@
       reclass_storage_name: openstack_database_node02
       roles:
       - openstack_database
-      - openstack_designate_database
+      - features_designate_database
       - linux_system_codename_xenial
       interfaces:
         ens3:
@@ -141,7 +141,7 @@
       reclass_storage_name: openstack_database_node03
       roles:
       - openstack_database
-      - openstack_designate_database
+      - features_designate_database
       - linux_system_codename_xenial
       interfaces:
         ens3:
diff --git "a/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/bond0_ab_contrail" "b/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/bond0_ab_contrail"
index 3147d1f..8de76d6 100644
--- "a/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/bond0_ab_contrail"
+++ "b/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/bond0_ab_contrail"
@@ -1,16 +1,11 @@
 {#- Provides:     #}
-{#-   br_ctl (linux bridge) + control address #}
 {#-   br_mesh (linux bridge) + tenant address #}
+{#-   vhost0 , as a keepalived vip interface #}
 {#- Requirements:                     #}
-{#-   _param:single_address         #}
-{#-   _param:control_vlan           #}
-{#-   _param:control_network_netmask         #}
 {#-   _param:tenant_vlan           #}
 {#-   _param:tenant_address         #}
 {#-   _param:tenant_netmask         #}
 {#-   _param:tenant_network_gateway         #}
-{#-   _param:_param:dns_server01         #}
-{#-   _param:_param:dns_server02         #}
 
               # {{ interfaces_role }}
               {%- for interface_name, interface in interfaces.items() %}
@@ -38,27 +33,7 @@
                 - {{ interface_name }}
                 {%- endfor %}
 
-              br_ctl:
-                address: ${_param:_esc}{_param:single_address}
-                enabled: true
-                netmask: ${_param:_esc}{_param:control_network_netmask}
-                proto: static
-                type: bridge
-                use_interfaces:
-                - bond0.${_param:_esc}{_param:control_vlan}
-                require_interfaces:
-                - bond0.${_param:_esc}{_param:control_vlan}
-              bond0.control_vlan:
-                mtu: 9000
-                name: bond0.${_param:_esc}{_param:control_vlan}
-                enabled: true
-                proto: manual
-                type: vlan
-                use_interfaces:
-                - bond0
-                require_interfaces:
-                - bond0
-
+              {{- set_param('keepalived_vip_interface', 'vhost0') }}
               vhost0:
                 mtu: 9000
                 address: ${_param:_esc}{_param:tenant_address}
diff --git "a/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/bond0_ab_ctl_contrail" "b/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/bond0_ab_ctl_contrail"
new file mode 100644
index 0000000..dfee7cd
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/bond0_ab_ctl_contrail"
@@ -0,0 +1,88 @@
+{#- Provides:     #}
+{#-   br_ctl (linux bridge) + control address #}
+{#-   vhost0  #}
+{#- Requirements:                     #}
+{#-   _param:single_address         #}
+{#-   _param:control_vlan           #}
+{#-   _param:control_network_netmask         #}
+{#-   _param:tenant_vlan           #}
+{#-   _param:tenant_address         #}
+{#-   _param:tenant_netmask         #}
+{#-   _param:tenant_network_gateway         #}
+{#-   _param:_param:dns_server01         #}
+{#-   _param:_param:dns_server02         #}
+
+              # {{ interfaces_role }}
+              {%- for interface_name, interface in interfaces.items() %}
+              {{ interface_name }}:
+                mtu: 9000
+                enabled: true
+                name: {{ interface_name }}
+                proto: manual
+                type: eth
+                ipflush_onchange: true
+              {%- endfor %}
+              bond0:
+                mtu: 9000
+                enabled: true
+                mode: active-backup
+                proto: manual
+                slaves: {{ ' '.join(interfaces.keys()) }}
+                type: bond
+                use_interfaces:
+                {%- for interface_name in interfaces.keys() %}
+                - {{ interface_name }}
+                {%- endfor %}
+                require_interfaces:
+                {%- for interface_name in interfaces.keys() %}
+                - {{ interface_name }}
+                {%- endfor %}
+
+              br_ctl:
+                address: ${_param:_esc}{_param:single_address}
+                enabled: true
+                netmask: ${_param:_esc}{_param:control_network_netmask}
+                proto: static
+                type: bridge
+                use_interfaces:
+                - bond0.${_param:_esc}{_param:control_vlan}
+                require_interfaces:
+                - bond0.${_param:_esc}{_param:control_vlan}
+              bond0.control_vlan:
+                mtu: 9000
+                name: bond0.${_param:_esc}{_param:control_vlan}
+                enabled: true
+                proto: manual
+                type: vlan
+                use_interfaces:
+                - bond0
+                require_interfaces:
+                - bond0
+
+              vhost0:
+                mtu: 9000
+                address: ${_param:_esc}{_param:tenant_address}
+                netmask: ${_param:_esc}{_param:tenant_network_netmask}
+                gateway: ${_param:_esc}{_param:tenant_network_gateway}
+                enabled: true
+                proto: static
+                type: eth
+                pre_up_cmds:
+                - /usr/lib/contrail/if-vhost0
+                name_servers:
+                - ${_param:_esc}{_param:dns_server01}
+                - ${_param:_esc}{_param:dns_server02}
+                use_interfaces:
+                - bond0.${_param:_esc}{_param:tenant_vlan}
+                require_interfaces:
+                - bond0.${_param:_esc}{_param:tenant_vlan}
+              bond0.tenant_vlan:
+                mtu: 9000
+                name: bond0.${_param:_esc}{_param:tenant_vlan}
+                enabled: true
+                proto: manual
+                type: vlan
+                use_interfaces:
+                - bond0
+                require_interfaces:
+                - bond0
diff --git "a/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/bond0_ab_ovs_vlan_ctl" "b/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/bond0_ab_ovs_vlan_ctl"
index 4326138..d6bbd72 100644
--- "a/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/bond0_ab_ovs_vlan_ctl"
+++ "b/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/bond0_ab_ovs_vlan_ctl"
@@ -51,4 +51,3 @@
                 - bond0
                 require_interfaces:
                 - bond0
-{%- set _ = params.update({'keepalived_vip_interface': 'br_ctl'}) %}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/readme.txt" "b/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/readme.txt"
new file mode 100644
index 0000000..cf80b5b
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/readme.txt"
@@ -0,0 +1,10 @@
+Patterns from this folder are used for two purposes:
+1. Configure the real node interfaces as specified in the inventory.
+2. Provide the following list of interfaces for the underlay level:
+  - br_mgm: Access from infrastructure management network / admin network / DHCP / PXE
+  - br_ctl: OpenStack control network for internal services
+  - br-prv: For tenant networks with VLAN segmentation
+  - br-ten: For tenant networks with VXLAN segmentation
+  - br-mesh: Endpoint for VXLAN tunnels that are used by br-ten
+  - br-floating: Connection to the floating network
+  - vhost0: for OpenContrail workloads
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/single_ctl" "b/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/single_ctl"
index a289c99..ce54ed7 100644
--- "a/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/single_ctl"
+++ "b/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/single_ctl"
@@ -29,4 +29,3 @@
                 - {{ interface_name }}
                 require_interfaces:
                 - {{ interface_name }}
-{%- set _ = params.update({'keepalived_vip_interface': 'br_ctl'}) %}
diff --git "a/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/single_dhcp" "b/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/single_dhcp"
index 107b523..87315e0 100644
--- "a/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/single_dhcp"
+++ "b/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/single_dhcp"
@@ -1,12 +1,6 @@
-{#- Management (admin) network. For nodes where deploy address must be configured as static (at least cfg*) #}
+{#- Management (admin) network with DHCP #}
 {#- Provides:                         #}
-{#-   br_mgm (linux bridge) + address #}
-{#- Requires:                         #}
-{#-   _param:deploy_address         #}
-{#-   _param:deploy_network_netmask         #}
-{#-   _param:deploy_network_gateway         #}
-{#-   _param:dns_server01         #}
-{#-   _param:dns_server02         #}
+{#-   <interface_name> + DHCP address #}
 
               # {{ interfaces_role }}
               {%- set interface_name = interfaces.keys()[0] %}
@@ -14,4 +8,4 @@
                 enabled: true
                 type: eth
                 proto: dhcp
-                name: {{ interface_name }}
+                name: {{ interface_name }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/single_mgm_dhcp" "b/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/single_mgm_dhcp"
new file mode 100644
index 0000000..fd2bf66
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/single_mgm_dhcp"
@@ -0,0 +1,18 @@
+{#- Management (admin) network. For nodes where deploy address provided by DHCP server #}
+{#- Provides:                         #}
+{#-   br_mgm (linux bridge) + DHCP address #}
+
+              # {{ interfaces_role }}
+              {%- set interface_name = interfaces.keys()[0] %}
+              {{ interface_name }}:
+                enabled: true
+                type: eth
+                proto: manual
+                ipflush_onchange: true
+                name: {{ interface_name }}
+              br_mgm:
+                enabled: true
+                proto: dhcp
+                type: bridge
+                use_interfaces:
+                - {{ interface_name }}
diff --git "a/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/single_vlan_ctl" "b/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/single_vlan_ctl"
index db00e14..2b899a2 100644
--- "a/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/single_vlan_ctl"
+++ "b/tcp_tests/environment/environment_template/\173\043 interfaces \043\175/single_vlan_ctl"
@@ -39,4 +39,3 @@
                 - {{ interface_name }}
                 require_interfaces:
                 - {{ interface_name }}
-{%- set _ = params.update({'keepalived_vip_interface': 'br_ctl'}) %}
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/linux_network_interface" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/_linux_network_interface"
similarity index 100%
rename from "tcp_tests/environment/environment_template/\173\043 roles \043\175/linux_network_interface"
rename to "tcp_tests/environment/environment_template/\173\043 roles \043\175/_linux_network_interface"
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/_metadata_process" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/_metadata_process"
new file mode 100644
index 0000000..ed7dc6e
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/_metadata_process"
@@ -0,0 +1,67 @@
+{#- Collect interface roles and params into the following dict:
+ # interface_role:             # filename that will be included
+ #  interface_name:            # interface (eth0)
+ #    interface_param1: value  # optional parameters or empty dict
+ #    interface_param2: value
+ #    ...
+ #}
+
+{#-
+1. Check if 'local_metadata' matches to something in 'global_metadata'.
+   If yes, fetch and process the data.
+   If no, initialize necessary data.
+   If partially intersects (keepalived roles for different clusters): add a fail-state warning to the YAML to avoid using the wrong config
+2. Set necessary 'params' using the 'local_metadata'
+3. Store the 'local_metadata' to the 'global_metadata' if required.
+4. Increment/decrement the 'global_metadata' objects if necessary (next IP address, next vrouter ID, master->slave, etc)
+
+global_metadata keep states across the nodes
+local_metadata keep states for the current node only
+#}
+
+{%- macro stateful_counter(counter_name, counter_start, counter_end, counter_step) %}
+{#- ############################################################################# -#}
+{%- if counter_name in local_metadata %}
+  {%- if counter_name not in global_metadata %}
+    {#- Set default value for <counter_name> = <counter_start> #}
+    {%- set _ = global_metadata.update({counter_name: counter_start}) %}
+  {%- else %}
+    {#- Increment or decrement value <counter_name> #}
+    {%- set _ = global_metadata.update({counter_name: global_metadata[counter_name] + counter_step}) %}
+    {%- if global_metadata[counter_name] == counter_end %}
+      {# Cause a jinja render exception and make visible the message with correct counter_name #}
+      {%- if counter_name == 'cicd_database_id' %}
+        {{ "======> VALUE_ERROR: 'cicd_database_id' is too high!"/0 }}
+      {%- elif counter_name == 'opencontrail_database_id' %}
+        {{ "======> VALUE_ERROR: 'opencontrail_database_id' is too high!"/0 }}
+      {%- elif counter_name == 'keepalived_vip_priority' %}
+        {{ "======> VALUE_ERROR: 'keepalived_vip_priority' is too low!"/0 }}
+      {%- else %}
+        {{ "======> VALUE_ERROR: <counter_name> is too high!"/0 }}
+      {%- endif %}
+    {%- endif %}
+  {%- endif %}
+  {%- set _ = params.update({counter_name: global_metadata[counter_name]}) %}
+{%- endif %}
+{%- endmacro %}
+
+{%- macro stateful_masterslave(masterslave_name, master_name='master', slave_name='slave') %}
+{#- ##################################################################################### -#}
+{%- if masterslave_name in local_metadata %}
+  {%- if masterslave_name not in global_metadata %}
+    {#- Set first value <masterslave_name> = <master_name> #}
+    {%- set _ = global_metadata.update({masterslave_name: master_name}) %}
+  {%- else %}
+    {#- Set value <masterslave_name> = <slave_name> #}
+    {%- set _ = global_metadata.update({masterslave_name: slave_name}) %}
+  {%- endif %}
+  {%- set _ = params.update({masterslave_name: global_metadata[masterslave_name]}) %}
+{%- endif %}
+{%- endmacro %}
+
+{{- stateful_counter('cicd_database_id', counter_start=1, counter_end=255, counter_step=1) }}
+{{- stateful_counter('opencontrail_database_id', counter_start=1, counter_end=255, counter_step=1) }}
+{{- stateful_counter('keepalived_vip_priority', counter_start=254, counter_end=1, counter_step=-1) }}
+{{- stateful_masterslave('rabbitmq_cluster_role') }}
+{{- stateful_masterslave('mysql_cluster_role') }}
+{{- stateful_masterslave('redis_cluster_role') }}
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/overrides" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/_overrides"
similarity index 100%
rename from "tcp_tests/environment/environment_template/\173\043 roles \043\175/overrides"
rename to "tcp_tests/environment/environment_template/\173\043 roles \043\175/_overrides"
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/ceph_mon" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/ceph_mon"
new file mode 100644
index 0000000..26cb72a
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/ceph_mon"
@@ -0,0 +1,11 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.ceph.mon
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('keepalived_vip_priority', 'ceph_mon') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/cicd_control_leader" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/cicd_control_leader"
index 562647c..37fcbd3 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/cicd_control_leader"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/cicd_control_leader"
@@ -6,4 +6,7 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - cluster.${_param:cluster_name}.cicd.control.leader
\ No newline at end of file
+          - cluster.${_param:cluster_name}.cicd.control.leader
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('keepalived_vip_priority', 'cicd_control') }}
+{{- register_metaparam('cicd_database_id', 'cicd_control') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/cicd_control_manager" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/cicd_control_manager"
index 12d220e..b2909c5 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/cicd_control_manager"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/cicd_control_manager"
@@ -6,4 +6,7 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - cluster.${_param:cluster_name}.cicd.control.manager
\ No newline at end of file
+          - cluster.${_param:cluster_name}.cicd.control.manager
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('keepalived_vip_priority', 'cicd_control') }}
+{{- register_metaparam('cicd_database_id', 'cicd_control') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_designate" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/features_designate"
similarity index 99%
rename from "tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_designate"
rename to "tcp_tests/environment/environment_template/\173\043 roles \043\175/features_designate"
index c945427..e295f2b 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_designate"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/features_designate"
@@ -6,4 +6,4 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - environment.{{ cookiecutter._env_name }}.features.designate.system
+          - environment.{{ cookiecutter._env_name }}.features.designate.system
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_designate_database" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/features_designate_database"
similarity index 99%
rename from "tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_designate_database"
rename to "tcp_tests/environment/environment_template/\173\043 roles \043\175/features_designate_database"
index 006235a..e541620 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_designate_database"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/features_designate_database"
@@ -6,4 +6,4 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - environment.{{ cookiecutter._env_name }}.features.designate.database
+          - environment.{{ cookiecutter._env_name }}.features.designate.database
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_designate_keystone" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/features_designate_keystone"
similarity index 99%
rename from "tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_designate_keystone"
rename to "tcp_tests/environment/environment_template/\173\043 roles \043\175/features_designate_keystone"
index 5e1b3c7..3fdc6e7 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_designate_keystone"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/features_designate_keystone"
@@ -6,4 +6,4 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - environment.{{ cookiecutter._env_name }}.features.designate.keystone
+          - environment.{{ cookiecutter._env_name }}.features.designate.keystone
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/infra_idm" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/infra_idm"
new file mode 100644
index 0000000..b9842d1
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/infra_idm"
@@ -0,0 +1,9 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.infra.idm
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/infra_kvm" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/infra_kvm"
index 93774b0..6945d69 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/infra_kvm"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/infra_kvm"
@@ -6,4 +6,6 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - cluster.${_param:cluster_name}.infra.kvm
\ No newline at end of file
+          - cluster.${_param:cluster_name}.infra.kvm
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('keepalived_vip_priority', 'infra_kvm') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/infra_maas" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/infra_maas"
new file mode 100644
index 0000000..7c925d2
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/infra_maas"
@@ -0,0 +1,9 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.infra.maas
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/infra_proxy" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/infra_proxy"
new file mode 100644
index 0000000..0386173
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/infra_proxy"
@@ -0,0 +1,12 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.openstack.proxy
+          - cluster.${_param:cluster_name}.stacklight.proxy
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('keepalived_vip_priority', 'infra_proxy') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/infra_rsyslog" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/infra_rsyslog"
new file mode 100644
index 0000000..3fcffa6
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/infra_rsyslog"
@@ -0,0 +1,9 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.infra.rsyslog
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/kubernetes_control" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/kubernetes_control"
new file mode 100644
index 0000000..e8b9db7
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/kubernetes_control"
@@ -0,0 +1,11 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.kubernetes.control
+{{- set_param('keepalived_vip_interface', 'ens3') }}
+{{- register_metaparam('keepalived_vip_priority', 'kubernetes_control') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/linux_system_codename_centos" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/linux_system_codename_centos"
new file mode 100644
index 0000000..2f199df
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/linux_system_codename_centos"
@@ -0,0 +1 @@
+{{- set_param('linux_system_codename', 'centos') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/linux_system_codename_trusty" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/linux_system_codename_trusty"
index 183f22c..997e3f5 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/linux_system_codename_trusty"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/linux_system_codename_trusty"
@@ -1,9 +1 @@
-{#-
-parameters:
-  reclass:
-    storage:
-      node:
-        <reclass_storage_node_name>:
-          classes:
-#}
-          - environment.{{ cookiecutter._env_name }}.linux_system_codename_trusty
\ No newline at end of file
+{{- set_param('linux_system_codename', 'trusty') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/linux_system_codename_xenial" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/linux_system_codename_xenial"
index 1ce5d52..a473f56 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/linux_system_codename_xenial"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/linux_system_codename_xenial"
@@ -1,9 +1 @@
-{#-
-parameters:
-  reclass:
-    storage:
-      node:
-        <reclass_storage_node_name>:
-          classes:
-#}
-          - environment.{{ cookiecutter._env_name }}.linux_system_codename_xenial
\ No newline at end of file
+{{- set_param('linux_system_codename', 'xenial') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/monitoring_service" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/monitoring_service"
new file mode 100644
index 0000000..ff7de21
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/monitoring_service"
@@ -0,0 +1,9 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.monitoring.server
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/opencontrail_analytics" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/opencontrail_analytics"
new file mode 100644
index 0000000..140be07
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/opencontrail_analytics"
@@ -0,0 +1,12 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.opencontrail.analytics
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('opencontrail_database_id', 'opencontrail_analytics') }}
+{{- register_metaparam('keepalived_vip_priority', 'opencontrail_analytics') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/opencontrail_control" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/opencontrail_control"
new file mode 100644
index 0000000..4684427
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/opencontrail_control"
@@ -0,0 +1,12 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.opencontrail.control
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('opencontrail_database_id', 'opencontrail_control') }}
+{{- register_metaparam('keepalived_vip_priority', 'opencontrail_control') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/opencontrail_gateway" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/opencontrail_gateway"
new file mode 100644
index 0000000..a75b537
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/opencontrail_gateway"
@@ -0,0 +1,9 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.opencontrail.gateway
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/opencontrail_tor" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/opencontrail_tor"
new file mode 100644
index 0000000..0af03a4
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/opencontrail_tor"
@@ -0,0 +1,11 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.opencontrail.tor
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('keepalived_vip_priority', 'opencontrail_tor') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_baremetal" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_baremetal"
new file mode 100644
index 0000000..33c0294
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_baremetal"
@@ -0,0 +1,11 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.openstack.baremetal
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('keepalived_vip_priority', 'openstack_baremetal') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_benchmark" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_benchmark"
new file mode 100644
index 0000000..93b92aa
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_benchmark"
@@ -0,0 +1,9 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.openstack.benchmark
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_billing" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_billing"
new file mode 100644
index 0000000..a78fae9
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_billing"
@@ -0,0 +1,9 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.openstack.billing
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_catalog" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_catalog"
new file mode 100644
index 0000000..8d95fce
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_catalog"
@@ -0,0 +1,11 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.openstack.catalog
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('keepalived_vip_priority', 'openstack_catalog') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_control" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_control"
index dcf605c..cf49380 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_control"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_control"
@@ -6,4 +6,6 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - cluster.${_param:cluster_name}.openstack.control
\ No newline at end of file
+          - cluster.${_param:cluster_name}.openstack.control
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('keepalived_vip_priority', 'openstack_control') }}
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_control_leader" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_control_leader"
index 935fd62..3a49d2a 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_control_leader"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_control_leader"
@@ -6,5 +6,5 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - cluster.${_param:cluster_name}.openstack.control
+          {%- include ("{# roles #}/" + 'openstack_control') %}
           - cluster.${_param:cluster_name}.openstack.control_init
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_control_upgrade" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_control_upgrade"
new file mode 100644
index 0000000..24bbddc
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_control_upgrade"
@@ -0,0 +1,9 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.openstack.upgrade
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_dashboard" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_dashboard"
new file mode 100644
index 0000000..65751e9
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_dashboard"
@@ -0,0 +1,9 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.openstack.dashboard
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_database" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_database"
index 68aff16..c5594e7 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_database"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_database"
@@ -6,4 +6,7 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - cluster.${_param:cluster_name}.openstack.database
\ No newline at end of file
+          - cluster.${_param:cluster_name}.openstack.database
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('mysql_cluster_role', 'openstack_database') }}
+{{- register_metaparam('keepalived_vip_priority', 'openstack_database') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_database_leader" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_database_leader"
index fa435ae..1f855fe 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_database_leader"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_database_leader"
@@ -6,5 +6,5 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - cluster.${_param:cluster_name}.openstack.database
+          {%- include ("{# roles #}/" + 'openstack_database') %}
           - cluster.${_param:cluster_name}.openstack.database_init
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_dns" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_dns"
new file mode 100644
index 0000000..b5cc3d2
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_dns"
@@ -0,0 +1,11 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.openstack.dns
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('keepalived_vip_priority', 'openstack_dns') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_gateway_octavia" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_gateway_octavia"
new file mode 100644
index 0000000..35edfae
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_gateway_octavia"
@@ -0,0 +1,10 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - cluster.${_param:cluster_name}.openstack.gateway
+          - cluster.${_param:cluster_name}.openstack.octavia_manager
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_message_queue" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_message_queue"
index a506c90..13bea9c 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_message_queue"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_message_queue"
@@ -6,4 +6,7 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - cluster.${_param:cluster_name}.openstack.message_queue
\ No newline at end of file
+          - cluster.${_param:cluster_name}.openstack.message_queue
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('rabbitmq_cluster_role', 'openstack_message_queue') }}
+{{- register_metaparam('keepalived_vip_priority', 'openstack_message_queue') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_proxy" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_proxy"
index 2cb0710..0fda65e 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_proxy"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_proxy"
@@ -6,4 +6,6 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - cluster.${_param:cluster_name}.openstack.proxy
\ No newline at end of file
+          - cluster.${_param:cluster_name}.openstack.proxy
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('keepalived_vip_priority', 'openstack_proxy') }}
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_telemetry" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_telemetry"
index 67e284b..59d6343 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_telemetry"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/openstack_telemetry"
@@ -6,4 +6,6 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - cluster.${_param:cluster_name}.openstack.telemetry
\ No newline at end of file
+          - cluster.${_param:cluster_name}.openstack.telemetry
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('keepalived_vip_priority', 'openstack_telemetry') }}
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_log" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_log"
index 698ffbe..de09752 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_log"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_log"
@@ -7,4 +7,6 @@
           classes:
 #}
           - cluster.${_param:cluster_name}.stacklight.log
-          - cluster.${_param:cluster_name}.stacklight.log_curator
\ No newline at end of file
+          - cluster.${_param:cluster_name}.stacklight.log_curator
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('keepalived_vip_priority', 'stacklight_log') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_log_leader" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_log_leader"
index 48c4b1c..83b59d6 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_log_leader"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_log_leader"
@@ -6,6 +6,6 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - cluster.${_param:cluster_name}.stacklight.log
+          {%- include ("{# roles #}/" + 'stacklight_log') %}
           - cluster.${_param:cluster_name}.stacklight.log_curator
           - system.elasticsearch.client.single
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_monitor" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_monitor"
index 726ba7c..f508816 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_monitor"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_monitor"
@@ -6,4 +6,7 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - cluster.${_param:cluster_name}.stacklight.monitor
\ No newline at end of file
+          - cluster.${_param:cluster_name}.stacklight.monitor
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('redis_cluster_role', 'stacklight_monitor') }}
+{{- register_metaparam('keepalived_vip_priority', 'stacklight_monitor') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_monitor_leader" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_monitor_leader"
index 5cc8cb5..ae6d3c4 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_monitor_leader"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_monitor_leader"
@@ -6,6 +6,6 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - cluster.${_param:cluster_name}.stacklight.monitor
+          {%- include ("{# roles #}/" + 'stacklight_monitor') %}
           - system.grafana.client.single
           - system.kibana.client.single
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_telemetry" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_telemetry"
index 8b17922..e5b9c7b 100644
--- "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_telemetry"
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklight_telemetry"
@@ -6,4 +6,6 @@
         <reclass_storage_node_name>:
           classes:
 #}
-          - cluster.${_param:cluster_name}.stacklight.telemetry
\ No newline at end of file
+          - cluster.${_param:cluster_name}.stacklight.telemetry
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('keepalived_vip_priority', 'stacklight_telemetry') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklightv2_server" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklightv2_server"
new file mode 100644
index 0000000..773dc1c
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklightv2_server"
@@ -0,0 +1,13 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          - system.docker.swarm.manager
+          - cluster.${_param:cluster_name}.stacklight.server
+{{- set_param('keepalived_vip_interface', 'br_ctl') }}
+{{- register_metaparam('redis_cluster_role', 'stacklightv2_server') }}
+{{- register_metaparam('keepalived_vip_priority', 'stacklightv2_server') }}
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklightv2_server_leader" "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklightv2_server_leader"
new file mode 100644
index 0000000..7e4f4ca
--- /dev/null
+++ "b/tcp_tests/environment/environment_template/\173\043 roles \043\175/stacklightv2_server_leader"
@@ -0,0 +1,10 @@
+{#-
+parameters:
+  reclass:
+    storage:
+      node:
+        <reclass_storage_node_name>:
+          classes:
+#}
+          {%- include ("{# roles #}/" + 'stacklightv2_server') %}
+          - cluster.${_param:cluster_name}.stacklight.client
\ No newline at end of file
diff --git "a/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/init.yml" "b/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/init.yml"
index c1c1b12..89db66f 100644
--- "a/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/init.yml"
+++ "b/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/init.yml"
@@ -1,5 +1,9 @@
 {# 'infra_config_classes' list object is dynamically generated from 'roles' to add on the cfg node #}
 {%- set infra_config_classes = [] %}
+{# 'global_metadata' is a global collection of objects shared between nodes #}
+{%- set global_metadata = {} %}
+{%- set common_roles = ['_linux_network_interface', '_metadata_process', '_overrides'] %}
+
 parameters:
   _param:
     _esc: $
@@ -9,12 +13,27 @@
       {%- for inventory_node_name, node in nodes.items()|sort %}
         {%- set node_name = inventory_node_name.split('.')[0] %}
         {{ node['reclass_storage_name'] }}:
-        {# 'params' dict object is dynamically generated from 'roles' to add on the node #}
-        {%- set params = {} %}
+
+          {#- 'local_metadata' is to collect the data from different roles in a single place inside the node #}
+          {%- set local_metadata = {} %}
+          {#- 'params' dict object is dynamically generated from 'roles' to add on the node #}
+          {%- set params = {} %}
+
+          {%- macro register_metaparam(param_name, role_name) %}
+          {#- Add the <role_name> into the list attached to <param_name> #}
+          {#- to control that the <param_name> is not spreaded across incompatible roles #}
+            {%- set _ = local_metadata.update({param_name: local_metadata.get(param_name, []) + [role_name]}) %}
+          {%- endmacro %}
+
+          {%- macro set_param(param_name, param_value) %}
+          {#- Set a parameter for '_param' dict for the node #}
+            {%- set _ = params.update({param_name: param_value}) %}
+          {%- endmacro %}
+
           classes:
           {#- Default roles are added to each node #}
           {#- 'overrides' must be the very last role for each node #}
-          {%- for role in node.get('roles', []) + ['linux_network_interface', 'overrides'] %}
+          {%- for role in node.get('roles', []) + common_roles %}
             {%- include ("{# roles #}/" + role) %}
           {%- endfor %}
 
diff --git "a/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/linux_network_interface.yml" "b/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/linux_network_interface.yml"
index f74e880..8474d17 100644
--- "a/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/linux_network_interface.yml"
+++ "b/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/linux_network_interface.yml"
@@ -1,6 +1,3 @@
-classes:
-# Enable root and *ALL* users access
-- system.openssh.server.team.all
 parameters:
   # _param:
   # Put overrides for any environment-specific variables here
diff --git "a/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/linux_system_codename_trusty.yml" "b/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/linux_system_codename_trusty.yml"
deleted file mode 100644
index 1510a00..0000000
--- "a/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/linux_system_codename_trusty.yml"
+++ /dev/null
@@ -1,3 +0,0 @@
-parameters:
-  _param:
-    linux_system_codename: trusty
diff --git "a/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/linux_system_codename_xenial.yml" "b/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/linux_system_codename_xenial.yml"
deleted file mode 100644
index c78c0b9..0000000
--- "a/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/linux_system_codename_xenial.yml"
+++ /dev/null
@@ -1,3 +0,0 @@
-parameters:
-  _param:
-    linux_system_codename: xenial
diff --git "a/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/overrides.yml" "b/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/overrides.yml"
index 39735bc..5a2e28e 100644
--- "a/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/overrides.yml"
+++ "b/tcp_tests/environment/environment_template/\173\173 cookiecutter._env_name \175\175/overrides.yml"
@@ -1,6 +1,18 @@
 # Do not delete! This file is for global parameters overrides over all the nodes in the environment.
-# Example: salt-call reclass.cluster_meta_set foo bar
+classes:
+# Enable root and *ALL* users access
+- system.openssh.server.team.all
+
+# Example: salt-call reclass.cluster_meta_set foo bar /path/to/overrides.yml
 #parameters:
 #  _param:
-#    cluster_public_protocol: http
-#    neutron_public_protocol: http
+#    foo: bar
+parameters:
+  openssh:
+    server:
+      password_auth: true
+  linux:
+    system:
+      user:
+        root:
+          password: $6$oV7iKxfx$7DOZUfLw30d/W.pzUf97F0z1JhxgNmFAiKT1HhIodjkWb0M/.dTYAc3uxDCScR3lvCALjRe4/xWtiDyywf8wi1