OS::TripleO::Services::Keystone: ../puppet/services/pacemaker/keystone.yaml
   OS::TripleO::Services::GlanceApi: ../puppet/services/pacemaker/glance-api.yaml
   OS::TripleO::Services::GlanceRegistry: ../puppet/services/pacemaker/glance-registry.yaml
+  OS::TripleO::Services::HeatApi: ../puppet/services/pacemaker/heat-api.yaml
+  OS::TripleO::Services::HeatApiCfn: ../puppet/services/pacemaker/heat-api-cfn.yaml
+  OS::TripleO::Services::HeatApiCloudwatch: ../puppet/services/pacemaker/heat-api-cloudwatch.yaml
+  OS::TripleO::Services::HeatEngine: ../puppet/services/pacemaker/heat-engine.yaml
   OS::TripleO::Services::NeutronDhcpAgent: ../puppet/services/pacemaker/neutron-dhcp.yaml
 
   OS::TripleO::Services::Keystone: puppet/services/keystone.yaml
   OS::TripleO::Services::GlanceApi: puppet/services/glance-api.yaml
   OS::TripleO::Services::GlanceRegistry: puppet/services/glance-registry.yaml
+  OS::TripleO::Services::HeatApi: puppet/services/heat-api.yaml
+  OS::TripleO::Services::HeatApiCfn: puppet/services/heat-api-cfn.yaml
+  OS::TripleO::Services::HeatApiCloudwatch: puppet/services/heat-api-cloudwatch.yaml
+  OS::TripleO::Services::HeatEngine: puppet/services/heat-engine.yaml
   OS::TripleO::Services::NeutronDhcpAgent: puppet/services/neutron-dhcp.yaml
 
 parameter_defaults:
 
     description: The password for the gnocchi service account.
     type: string
     hidden: true
-  HeatPassword:
-    description: The password for the Heat service account, used by the Heat services.
-    type: string
-    hidden: true
-  HeatStackDomainAdminPassword:
-    description: Password for heat_stack_domain_admin user.
-    type: string
-    hidden: true
   InstanceNameTemplate:
     default: 'instance-%08x'
     description: Template string to be used to generate instance names
       - OS::TripleO::Services::Keystone
       - OS::TripleO::Services::GlanceApi
       - OS::TripleO::Services::GlanceRegistry
+      - OS::TripleO::Services::HeatApi
+      - OS::TripleO::Services::HeatApiCfn
+      - OS::TripleO::Services::HeatApiCloudwatch
+      - OS::TripleO::Services::HeatEngine
       - OS::TripleO::Services::NeutronDhcpAgent
     description: A list of service resources (configured in the Heat
                  resource_registry) which represent nested stacks
           GnocchiBackend: {get_param: GnocchiBackend}
           GnocchiIndexerBackend: {get_param: GnocchiIndexerBackend}
           HAProxySyslogAddress: {get_param: HAProxySyslogAddress}
-          HeatPassword: {get_param: HeatPassword}
-          HeatStackDomainAdminPassword: {get_param: HeatStackDomainAdminPassword}
           HeatAuthEncryptionKey: {get_resource: HeatAuthEncryptionKey}
           HorizonAllowedHosts: {get_param: HorizonAllowedHosts}
           HorizonSecret: {get_resource: HorizonSecret}
 
     default: /dev/log
     description: Syslog address where HAproxy will send its log
     type: string
-  HeatPassword:
-    description: The password for the Heat service and db account, used by the Heat services.
-    type: string
-    hidden: true
-  HeatStackDomainAdminPassword:
-    description: Password for heat_stack_domain_admin user.
-    type: string
-    hidden: true
   HeatAuthEncryptionKey:
     description: Auth encryption key for heat-engine
     type: string
     default: '*'
     description: A list of IP/Hostname allowed to connect to horizon
     type: comma_delimited_list
-  HeatWorkers:
-    default: 0
-    description: Number of workers for Heat service.
-    type: number
-  HeatEnableDBPurge:
-    type: boolean
-    default: true
-    description: |
-        Whether to create cron job for purging soft deleted rows in the Heat database.
   HorizonSecret:
     description: Secret key for Django
     type: string
         bootstack_nodeid: {get_attr: [Controller, name]}
         ceilometer_workers: {get_param: CeilometerWorkers}
         cinder_workers: {get_param: CinderWorkers}
