Convert PublicVirtualIP to new port creation method
[apex-tripleo-heat-templates.git] / overcloud-without-mergepy.yaml
index 7c2c3a2..d9190ea 100644 (file)
@@ -58,12 +58,6 @@ parameters:
     default: ''
     description: Set to True to enable debugging on all services.
     type: string
-  DefaultSignalTransport:
-    default: CFN_SIGNAL
-    description: Transport to use for software-config signals.
-    type: string
-    constraints:
-      - allowed_values: [ CFN_SIGNAL, HEAT_SIGNAL, NO_SIGNAL ]
   GlancePort:
     default: "9292"
     description: Glance port.
@@ -82,6 +76,10 @@ parameters:
     type: string
     constraints:
       - custom_constraint: nova.keypair
+  NeutronExternalNetworkBridge:
+    description: Name of bridge used for external network traffic.
+    type: string
+    default: 'br-ex'
   NeutronBridgeMappings:
     description: >
       The OVS logical->physical bridge mappings to use. See the Neutron
@@ -164,6 +162,10 @@ parameters:
     default: 'False'
     description: Whether to enable l3-agent HA
     type: string
+  NeutronDhcpAgentsPerNetwork:
+    type: number
+    default: 3
+    description: The number of neutron dhcp agents to schedule per network
   NovaPassword:
     default: unset
     description: The password for the nova service account, used by nova-api.
@@ -178,11 +180,6 @@ parameters:
         Control the IP allocation for the PublicVirtualInterface port. E.g.
         [{'ip_address':'1.2.3.4'}]
     type: json
-  PublicVirtualNetwork:
-    default: 'ctlplane'
-    type: string
-    description: >
-        Neutron network to allocate public virtual IP port on.
   RabbitCookieSalt:
     type: string
     default: unset
@@ -263,15 +260,14 @@ parameters:
     default: 'br-ex'
     description: Interface where virtual ip will be assigned.
     type: string
+  EnableFencing:
+    default: false
+    description: Whether to enable fencing in Pacemaker or not.
+    type: boolean
   EnableGalera:
     default: true
     description: Whether to use Galera instead of regular MariaDB.
     type: boolean
-  EnablePacemaker:
-    default: false
-    description: If enabled services will be monitored by Pacemaker; it
-      will manage VIPs as well, in place of Keepalived.
-    type: boolean
   ControllerEnableCephStorage:
     default: false
     description: Whether to deploy Ceph Storage (OSD) on the Controller
@@ -318,6 +314,38 @@ parameters:
           }
         }
     type: json
+  FencingConfig:
+    default: {}
+    description: |
+      Pacemaker fencing configuration. The JSON should have
+      the following structure:
+        {
+          "devices": [
+            {
+              "agent": "AGENT_NAME",
+              "host_mac": "HOST_MAC_ADDRESS",
+              "params": {"PARAM_NAME": "PARAM_VALUE"}
+            }
+          ]
+        }
+      For instance:
+        {
+          "devices": [
+            {
+              "agent": "fence_xvm",
+              "host_mac": "52:54:00:aa:bb:cc",
+              "params": {
+                "multicast_address": "225.0.0.12",
+                "port": "baremetal_0",
+                "manage_fw": true,
+                "manage_key_file": true,
+                "key_file": "/etc/fence_xvm.key",
+                "key_file_password": "abcdef"
+              }
+            }
+          ]
+        }
+    type: json
   GlanceLogFile:
     description: The filepath of the file to use for logging messages from Glance.
     type: string
@@ -377,6 +405,10 @@ parameters:
         lower level default.
     type: number
     default: 0
+  MysqlMaxConnections:
+    description: Configures MySQL max_connections config setting
+    type: number
+    default: 1024
   NeutronDnsmasqOptions:
     default: 'dhcp-option-force=26,1400'
     description: Dnsmasq options for neutron-dhcp-agent. The default value here forces MTU to be set to 1400 to account for the tunnel overhead.