-        heat_workers: {get_param: HeatWorkers}
         nova_workers: {get_param: NovaWorkers}
         neutron_workers: {get_param: NeutronWorkers}
         swift_workers: {get_param: SwiftWorkers}
         haproxy_log_address: {get_param: HAProxySyslogAddress}
         haproxy_stats_password: {get_param: HAProxyStatsPassword}
         haproxy_stats_user: {get_param: HAProxyStatsUser}
-        heat.watch_server_url:
-          list_join:
-            - ''
-            - - 'http://'
-              - {get_param: HeatApiVirtualIPUri}
-              - ':8003'
-        heat.metadata_server_url:
-          list_join:
-            - ''
-            - - 'http://'
-              - {get_param: HeatApiVirtualIPUri}
-              - ':8000'
-        heat.waitcondition_server_url:
-          list_join:
-            - ''
-            - - 'http://'
-              - {get_param: HeatApiVirtualIPUri}
-              - ':8000/v1/waitcondition'
-        heat_public_url: {get_param: [EndpointMap, HeatPublic, uri]}
-        heat_internal_url: {get_param: [EndpointMap, HeatInternal, uri]}
-        heat_admin_url: {get_param: [EndpointMap, HeatAdmin, uri]}
         heat_auth_encryption_key: {get_param: HeatAuthEncryptionKey}
-        heat_enable_db_purge: {get_param: HeatEnableDBPurge}
         horizon_allowed_hosts: {get_param: HorizonAllowedHosts}
         horizon_secret: {get_param: HorizonSecret}
         admin_password: {get_param: AdminPassword}
         cinder_public_url_v2: {get_param: [EndpointMap, CinderV2Public, uri]}
         cinder_internal_url_v2: {get_param: [EndpointMap, CinderV2Internal, uri]}
         cinder_admin_url_v2: {get_param: [EndpointMap, CinderV2Admin, uri]}
-        heat_password: {get_param: HeatPassword}
-        heat_stack_domain_admin_password: {get_param: HeatStackDomainAdminPassword}
-        heat_dsn:
-          list_join:
-            - ''
-            - - 'mysql+pymysql://heat:'
-              - {get_param: HeatPassword}
-              - '@'
-              - {get_param: MysqlVirtualIPUri}
-              - '/heat'
         keystone_identity_uri: { get_param: [EndpointMap, KeystoneAdmin, uri_no_suffix] }
         keystone_auth_uri: {get_param: [EndpointMap, KeystoneInternal, uri] }
         keystone_ec2_uri: { get_param: [EndpointMap, KeystoneEC2, uri] }
                 glance::keystone::auth::region: {get_input: keystone_region}
 
                 # Heat
-                heat_stack_domain_admin_password: {get_input: heat_stack_domain_admin_password}
-                heat::engine::heat_watch_server_url: {get_input: heat.watch_server_url}
-                heat::engine::heat_metadata_server_url: {get_input: heat.metadata_server_url}
-                heat::engine::heat_waitcondition_server_url: {get_input: heat.waitcondition_server_url}
-                heat::engine::auth_encryption_key: {get_input: heat_auth_encryption_key}
-                heat::rabbit_userid: {get_input: rabbit_username}
-                heat::rabbit_password: {get_input: rabbit_password}
-                heat::rabbit_use_ssl: {get_input: rabbit_client_use_ssl}
-                heat::rabbit_port: {get_input: rabbit_client_port}
-                heat::auth_uri: {get_input: keystone_auth_uri}
-                heat::keystone_ec2_uri: {get_input: keystone_ec2_uri}
-                heat::identity_uri: {get_input: keystone_identity_uri}
-                heat::keystone_password: {get_input: heat_password}
                 heat::api::bind_host: {get_input: heat_api_network}
-                heat::api::workers: {get_input: heat_workers}
                 heat::api_cloudwatch::bind_host: {get_input: heat_api_network}
-                heat::api_cloudwatch::workers: {get_input: heat_workers}
                 heat::api_cfn::bind_host: {get_input: heat_api_network}