@@ -467,7 +499,7 @@ parameters:
       The Neutron ML2 and OpenVSwitch vlan mapping range to support. See the
       Neutron documentation for permitted values. Defaults to permitting any
       VLAN on the 'datacentre' physical network (See NeutronBridgeMappings).
-    type: string
+    type: comma_delimited_list
   NovaComputeDriver:
     type: string
     default: libvirt.LibvirtDriver
@@ -494,6 +526,39 @@ parameters:
     type: string
     constraints:
       - custom_constraint: nova.flavor
+  ServiceNetMap:
+    default:
+      NeutronTenantNetwork: tenant
+      CeilometerApiNetwork: internal_api
+      MongoDbNetwork: internal_api
+      CinderApiNetwork: internal_api
+      CinderIscsiNetwork: storage
+      GlanceApiNetwork: storage
+      GlanceRegistryNetwork: internal_api
+      KeystoneAdminApiNetwork: internal_api
+      KeystonePublicApiNetwork: internal_api
+      NeutronApiNetwork: internal_api
+      HeatApiNetwork: internal_api
+      NovaApiNetwork: internal_api
+      NovaMetadataNetwork: internal_api
+      NovaVncProxyNetwork: internal_api
+      SwiftMgmtNetwork: storage_mgmt
+      SwiftProxyNetwork: storage
+      HorizonNetwork: internal_api
+      MemcachedNetwork: internal_api
+      RabbitMqNetwork: internal_api
+      RedisNetwork: internal_api
+      MysqlNetwork: internal_api
+      CephClusterNetwork: storage_mgmt
+      CephPublicNetwork: storage
+      ControllerHostnameResolveNetwork: internal_api
+      ComputeHostnameResolveNetwork: internal_api
+      BlockStorageHostnameResolveNetwork: internal_api
+      ObjectStorageHostnameResolveNetwork: internal_api
+      CephStorageHostnameResolveNetwork: storage
+    description: Mapping of service_name -> network name. Typically set
+                 via parameter_defaults in the resource registry.
+    type: json
 
 # Block storage specific parameters
   BlockStorageCount:
@@ -535,6 +600,74 @@ parameters:
     constraints:
       - custom_constraint: nova.flavor
 
+  # Hostname format for each role
+  # Note %index% is translated into the index of the node, e.g 0/1/2 etc
+  # and %stackname% is replaced with OS::stack_name in the template below.
+  # If you want to use the heat generated names, pass '' (empty string).
+  ControllerHostnameFormat:
+    type: string
+    description: Format for Controller node hostnames
+    default: '%stackname%-controller-%index%'
+  ComputeHostnameFormat:
+    type: string
+    description: Format for Compute node hostnames
+    default: '%stackname%-novacompute-%index%'
+  BlockStorageHostnameFormat:
+    type: string
+    description: Format for BlockStorage node hostnames
+    default: '%stackname%-blockstorage-%index%'
+  ObjectStorageHostnameFormat:
+    type: string
+    description: Format for SwiftStorage node hostnames
+    default: '%stackname%-objectstorage-%index%'
+  CephStorageHostnameFormat:
+    type: string
+    description: Format for CephStorage node hostnames
+    default: '%stackname%-cephstorage-%index%'
+
+  # Identifiers to trigger tasks on nodes
+  UpdateIdentifier:
+    default: ''
+    type: string
+    description: >
+      Setting to a previously unused value during stack-update will trigger
+      package update on all nodes
+
+  # If you want to remove a specific node from a resource group, you can pass
+  # the node name or id as a <Group>RemovalPolicies parameter, for example:
+  # ComputeRemovalPolicies: [{'resource_list': ['0']}]
+  ControllerRemovalPolicies:
+    default: []
+    type: json
+    description: >
+      List of resources to be removed from ControllerResourceGroup when
+      doing an update which requires removal of specific resources.
+  ComputeRemovalPolicies:
+    default: []
+    type: json
+    description: >
+      List of resources to be removed from ComputeResourceGroup when
+      doing an update which requires removal of specific resources.
+  BlockStorageRemovalPolicies:
+    default: []
+    type: json
+    description: >
+      List of resources to be removed from BlockStorageResourceGroup when
+      doing an update which requires removal of specific resources.
+  ObjectStorageRemovalPolicies:
+    default: []
+    type: json
+    description: >
+      List of resources to be removed from ObjectStorageResourceGroup when
+      doing an update which requires removal of specific resources.
+  CephStorageRemovalPolicies:
+    default: []
+    type: json
+    description: >
+      List of resources to be removed from CephStorageResourceGroup when
+      doing an update which requires removal of specific resources.
+
+
 resources:
 
   HeatAuthEncryptionKey:
@@ -555,6 +688,7 @@ resources:
     depends_on: Networks
     properties:
       count: {get_param: ControllerCount}
+      removal_policies: {get_param: ControllerRemovalPolicies}
       resource_def:
         type: OS::TripleO::Controller
         properties:
@@ -572,11 +706,12 @@ resources:
           ControlVirtualInterface: {get_param: ControlVirtualInterface}
           ControllerExtraConfig: {get_param: controllerExtraConfig}
           Debug: {get_param: Debug}
+          EnableFencing: {get_param: EnableFencing}
           EnableGalera: {get_param: EnableGalera}
-          EnablePacemaker: {get_param: EnablePacemaker}
           EnableCephStorage: {get_param: ControllerEnableCephStorage}
           EnableSwiftStorage: {get_param: ControllerEnableSwiftStorage}
           ExtraConfig: {get_param: ExtraConfig}
+          FencingConfig: {get_param: FencingConfig}
           Flavor: {get_param: OvercloudControlFlavor}
           GlancePort: {get_param: GlancePort}
           GlanceProtocol: {get_param: GlanceProtocol}
@@ -598,10 +733,13 @@ resources:
           KeystoneSSLCertificateKey: {get_param: KeystoneSSLCertificateKey}
           MysqlClusterUniquePart: {get_attr: [MysqlClusterUniquePart, value]}
           MysqlInnodbBufferPoolSize: {get_param: MysqlInnodbBufferPoolSize}
+          MysqlMaxConnections: {get_param: MysqlMaxConnections}
           MysqlRootPassword: {get_attr: [MysqlRootPassword, value]}
           NeutronPublicInterfaceIP: {get_param: NeutronPublicInterfaceIP}
           NeutronFlatNetworks: {get_param: NeutronFlatNetworks}
           NeutronBridgeMappings: {get_param: NeutronBridgeMappings}
+          NeutronExternalNetworkBridge: {get_param: NeutronExternalNetworkBridge}
+          NeutronEnableTunnelling: {get_param: NeutronEnableTunnelling}
           NeutronNetworkVLANRanges: {get_param: NeutronNetworkVLANRanges}
           NeutronPublicInterface: {get_param: NeutronPublicInterface}
           NeutronPublicInterfaceDefaultRoute: {get_param: NeutronPublicInterfaceDefaultRoute}
@@ -614,6 +752,7 @@ resources:
           NeutronMechanismDrivers: {get_param: NeutronMechanismDrivers}
           NeutronAllowL3AgentFailover: {get_param: NeutronAllowL3AgentFailover}
           NeutronL3HA: {get_param: NeutronL3HA}
+          NeutronDhcpAgentsPerNetwork: {get_param: NeutronDhcpAgentsPerNetwork}
           NeutronNetworkType: {get_param: NeutronNetworkType}
           NeutronTunnelTypes: {get_param: NeutronTunnelTypes}
           NovaPassword: {get_param: NovaPassword}
@@ -627,6 +766,7 @@ resources:
           RabbitClientPort: {get_param: RabbitClientPort}
           SnmpdReadonlyUserName: {get_param: SnmpdReadonlyUserName}
           SnmpdReadonlyUserPassword: {get_param: SnmpdReadonlyUserPassword}
+          RedisVirtualIP: {get_attr: [RedisVirtualIP, ip_address]}
           SSLCertificate: {get_param: SSLCertificate}
           SSLKey: {get_param: SSLKey}
           SSLCACertificate: {get_param: SSLCACertificate}
@@ -636,14 +776,27 @@ resources:
           SwiftPartPower: {get_param: SwiftPartPower}
           SwiftPassword: {get_param: SwiftPassword}
           SwiftReplicas: { get_param: SwiftReplicas}
-          VirtualIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
-          PublicVirtualIP: {get_attr: [PublicVirtualIP, fixed_ips, 0, ip_address]}
+          VirtualIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]} # deprecated. Use per service VIP settings instead now.
+          PublicVirtualIP: {get_attr: [PublicVirtualIP, ip_address]}
+          ServiceNetMap: {get_param: ServiceNetMap}
+          HeatApiVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, HeatApiNetwork]}]}
+          GlanceApiVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, GlanceApiNetwork]}]}
+          MysqlVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, MysqlNetwork]}]}
+          KeystonePublicApiVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, KeystonePublicApiNetwork]}]}
+          NeutronApiVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, NeutronApiNetwork]}]}
+          UpdateIdentifier: {get_param: UpdateIdentifier}
+          Hostname:
+            str_replace:
+              template: {get_param: ControllerHostnameFormat}
+              params:
+                '%stackname%': {get_param: 'OS::stack_name'}
 
   Compute:
     type: OS::Heat::ResourceGroup
     depends_on: Networks
     properties:
       count: {get_param: ComputeCount}
+      removal_policies: {get_param: ComputeRemovalPolicies}
       resource_def:
         type: OS::TripleO::Compute
         properties:
@@ -654,17 +807,17 @@ resources:
           Debug: {get_param: Debug}
           ExtraConfig: {get_param: ExtraConfig}
           Flavor: {get_param: OvercloudComputeFlavor}
-          GlanceHost: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+          GlanceHost: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, GlanceApiNetwork]}]}
           GlancePort: {get_param: GlancePort}
           GlanceProtocol: {get_param: GlanceProtocol}
           Image: {get_param: NovaImage}
           ImageUpdatePolicy: {get_param: ImageUpdatePolicy}
           KeyName: {get_param: KeyName}
-          KeystoneHost: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+          KeystoneHost: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, KeystonePublicApiNetwork]}]}
           NeutronBridgeMappings: {get_param: NeutronBridgeMappings}
           NeutronEnableTunnelling: {get_param: NeutronEnableTunnelling}
           NeutronFlatNetworks: {get_param: NeutronFlatNetworks}
-          NeutronHost: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+          NeutronHost: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, NeutronApiNetwork]}]}
           NeutronNetworkType: {get_param: NeutronNetworkType}
           NeutronTunnelTypes: {get_param: NeutronTunnelTypes}
           NeutronNetworkVLANRanges: {get_param: NeutronNetworkVLANRanges}
@@ -679,27 +832,35 @@ resources:
           # L3 HA and Failover is not relevant for Computes, should be removed
           NeutronAllowL3AgentFailover: {get_param: NeutronAllowL3AgentFailover}
           NeutronL3HA: {get_param: NeutronL3HA}
-          NovaApiHost: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+          NovaApiHost: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, NovaApiNetwork]}]}
           NovaComputeDriver: {get_param: NovaComputeDriver}
           NovaComputeExtraConfig: {get_param: NovaComputeExtraConfig}
           NovaComputeLibvirtType: {get_param: NovaComputeLibvirtType}
           NovaEnableRbdBackend: {get_param: NovaEnableRbdBackend}
-          NovaPublicIP: {get_attr: [PublicVirtualIP, fixed_ips, 0, ip_address]}
+          NovaPublicIP: {get_attr: [PublicVirtualIP, ip_address]}
           NovaPassword: {get_param: NovaPassword}
           NtpServer: {get_param: NtpServer}