-                heat::api_cfn::workers: {get_input: heat_workers}
-                heat::engine::num_engine_workers: {get_input: heat_workers}
-                heat::database_connection: {get_input: heat_dsn}
-                heat::debug: {get_input: debug}
-                heat::db::mysql::password: {get_input: heat_password}
-                heat_enable_db_purge: {get_input: heat_enable_db_purge}
-                heat::keystone::domain::domain_password: {get_input: heat_stack_domain_admin_password}
-                heat::keystone::auth::public_url: {get_input: heat_public_url }
-                heat::keystone::auth::internal_url: {get_input: heat_internal_url }
-                heat::keystone::auth::admin_url: {get_input: heat_admin_url }
-                heat::keystone::auth::password: {get_input: heat_password }
-                heat::keystone::auth::region: {get_input: keystone_region}
+                heat::engine::auth_encryption_key: {get_input: heat_auth_encryption_key}
 
                 # Keystone
                 keystone::admin_bind_host: {get_input: keystone_admin_api_network}
 
   include ::nova::db::mysql_api
   include ::neutron::db::mysql
   include ::cinder::db::mysql
-  include ::heat::db::mysql
   include ::sahara::db::mysql
   if downcase(hiera('gnocchi_indexer_backend')) == 'mysql' {
     include ::gnocchi::db::mysql
   include ::aodh::listener
   include ::aodh::client
 
-  # Heat
-  class { '::heat' :
-    notification_driver => 'messaging',
-  }
-  include ::heat::config
-  include ::heat::api
-  include ::heat::api_cfn
-  include ::heat::api_cloudwatch
-  include ::heat::engine
-
   # Sahara
   include ::sahara
   include ::sahara::service::api
 if hiera('step') >= 5 {
   $nova_enable_db_purge = hiera('nova_enable_db_purge', true)
   $cinder_enable_db_purge = hiera('cinder_enable_db_purge', true)
-  $heat_enable_db_purge = hiera('heat_enable_db_purge', true)
 
   if $nova_enable_db_purge {
     include ::nova::cron::archive_deleted_rows
   if $cinder_enable_db_purge {
     include ::cinder::cron::db_purge
   }
-  if $heat_enable_db_purge {
-    include ::heat::cron::purge_deleted
-  }
-
-  if downcase(hiera('bootstrap_nodeid')) == $::hostname {
-    # Class ::heat::keystone::domain has to run on bootstrap node
-    # because it creates DB entities via API calls.
-    include ::heat::keystone::domain
-
-    Class['::keystone::roles::admin'] -> Class['::heat::keystone::domain']
-  } else {
-    # On non-bootstrap node we don't need to create Keystone resources again
-    class { '::heat::keystone::domain':
-      manage_domain => false,
-      manage_user   => false,
-      manage_role   => false,
-    }
-  }
-
 } #END STEP 5
 
 $package_manifest_name = join(['/var/lib/tripleo/installed-packages/overcloud_controller', hiera('step')])
 
   tag == 'cinder-service' or
   tag == 'ceilometer-service' or
   tag == 'gnocchi-service' or
-  tag == 'heat-service' or
   tag == 'neutron-service' or
   tag == 'nova-service' or
   tag == 'sahara-service'
     class { '::cinder::db::mysql':
       require => Exec['galera-ready'],
     }
-    class { '::heat::db::mysql':
-      require => Exec['galera-ready'],
-    }
 
     if downcase(hiera('ceilometer_backend')) == 'mysql' {
       class { '::ceilometer::db::mysql':
 
   Cron <| title == 'ceilometer-expirer' |> { command => "sleep $((\$(od -A n -t d -N 3 /dev/urandom) % 86400)) && ${::ceilometer::params::expirer_command}" }
 
-  # Heat
-  include ::heat::config
-  class { '::heat' :
-    sync_db             => $sync_db,
-    notification_driver => 'messaging',
-  }
-  class { '::heat::api' :
-    manage_service => false,
-    enabled        => false,
-  }
-  class { '::heat::api_cfn' :
-    manage_service => false,
-    enabled        => false,
-  }
-  class { '::heat::api_cloudwatch' :
-    manage_service => false,
-    enabled        => false,
-  }
-  class { '::heat::engine' :
-    manage_service => false,
-    enabled        => false,
-  }
-
   # httpd/apache and horizon
   # NOTE(gfidente): server-status can be consumed by the pacemaker resource agent
   class { '::apache' :
 if hiera('step') >= 5 {
   $nova_enable_db_purge = hiera('nova_enable_db_purge', true)
   $cinder_enable_db_purge = hiera('cinder_enable_db_purge', true)
-  $heat_enable_db_purge = hiera('heat_enable_db_purge', true)
 
   if $nova_enable_db_purge {
     include ::nova::cron::archive_deleted_rows
   if $cinder_enable_db_purge {
     include ::cinder::cron::db_purge
   }
-  if $heat_enable_db_purge {
-    include ::heat::cron::purge_deleted
-  }
 
   if $pacemaker_master {
 
                   Pacemaker::Resource::Service[$::gnocchi::params::statsd_service_name]],
     }
 
-    # Heat
-    pacemaker::resource::service { $::heat::params::api_service_name :
-      clone_params => 'interleave=true',
-    }
-    pacemaker::resource::service { $::heat::params::api_cloudwatch_service_name :
-      clone_params => 'interleave=true',
-    }
-    pacemaker::resource::service { $::heat::params::api_cfn_service_name :
-      clone_params => 'interleave=true',
-    }
-    pacemaker::resource::service { $::heat::params::engine_service_name :
-      clone_params => 'interleave=true',
-    }
-    pacemaker::constraint::base { 'heat-api-then-heat-api-cfn-constraint':
-      constraint_type => 'order',
-      first_resource  => "${::heat::params::api_service_name}-clone",
-      second_resource => "${::heat::params::api_cfn_service_name}-clone",
-      first_action    => 'start',
-      second_action   => 'start',
-      require         => [Pacemaker::Resource::Service[$::heat::params::api_service_name],
-                          Pacemaker::Resource::Service[$::heat::params::api_cfn_service_name]],
-    }
-    pacemaker::constraint::colocation { 'heat-api-cfn-with-heat-api-colocation':
-      source  => "${::heat::params::api_cfn_service_name}-clone",
-      target  => "${::heat::params::api_service_name}-clone",
-      score   => 'INFINITY',
-      require => [Pacemaker::Resource::Service[$::heat::params::api_cfn_service_name],
-                  Pacemaker::Resource::Service[$::heat::params::api_service_name]],
-    }
-    pacemaker::constraint::base { 'heat-api-cfn-then-heat-api-cloudwatch-constraint':
-      constraint_type => 'order',
-      first_resource  => "${::heat::params::api_cfn_service_name}-clone",
-      second_resource => "${::heat::params::api_cloudwatch_service_name}-clone",
-      first_action    => 'start',
-      second_action   => 'start',
-      require         => [Pacemaker::Resource::Service[$::heat::params::api_cloudwatch_service_name],
-                          Pacemaker::Resource::Service[$::heat::params::api_cfn_service_name]],
-    }
-    pacemaker::constraint::colocation { 'heat-api-cloudwatch-with-heat-api-cfn-colocation':
-      source  => "${::heat::params::api_cloudwatch_service_name}-clone",
-      target  => "${::heat::params::api_cfn_service_name}-clone",
-      score   => 'INFINITY',
-      require => [Pacemaker::Resource::Service[$::heat::params::api_cfn_service_name],
-                  Pacemaker::Resource::Service[$::heat::params::api_cloudwatch_service_name]],
-    }
-    pacemaker::constraint::base { 'heat-api-cloudwatch-then-heat-engine-constraint':
-      constraint_type => 'order',
-      first_resource  => "${::heat::params::api_cloudwatch_service_name}-clone",
-      second_resource => "${::heat::params::engine_service_name}-clone",
-      first_action    => 'start',
-      second_action   => 'start',
-      require         => [Pacemaker::Resource::Service[$::heat::params::api_cloudwatch_service_name],
-                          Pacemaker::Resource::Service[$::heat::params::engine_service_name]],
-    }
-    pacemaker::constraint::colocation { 'heat-engine-with-heat-api-cloudwatch-colocation':
-      source  => "${::heat::params::engine_service_name}-clone",
-      target  => "${::heat::params::api_cloudwatch_service_name}-clone",
-      score   => 'INFINITY',
-      require => [Pacemaker::Resource::Service[$::heat::params::api_cloudwatch_service_name],
-                  Pacemaker::Resource::Service[$::heat::params::engine_service_name]],
-    }
-    pacemaker::constraint::base { 'ceilometer-notification-then-heat-api-constraint':
-      constraint_type => 'order',
-      first_resource  => "${::ceilometer::params::agent_notification_service_name}-clone",
-      second_resource => "${::heat::params::api_service_name}-clone",
-      first_action    => 'start',
-      second_action   => 'start',
-      require         => [Pacemaker::Resource::Service[$::heat::params::api_service_name],
-                          Pacemaker::Resource::Service[$::ceilometer::params::agent_notification_service_name]],
-    }
-
     # Horizon and Keystone
     pacemaker::resource::service { $::apache::params::service_name:
       clone_params     => 'interleave=true',
 
--- /dev/null
+heat_template_version: 2016-04-08
+
+description: >
+  Openstack Heat CloudFormation API service configured with Puppet
+
+parameters:
+  EndpointMap:
+    default: {}
+    description: Mapping of service endpoint -> protocol. Typically set
+                 via parameter_defaults in the resource registry.
+    type: json
+  MysqlVirtualIPUri:
+    type: string
+    default: ''
+  HeatWorkers:
+    default: 0
+    description: Number of workers for Heat service.
+    type: number
+  HeatPassword:
+    description: The password for the Heat service and db account, used by the Heat services.
+    type: string
+    hidden: true
+  KeystoneRegion:
+    type: string
+    default: 'regionOne'
+    description: Keystone region for endpoint
+
+resources:
+  HeatBase:
+    type: ./heat-base.yaml
+
+outputs:
+  role_data:
+    description: Role data for the Heat CloudFormation API role.
+    value:
+      config_settings:
+        map_merge:
+          - get_attr: [HeatBase, role_data, config_settings]
+          - heat::api_cfn::workers: {get_param: HeatWorkers}
+            heat::keystone::auth_cfn::public_url: {get_param: [EndpointMap, HeatCfnPublic, uri]}
+            heat::keystone::auth_cfn::internal_url: {get_param: [EndpointMap, HeatCfnInternal, uri]}
+            heat::keystone::auth_cfn::admin_url: {get_param: [EndpointMap, HeatCfnAdmin, uri]}
+            heat::keystone::auth_cfn::password: {get_param: HeatPassword}
+            heat::keystone::auth::region: {get_param: KeystoneRegion}
+      step_config: |
+        include ::tripleo::profile::base::heat::api_cfn
 
--- /dev/null
+heat_template_version: 2016-04-08
+
+description: >
+  Openstack Heat CloudWatch API service configured with Puppet
+
+parameters:
+  EndpointMap:
+    default: {}
+    description: Mapping of service endpoint -> protocol. Typically set
+                 via parameter_defaults in the resource registry.
+    type: json
+  MysqlVirtualIPUri:
+    type: string
+    default: ''
+  HeatWorkers:
+    default: 0
+    description: Number of workers for Heat service.
+    type: number
+
+resources:
+  HeatBase:
+    type: ./heat-base.yaml
+
+outputs:
+  role_data:
+    description: Role data for the Heat Cloudwatch API role.
+    value:
+      config_settings:
+        map_merge:
+          - get_attr: [HeatBase, role_data, config_settings]
+          - heat::api_cloudwatch::workers: {get_param: HeatWorkers}
+      step_config: |
+        include ::tripleo::profile::base::heat::api_cloudwatch
 
--- /dev/null
+heat_template_version: 2016-04-08
+
+description: >
+  Openstack Heat API service configured with Puppet
+
+parameters:
+  EndpointMap:
+    default: {}
+    description: Mapping of service endpoint -> protocol. Typically set
+                 via parameter_defaults in the resource registry.
+    type: json
+  MysqlVirtualIPUri:
+    type: string
+    default: ''
+  HeatWorkers:
+    default: 0
+    description: Number of workers for Heat service.
+    type: number
+  HeatPassword:
+    description: The password for the Heat service and db account, used by the Heat services.
+    type: string
+    hidden: true
+  KeystoneRegion:
+    type: string
+    default: 'regionOne'
+    description: Keystone region for endpoint
+
+resources:
+  HeatBase:
+    type: ./heat-base.yaml
+
+outputs:
+  role_data:
+    description: Role data for the Heat API role.
+    value:
+      config_settings:
+        map_merge:
+          - get_attr: [HeatBase, role_data, config_settings]
+          - heat::api::workers: {get_param: HeatWorkers}
+            heat::keystone::auth::public_url: {get_param: [EndpointMap, HeatPublic, uri]}
+            heat::keystone::auth::internal_url: {get_param: [EndpointMap, HeatInternal, uri]}
+            heat::keystone::auth::admin_url: {get_param: [EndpointMap, HeatAdmin, uri]}
+            heat::keystone::auth::password: {get_param: HeatPassword}
+            heat::keystone::auth::region: {get_param: KeystoneRegion}
+      step_config: |
+        include ::tripleo::profile::base::heat::api
 
--- /dev/null
+heat_template_version: 2016-04-08
+
+description: >
+  Openstack Heat base service. Shared for all Heat services.
+
+parameters:
+  Debug:
+    default: ''
+    description: Set to True to enable debugging on all services.
+    type: string
+  RabbitPassword:
+    description: The password for RabbitMQ
+    type: string
+    hidden: true
+  RabbitUserName:
+    default: guest
+    description: The username for RabbitMQ
+    type: string
+  RabbitClientUseSSL:
+    default: false
+    description: >
+        Rabbit client subscriber parameter to specify
+        an SSL connection to the RabbitMQ host.
+    type: string
+  RabbitClientPort:
+    default: 5672
+    description: Set rabbit subscriber port, change this if using SSL
+    type: number
+
+outputs:
+  role_data:
+    description: Shared role data for the Heat services.
+    value:
+      config_settings:
+        heat::rabbit_userid: {get_param: RabbitUserName}
+        heat::rabbit_password: {get_param: RabbitPassword}
+        heat::rabbit_use_ssl: {get_param: RabbitClientUseSSL}
+        heat::rabbit_port: {get_param: RabbitClientPort}
+        heat::debug: {get_param: Debug}
 
--- /dev/null
+heat_template_version: 2016-04-08
+
+description: >
+  Openstack Heat Engine service configured with Puppet
+
+parameters:
+  EndpointMap:
+    default: {}
+    description: Mapping of service endpoint -> protocol. Typically set
+                 via parameter_defaults in the resource registry.
+    type: json
+  MysqlVirtualIPUri:
+    type: string
+    default: ''
+  HeatEnableDBPurge:
+    type: boolean
+    default: true
+    description: |
+        Whether to create cron job for purging soft deleted rows in the Heat database.
+  HeatWorkers:
+    default: 0
+    description: Number of workers for Heat service.
+    type: number
+  HeatPassword:
+    description: The password for the Heat service and db account, used by the Heat services.
+    type: string
+    hidden: true
+  HeatStackDomainAdminPassword:
+    description: Password for heat_stack_domain_admin user.
+    type: string
+    hidden: true
+
+resources:
+  HeatBase:
+    type: ./heat-base.yaml
+
+outputs:
+  role_data:
+    description: Role data for the Heat Engine role.
+    value:
+      config_settings:
+        map_merge:
+          - get_attr: [HeatBase, role_data, config_settings]
+          - heat::engine::num_engine_workers: {get_param: HeatWorkers}
+            tripleo::profile::base::heat::manage_db_purge: {get_param: HeatEnableDBPurge}
+            heat_dsn: &heat_dsn
+              list_join:
+                - ''
+                - - 'mysql+pymysql://heat:'
+                  - {get_param: HeatPassword}
+                  - '@'
+                  - {get_param: MysqlVirtualIPUri}
+                  - '/heat'
+            heat::auth_uri: {get_param: [EndpointMap, KeystoneInternal, uri]}
+            heat::keystone_ec2_uri: {get_param: [EndpointMap, KeystoneEC2, uri]}
+            heat::identity_uri: {get_param: [EndpointMap, KeystoneAdmin, uri_no_suffix]}
+            heat::keystone_password: {get_param: HeatPassword}
+            heat::database_connection: *heat_dsn
+            heat::db::mysql::password: {get_param: HeatPassword}
+            heat::keystone::domain::domain_password: {get_param: HeatStackDomainAdminPassword}
+      step_config: |
+        include ::tripleo::profile::base::heat::engine
 
--- /dev/null
+heat_template_version: 2016-04-08
+
+description: >
+  Openstack Heat CloudFormation API service configured with Puppet
+
+parameters:
+  EndpointMap:
+    default: {}
+    description: Mapping of service endpoint -> protocol. Typically set
+                 via parameter_defaults in the resource registry.
+    type: json
+  MysqlVirtualIPUri:
+    type: string
+    default: ''
+
+resources:
+  HeatApiCfnBase:
+    type: ../heat-api-cfn.yaml
+    properties:
+      EndpointMap: {get_param: EndpointMap}
+      MysqlVirtualIPUri: {get_param: MysqlVirtualIPUri}
+
+outputs:
+  role_data:
+    description: Role data for the Heat CloudFormation API role.
+    value:
+      config_settings:
+        map_merge:
+          - get_attr: [HeatApiCfnBase, role_data, config_settings]
+          - heat::api_cfn::manage_service: false
+            heat::api_cfn::enabled: false
+      step_config:
+        # No puppet manifests since heat-api-cfn is included in
+        # ::tripleo::profile::pacemaker::heat which is maintained alongside of
+        # pacemaker/heat-api.yaml.
 
--- /dev/null
+heat_template_version: 2016-04-08
+
+description: >
+  Openstack Heat CloudWatch API service configured with Puppet
+
+parameters:
+  EndpointMap:
+    default: {}
+    description: Mapping of service endpoint -> protocol. Typically set
+                 via parameter_defaults in the resource registry.
+    type: json
+  MysqlVirtualIPUri:
+    type: string
+    default: ''
+
+resources:
+  HeatApiCloudwatchBase:
+    type: ../heat-api-cloudwatch.yaml
+    properties:
+      EndpointMap: {get_param: EndpointMap}
+      MysqlVirtualIPUri: {get_param: MysqlVirtualIPUri}
+
+outputs:
+  role_data:
+    description: Role data for the Heat Cloudwatch API role.
+    value:
+      config_settings:
+        map_merge:
+           - get_attr: [HeatApiCloudwatchBase, role_data, config_settings]
+           - heat::api_cloudwatch::manage_service: false
+             heat::api_cloudwatch::enabled: false
+      step_config:
+        # No puppet manifests since heat-api-cloudwatch is included in
+        # ::tripleo::profile::pacemaker::heat which is maintained alongside of
+        # pacemaker/heat-api.yaml.
 
--- /dev/null
+heat_template_version: 2016-04-08
+
+description: >
+  Openstack Heat API service configured with Puppet
+
+parameters:
+  EndpointMap:
+    default: {}
+    description: Mapping of service endpoint -> protocol. Typically set
+                 via parameter_defaults in the resource registry.
+    type: json
+  MysqlVirtualIPUri:
+    type: string
+    default: ''
+
+resources:
+  HeatApiBase:
+    type: ../heat-api.yaml
+    properties:
+      EndpointMap: {get_param: EndpointMap}
+      MysqlVirtualIPUri: {get_param: MysqlVirtualIPUri}
+
+outputs:
+  role_data:
+    description: Role data for the Heat API role.
+    value:
+      config_settings:
+        map_merge:
+          - get_attr: [HeatApiBase, role_data, config_settings]
+          - heat::api::manage_service: false
+            heat::api::enabled: false
+      step_config: |
+        include ::tripleo::profile::pacemaker::heat
 
--- /dev/null
+heat_template_version: 2016-04-08
+
+description: >
+  Openstack Heat Engine service configured with Puppet
+
+parameters:
+  EndpointMap:
+    default: {}
+    description: Mapping of service endpoint -> protocol. Typically set
+                 via parameter_defaults in the resource registry.
+    type: json
+  MysqlVirtualIPUri:
+    type: string
+    default: ''
+
+resources:
+  HeatEngineBase:
+    type: ../heat-engine.yaml
+    properties:
+      EndpointMap: {get_param: EndpointMap}
+      MysqlVirtualIPUri: {get_param: MysqlVirtualIPUri}
+
+
+outputs:
+  role_data:
+    description: Role data for the Heat engine role.
+    value:
+      config_settings:
+        map_merge:
+          - get_attr: [HeatEngineBase, role_data, config_settings]
+          - heat::engine::manage_service: false
+            heat::engine::enabled: false
+      step_config:
+        # No puppet manifests since heat-engine is included in
+        # ::tripleo::profile::pacemaker::heat which is maintained alongside of
+        # pacemaker/heat-api.yaml.