-          RabbitHost: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+          RabbitHost: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, RabbitMqNetwork]}]}
           RabbitPassword: {get_param: RabbitPassword}
           RabbitUserName: {get_param: RabbitUserName}
           RabbitClientUseSSL: {get_param: RabbitClientUseSSL}
           RabbitClientPort: {get_param: RabbitClientPort}
           SnmpdReadonlyUserName: {get_param: SnmpdReadonlyUserName}
           SnmpdReadonlyUserPassword: {get_param: SnmpdReadonlyUserPassword}
+          ServiceNetMap: {get_param: ServiceNetMap}
+          UpdateIdentifier: {get_param: UpdateIdentifier}
+          Hostname:
+            str_replace:
+              template: {get_param: ComputeHostnameFormat}
+              params:
+                '%stackname%': {get_param: 'OS::stack_name'}
 
   BlockStorage:
     type: OS::Heat::ResourceGroup
     depends_on: Networks
     properties:
       count: {get_param: BlockStorageCount}
+      removal_policies: {get_param: BlockStorageRemovalPolicies}
       resource_def:
         type: OS::TripleO::BlockStorage
         properties:
@@ -710,20 +871,32 @@ resources:
           # Purpose of the dedicated BlockStorage nodes should be to use their local LVM
           CinderEnableIscsiBackend: {get_param: CinderEnableIscsiBackend}
           CinderPassword: {get_param: CinderPassword}
-          VirtualIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
           KeyName: {get_param: KeyName}
           Flavor: {get_param: OvercloudBlockStorageFlavor}
+          VirtualIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+          GlancePort: {get_param: GlancePort}
+          GlanceProtocol: {get_param: GlanceProtocol}
+          GlanceApiVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, GlanceApiNetwork]}]}
           RabbitPassword: {get_param: RabbitPassword}
           RabbitUserName: {get_param: RabbitUserName}
           RabbitClientUseSSL: {get_param: RabbitClientUseSSL}
           RabbitClientPort: {get_param: RabbitClientPort}
           NtpServer: {get_param: NtpServer}
+          UpdateIdentifier: {get_param: UpdateIdentifier}
+          Hostname:
+            str_replace:
+              template: {get_param: BlockStorageHostnameFormat}
+              params:
+                '%stackname%': {get_param: 'OS::stack_name'}
+          ServiceNetMap: {get_param: ServiceNetMap}
+          MysqlVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, MysqlNetwork]}]}
 
   ObjectStorage:
     type: OS::Heat::ResourceGroup
     depends_on: Networks
     properties:
       count: {get_param: ObjectStorageCount}
+      removal_policies: {get_param: ObjectStorageRemovalPolicies}
       resource_def:
         type: OS::TripleO::ObjectStorage
         properties:
@@ -736,12 +909,20 @@ resources:
           Image: {get_param: SwiftStorageImage}
           Replicas: { get_param: SwiftReplicas}
           NtpServer: {get_param: NtpServer}
+          UpdateIdentifier: {get_param: UpdateIdentifier}
+          ServiceNetMap: {get_param: ServiceNetMap}
+          Hostname:
+            str_replace:
+              template: {get_param: ObjectStorageHostnameFormat}
+              params:
+                '%stackname%': {get_param: 'OS::stack_name'}
 
   CephStorage:
     type: OS::Heat::ResourceGroup
     depends_on: Networks
     properties:
       count: {get_param: CephStorageCount}
+      removal_policies: {get_param: CephStorageRemovalPolicies}
       resource_def:
         type: OS::TripleO::CephStorage
         properties:
@@ -749,6 +930,22 @@ resources:
           KeyName: {get_param: KeyName}
           Flavor: {get_param: OvercloudCephStorageFlavor}
           NtpServer: {get_param: NtpServer}
+          ServiceNetMap: {get_param: ServiceNetMap}
+          UpdateIdentifier: {get_param: UpdateIdentifier}
+          Hostname:
+            str_replace:
+              template: {get_param: CephStorageHostnameFormat}
+              params:
+                '%stackname%': {get_param: 'OS::stack_name'}
+
+  ControllerIpListMap:
+    type: OS::TripleO::Network::Ports::NetIpListMap
+    properties:
+      ExternalIpList: {get_attr: [Controller, external_ip_address]}
+      InternalApiIpList: {get_attr: [Controller, internal_api_ip_address]}
+      StorageIpList: {get_attr: [Controller, storage_ip_address]}
+      StorageMgmtIpList: {get_attr: [Controller, storage_mgmt_ip_address]}
+      TenantIpList: {get_attr: [Controller, tenant_ip_address]}
 
   allNodesConfig:
     type: OS::TripleO::AllNodes::SoftwareConfig
@@ -760,6 +957,23 @@ resources:
       object_storage_hosts: {get_attr: [ObjectStorage, hosts_entry]}
       ceph_storage_hosts: {get_attr: [CephStorage, hosts_entry]}
       controller_names: {get_attr: [Controller, hostname]}
+      rabbit_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, RabbitMqNetwork]}]}
+      mongo_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, MongoDbNetwork]}]}
+      redis_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, RedisNetwork]}]}
+      memcache_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, MemcachedNetwork]}]}
+      mysql_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, MysqlNetwork]}]}
+      horizon_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, HorizonNetwork]}]}
+      heat_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, HeatApiNetwork]}]}
+      swift_proxy_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, SwiftProxyNetwork]}]}
+      ceilometer_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, CeilometerApiNetwork]}]}
+      nova_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, NovaApiNetwork]}]}
+      nova_metadata_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, NovaMetadataNetwork]}]}
+      glance_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, GlanceApiNetwork]}]}
+      glance_registry_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, GlanceRegistryNetwork]}]}
+      cinder_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, CinderApiNetwork]}]}
+      neutron_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, NeutronApiNetwork]}]}
+      keystone_public_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, KeystonePublicApiNetwork]}]}
+      keystone_admin_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, KeystoneAdminApiNetwork]}]}
 
   MysqlRootPassword:
     type: OS::Heat::RandomString
@@ -790,14 +1004,86 @@ resources:
       fixed_ips: {get_param: ControlFixedIPs}
       replacement_policy: AUTO
 
+  RedisVirtualIP:
+    depends_on: Networks
+    type: OS::TripleO::Controller::Ports::RedisVipPort
+    properties:
+      ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+      ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
+      PortName: redis_virtual_ip
+      NetworkName: {get_param: [ServiceNetMap, RedisNetwork]}
+
+  # The public VIP is on the External net, falls back to ctlplane
   PublicVirtualIP:
-    type: OS::Neutron::Port
     depends_on: Networks
+    type: OS::TripleO::Controller::Ports::ExternalPort
     properties:
-      name: public_virtual_ip
-      network: {get_param: PublicVirtualNetwork}
-      fixed_ips: {get_param: PublicVirtualFixedIPs}
-      replacement_policy: AUTO
+      ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+      ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
+      PortName: public_virtual_ip
+      FixedIPs: {get_param: PublicVirtualFixedIPs}
+
+  InternalApiVirtualIP:
+    depends_on: Networks
+    type: OS::TripleO::Controller::Ports::InternalApiPort
+    properties:
+      ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+      PortName: internal_api_virtual_ip
+
+  StorageVirtualIP:
+    depends_on: Networks
+    type: OS::TripleO::Controller::Ports::StoragePort
+    properties:
+      ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+      PortName: storage_virtual_ip
+
+  StorageMgmtVirtualIP:
+    depends_on: Networks
+    type: OS::TripleO::Controller::Ports::StorageMgmtPort
+    properties:
+      ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+      PortName: storage_management_virtual_ip
+
+  VipMap:
+    type: OS::TripleO::Network::Ports::NetIpMap
+    properties:
+      ExternalIp: {get_attr: [PublicVirtualIP, ip_address]}
+      InternalApiIp: {get_attr: [InternalApiVirtualIP, ip_address]}
+      StorageIp: {get_attr: [StorageVirtualIP, ip_address]}
+      StorageMgmtIp: {get_attr: [StorageMgmtVirtualIP, ip_address]}
+      # No tenant VIP required
+
+  VipConfig:
+    type: OS::TripleO::VipConfig
+
+  VipDeployment:
+    type: OS::Heat::StructuredDeployments
+    properties:
+      config: {get_resource: VipConfig}
+      servers: {get_attr: [Controller, attributes, nova_server_resource]}
+      input_values:
+        # service VIP mappings
+        keystone_admin_api_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, KeystoneAdminApiNetwork]}]}
+        keystone_public_api_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, KeystonePublicApiNetwork]}]}
+        neutron_api_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, NeutronApiNetwork]}]}
+        cinder_api_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, CinderApiNetwork]}]}
+        glance_api_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, GlanceApiNetwork]}]}
+        glance_registry_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, GlanceRegistryNetwork]}]}
+        swift_proxy_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, SwiftProxyNetwork]}]}
+        nova_api_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, NovaApiNetwork]}]}
+        nova_metadata_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, NovaMetadataNetwork]}]}
+        ceilometer_api_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, CeilometerApiNetwork]}]}
+        heat_api_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, HeatApiNetwork]}]}
+        horizon_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, HorizonNetwork]}]}
+        redis_vip: {get_attr: [RedisVirtualIP, ip_address]}
+        mysql_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, MysqlNetwork]}]}
+        rabbit_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, RabbitMqNetwork]}]}
+        # direct configuration of Virtual IPs for each network
+        control_virtual_ip: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+        public_virtual_ip: {get_attr: [PublicVirtualIP, ip_address]}
+        internal_api_virtual_ip: {get_attr: [InternalApiVirtualIP, ip_address]}
+        storage_virtual_ip: {get_attr: [StorageVirtualIP, ip_address]}
+        storage_mgmt_virtual_ip: {get_attr: [StorageMgmtVirtualIP, ip_address]}
 
   ControllerBootstrapNodeConfig:
     type: OS::TripleO::BootstrapNode::SoftwareConfig
@@ -810,21 +1096,18 @@ resources:
     properties:
       config: {get_attr: [ControllerBootstrapNodeConfig, config_id]}
       servers: {get_attr: [Controller, attributes, nova_server_resource]}
-      signal_transport: NO_SIGNAL
 
   ControllerSwiftDeployment:
     type: OS::Heat::StructuredDeployments
     properties:
       config: {get_attr: [SwiftDevicesAndProxyConfig, config_id]}
       servers: {get_attr: [Controller, attributes, nova_server_resource]}
-      signal_transport: NO_SIGNAL
 
   ObjectStorageSwiftDeployment:
     type: OS::Heat::StructuredDeployments
     properties:
       config: {get_attr: [SwiftDevicesAndProxyConfig, config_id]}
       servers: {get_attr: [ObjectStorage, attributes, nova_server_resource]}
-      signal_transport: NO_SIGNAL
 
   SwiftDevicesAndProxyConfig:
     type: OS::TripleO::SwiftDevicesAndProxy::SoftwareConfig
@@ -858,11 +1141,12 @@ resources:
       ceph_mon_key: {get_param: CephMonKey}
       ceph_admin_key: {get_param: CephAdminKey}
       ceph_mon_names: {get_attr: [Controller, hostname]}
-      ceph_mon_ips: {get_attr: [Controller, ip_address]}
+      ceph_mon_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, CephPublicNetwork]}]}
 
   ControllerClusterConfig:
     type: OS::Heat::StructuredConfig
     properties:
+      group: os-apply-config
       config:
         corosync:
           nodes: {get_attr: [Controller, corosync_node]}
@@ -880,7 +1164,6 @@ resources:
     properties:
       config: {get_resource: ControllerClusterConfig}
       servers: {get_attr: [Controller, attributes, nova_server_resource]}
-      signal_transport: NO_SIGNAL
 
   ControllerAllNodesDeployment:
     type: OS::Heat::StructuredDeployments
@@ -918,30 +1201,36 @@ resources:
     depends_on: [ControllerBootstrapNodeDeployment, ControllerAllNodesDeployment, ControllerSwiftDeployment, ControllerCephDeployment]
     properties:
       servers: {get_attr: [Controller, attributes, nova_server_resource]}
+      NodeConfigIdentifiers: {get_attr: [Controller, attributes, config_identifier]}
 
   ComputeNodesPostDeployment:
     type: OS::TripleO::ComputePostDeployment
     depends_on: [ComputeAllNodesDeployment, ComputeCephDeployment]
     properties:
       servers: {get_attr: [Compute, attributes, nova_server_resource]}
+      NodeConfigIdentifiers: {get_attr: [Compute, attributes, config_identifier]}
 
   ObjectStorageNodesPostDeployment:
     type: OS::TripleO::ObjectStoragePostDeployment
     depends_on: [ObjectStorageSwiftDeployment, ObjectStorageAllNodesDeployment]
     properties:
       servers: {get_attr: [ObjectStorage, attributes, nova_server_resource]}
+      NodeConfigIdentifiers: {get_attr: [ObjectStorage, attributes, config_identifier]}
+
 
   BlockStorageNodesPostDeployment:
     type: OS::TripleO::BlockStoragePostDeployment
     depends_on: [ControllerNodesPostDeployment, BlockStorageAllNodesDeployment]
     properties:
       servers: {get_attr: [BlockStorage, attributes, nova_server_resource]}
+      NodeConfigIdentifiers: {get_attr: [BlockStorage, attributes, config_identifier]}
 
   CephStorageNodesPostDeployment:
     type: OS::TripleO::CephStoragePostDeployment
     depends_on: [ControllerNodesPostDeployment, CephStorageCephDeployment, CephStorageAllNodesDeployment]
     properties:
       servers: {get_attr: [CephStorage, attributes, nova_server_resource]}
+      NodeConfigIdentifiers: {get_attr: [CephStorage, attributes, config_identifier]}
 
 outputs:
   KeystoneURL:
@@ -950,5 +1239,32 @@ outputs:
       list_join:
       - ''
       - - http://
-        - {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+        - {get_attr: [PublicVirtualIP, ip_address]}
         - :5000/v2.0/
+  PublicVip:
+    description: Controller VIP for public API endpoints
+    value: {get_attr: [PublicVirtualIP, ip_address]}
+  CeilometerInternalVip:
+    description: VIP for Ceilometer API internal endpoint
+    value: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, CeilometerApiNetwork]}]}
+  CinderInternalVip:
+    description: VIP for Cinder API internal endpoint
+    value: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, CinderApiNetwork]}]}
+  GlanceInternalVip:
+    description: VIP for Glance API internal endpoint
+    value: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, GlanceApiNetwork]}]}
+  HeatInternalVip:
+    description: VIP for Heat API internal endpoint
+    value: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, HeatApiNetwork]}]}
+  KeystoneInternalVip:
+    description: VIP for Keystone API internal endpoint
+    value: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, KeystonePublicApiNetwork]}]}
+  NeutronInternalVip:
+    description: VIP for Neutron API internal endpoint
+    value: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, NeutronApiNetwork]}]}
+  NovaInternalVip:
+    description: VIP for Nova API internal endpoint
+    value: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, NovaApiNetwork]}]}
+  SwiftInternalVip:
+    description: VIP for Swift Proxy internal endpoint
+    value: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, SwiftProxyNetwork]}]}