Merge "Allow to enable fencing, pass through fencing config"
[apex-tripleo-heat-templates.git] / puppet / manifests / overcloud_controller_pacemaker.pp
1 # Copyright 2015 Red Hat, Inc.
2 # All Rights Reserved.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 # not use this file except in compliance with the License. You may obtain
6 # a copy of the License at
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 # License for the specific language governing permissions and limitations
14 # under the License.
15
16 Pcmk_resource <| |> {
17   tries     => 10,
18   try_sleep => 3,
19 }
20
21 if !str2bool(hiera('enable_package_install', 'false')) {
22   case $::osfamily {
23     'RedHat': {
24       Package { provider => 'norpm' } # provided by tripleo-puppet
25     }
26     default: {
27       warning('enable_package_install option not supported.')
28     }
29   }
30 }
31
32 if $::hostname == downcase(hiera('bootstrap_nodeid')) {
33   $pacemaker_master = true
34   $sync_db = true
35 } else {
36   $pacemaker_master = false
37   $sync_db = false
38 }
39
40 $enable_fencing = str2bool(hiera('enable_fencing', 'false')) and hiera('step') >= 5
41
42 # When to start and enable services which haven't been Pacemakerized
43 # FIXME: remove when we start all OpenStack services using Pacemaker
44 # (occurences of this variable will be gradually replaced with false)
45 $non_pcmk_start = hiera('step') >= 4
46
47 if hiera('step') >= 1 {
48
49   create_resources(sysctl::value, hiera('sysctl_settings'), {})
50
51   if count(hiera('ntp::servers')) > 0 {
52     include ::ntp
53   }
54
55   $controller_node_ips = split(hiera('controller_node_ips'), ',')
56   $controller_node_names = split(downcase(hiera('controller_node_names')), ',')
57   class { '::tripleo::loadbalancer' :
58     controller_hosts       => $controller_node_ips,
59     controller_hosts_names => $controller_node_names,
60     manage_vip             => false,
61     mysql_clustercheck     => true,
62     haproxy_service_manage => false,
63   }
64
65   $pacemaker_cluster_members = downcase(regsubst(hiera('controller_node_names'), ',', ' ', 'G'))
66   user { 'hacluster':
67    ensure => present,
68   } ->
69   class { '::pacemaker':
70     hacluster_pwd => hiera('hacluster_pwd'),
71   } ->
72   class { '::pacemaker::corosync':
73     cluster_members => $pacemaker_cluster_members,
74     setup_cluster   => $pacemaker_master,
75   }
76   class { '::pacemaker::stonith':
77     disable => !$enable_fencing,
78   }
79   if $enable_fencing {
80     include tripleo::fencing
81
82     # enable stonith after all fencing devices have been created
83     Class['tripleo::fencing'] -> Class['pacemaker::stonith']
84   }
85
86   # Only configure RabbitMQ in this step, don't start it yet to
87   # avoid races where non-master nodes attempt to start without
88   # config (eg. binding on 0.0.0.0)
89   # The module ignores erlang_cookie if cluster_config is false
90   class { '::rabbitmq':
91     service_manage          => false,
92     tcp_keepalive           => false,
93     config_kernel_variables => hiera('rabbitmq_kernel_variables'),
94     config_variables        => hiera('rabbitmq_config_variables'),
95     environment_variables   => hiera('rabbitmq_environment'),
96   } ->
97   file { '/var/lib/rabbitmq/.erlang.cookie':
98     ensure  => 'present',
99     owner   => 'rabbitmq',
100     group   => 'rabbitmq',
101     mode    => '0400',
102     content => hiera('rabbitmq::erlang_cookie'),
103     replace => true,
104   }
105
106   if downcase(hiera('ceilometer_backend')) == 'mongodb' {
107     include ::mongodb::globals
108     class { '::mongodb::server' :
109       service_manage => false,
110     }
111   }
112
113   # Memcached
114   class {'::memcached' :
115     service_manage => false,
116   }
117
118   # Redis
119   class { '::redis' :
120     service_manage => false,
121     notify_service => false,
122   }
123
124   # Galera
125   if str2bool(hiera('enable_galera', 'true')) {
126     $mysql_config_file = '/etc/my.cnf.d/galera.cnf'
127   } else {
128     $mysql_config_file = '/etc/my.cnf.d/server.cnf'
129   }
130   $galera_nodes = downcase(hiera('galera_node_names', $::hostname))
131   $galera_nodes_count = count(split($galera_nodes, ','))
132
133   $mysqld_options = {
134     'mysqld' => {
135       'skip-name-resolve'             => '1',
136       'binlog_format'                 => 'ROW',
137       'default-storage-engine'        => 'innodb',
138       'innodb_autoinc_lock_mode'      => '2',
139       'innodb_locks_unsafe_for_binlog'=> '1',
140       'query_cache_size'              => '0',
141       'query_cache_type'              => '0',
142       'bind-address'                  => hiera('mysql_bind_host'),
143       'max_connections'               => '1024',
144       'open_files_limit'              => '-1',
145       'wsrep_provider'                => '/usr/lib64/galera/libgalera_smm.so',
146       'wsrep_cluster_name'            => 'galera_cluster',
147       'wsrep_slave_threads'           => '1',
148       'wsrep_certify_nonPK'           => '1',
149       'wsrep_max_ws_rows'             => '131072',
150       'wsrep_max_ws_size'             => '1073741824',
151       'wsrep_debug'                   => '0',
152       'wsrep_convert_LOCK_to_trx'     => '0',
153       'wsrep_retry_autocommit'        => '1',
154       'wsrep_auto_increment_control'  => '1',
155       'wsrep_drupal_282555_workaround'=> '0',
156       'wsrep_causal_reads'            => '0',
157       'wsrep_notify_cmd'              => '',
158       'wsrep_sst_method'              => 'rsync',
159     }
160   }
161
162   class { '::mysql::server':
163     create_root_user   => false,
164     create_root_my_cnf => false,
165     config_file        => $mysql_config_file,
166     override_options   => $mysqld_options,
167     service_manage     => false,
168     service_enabled    => false,
169   }
170
171 }
172
173 if hiera('step') >= 2 {
174
175   # NOTE(gfidente): the following vars are needed on all nodes so they
176   # need to stay out of pacemaker_master conditional
177   $mongo_node_ips_with_port = suffix(hiera('mongo_node_ips'), ':27017')
178   $mongodb_replset = hiera('mongodb::server::replset')
179
180   if $pacemaker_master {
181
182     # FIXME: we should not have to access tripleo::loadbalancer class
183     # parameters here to configure pacemaker VIPs. The configuration
184     # of pacemaker VIPs could move into puppet-tripleo or we should
185     # make use of less specific hiera parameters here for the settings.
186     $control_vip = hiera('tripleo::loadbalancer::controller_virtual_ip')
187     pacemaker::resource::ip { 'control_vip':
188       ip_address => $control_vip,
189     }
190     $public_vip = hiera('tripleo::loadbalancer::public_virtual_ip')
191     pacemaker::resource::ip { 'public_vip':
192       ip_address => $public_vip,
193     }
194
195     $internal_api_vip = hiera('tripleo::loadbalancer::internal_api_virtual_ip')
196     if $internal_api_vip and $internal_api_vip != $control_vip {
197       pacemaker::resource::ip { 'internal_api_vip':
198         ip_address => $internal_api_vip,
199       }
200     }
201
202     $storage_vip = hiera('tripleo::loadbalancer::storage_virtual_ip')
203     if $storage_vip and $storage_vip != $control_vip {
204       pacemaker::resource::ip { 'storage_vip':
205         ip_address => $storage_vip,
206       }
207     }
208
209     $storage_mgmt_vip = hiera('tripleo::loadbalancer::storage_mgmt_virtual_ip')
210     if $storage_mgmt_vip and $storage_mgmt_vip != $control_vip {
211       pacemaker::resource::ip { 'storage_mgmt_vip':
212         ip_address => $storage_mgmt_vip,
213       }
214     }
215
216     pacemaker::resource::service { 'haproxy':
217       clone_params => true,
218     }
219     pacemaker::resource::service { $::memcached::params::service_name :
220       clone_params => true,
221       require      => Class['::memcached'],
222     }
223
224     pacemaker::resource::ocf { 'rabbitmq':
225       ocf_agent_name  => 'heartbeat:rabbitmq-cluster',
226       resource_params => 'set_policy=\'ha-all ^(?!amq\.).* {"ha-mode":"all"}\'',
227       clone_params    => 'ordered=true interleave=true',
228       require         => Class['::rabbitmq'],
229     }
230
231     if downcase(hiera('ceilometer_backend')) == 'mongodb' {
232       pacemaker::resource::service { $::mongodb::params::service_name :
233         op_params    => 'start timeout=120s',
234         clone_params => true,
235         require      => Class['::mongodb::server'],
236       }
237       # NOTE (spredzy) : The replset can only be run
238       # once all the nodes have joined the cluster.
239       mongodb_conn_validator { $mongo_node_ips_with_port :
240         timeout => '600',
241         require => Pacemaker::Resource::Service[$::mongodb::params::service_name],
242         before  => Mongodb_replset[$mongodb_replset],
243       }
244       mongodb_replset { $mongodb_replset :
245         members => $mongo_node_ips_with_port,
246       }
247     }
248
249     pacemaker::resource::ocf { 'galera' :
250       ocf_agent_name  => 'heartbeat:galera',
251       op_params       => 'promote timeout=300s on-fail=block',
252       master_params   => '',
253       meta_params     => "master-max=${galera_nodes_count} ordered=true",
254       resource_params => "additional_parameters='--open-files-limit=16384' enable_creation=true wsrep_cluster_address='gcomm://${galera_nodes}'",
255       require         => Class['::mysql::server'],
256       before          => Exec['galera-ready'],
257     }
258
259     pacemaker::resource::ocf { 'redis':
260       ocf_agent_name  => 'heartbeat:redis',
261       master_params   => '',
262       meta_params     => 'notify=true ordered=true interleave=true',
263       resource_params => 'wait_last_known_master=true',
264       require         => Class['::redis'],
265     }
266     $redis_vip = hiera('redis_vip')
267     if $redis_vip and $redis_vip != $control_vip {
268         pacemaker::resource::ip { 'vip-redis':
269           ip_address => $redis_vip,
270         }
271     }
272     pacemaker::constraint::base { 'redis-master-then-vip-redis':
273       constraint_type => 'order',
274       first_resource  => 'redis-master',
275       second_resource => "ip-${redis_vip}",
276       first_action    => 'promote',
277       second_action   => 'start',
278       require => [Pacemaker::Resource::Ocf['redis'],
279                   Pacemaker::Resource::Ip['vip-redis']],
280     }
281     pacemaker::constraint::colocation { 'vip-redis-with-redis-master':
282       source  => "ip-${redis_vip}",
283       target  => 'redis-master',
284       score   => 'INFINITY',
285       require => [Pacemaker::Resource::Ocf['redis'],
286                   Pacemaker::Resource::Ip['vip-redis']],
287     }
288
289   }
290
291   exec { 'galera-ready' :
292     command     => '/usr/bin/clustercheck >/dev/null',
293     timeout     => 30,
294     tries       => 180,
295     try_sleep   => 10,
296     environment => ["AVAILABLE_WHEN_READONLY=0"],
297     require     => File['/etc/sysconfig/clustercheck'],
298   }
299
300   file { '/etc/sysconfig/clustercheck' :
301     ensure  => file,
302     content => "MYSQL_USERNAME=root\n
303 MYSQL_PASSWORD=''\n
304 MYSQL_HOST=localhost\n",
305   }
306
307   xinetd::service { 'galera-monitor' :
308     port           => '9200',
309     server         => '/usr/bin/clustercheck',
310     per_source     => 'UNLIMITED',
311     log_on_success => '',
312     log_on_failure => 'HOST',
313     flags          => 'REUSE',
314     service_type   => 'UNLISTED',
315     user           => 'root',
316     group          => 'root',
317     require        => File['/etc/sysconfig/clustercheck'],
318   }
319
320   # Create all the database schemas
321   # Example DSN format: mysql://user:password@host/dbname
322   if $sync_db {
323     $allowed_hosts = ['%',hiera('mysql_bind_host')]
324     $keystone_dsn = split(hiera('keystone::database_connection'), '[@:/?]')
325     class { 'keystone::db::mysql':
326       user          => $keystone_dsn[3],
327       password      => $keystone_dsn[4],
328       host          => $keystone_dsn[5],
329       dbname        => $keystone_dsn[6],
330       allowed_hosts => $allowed_hosts,
331       require       => Exec['galera-ready'],
332     }
333     $glance_dsn = split(hiera('glance::api::database_connection'), '[@:/?]')
334     class { 'glance::db::mysql':
335       user          => $glance_dsn[3],
336       password      => $glance_dsn[4],
337       host          => $glance_dsn[5],
338       dbname        => $glance_dsn[6],
339       allowed_hosts => $allowed_hosts,
340       require       => Exec['galera-ready'],
341     }
342     $nova_dsn = split(hiera('nova::database_connection'), '[@:/?]')
343     class { 'nova::db::mysql':
344       user          => $nova_dsn[3],
345       password      => $nova_dsn[4],
346       host          => $nova_dsn[5],
347       dbname        => $nova_dsn[6],
348       allowed_hosts => $allowed_hosts,
349       require       => Exec['galera-ready'],
350     }
351     $neutron_dsn = split(hiera('neutron::server::database_connection'), '[@:/?]')
352     class { 'neutron::db::mysql':
353       user          => $neutron_dsn[3],
354       password      => $neutron_dsn[4],
355       host          => $neutron_dsn[5],
356       dbname        => $neutron_dsn[6],
357       allowed_hosts => $allowed_hosts,
358       require       => Exec['galera-ready'],
359     }
360     $cinder_dsn = split(hiera('cinder::database_connection'), '[@:/?]')
361     class { 'cinder::db::mysql':
362       user          => $cinder_dsn[3],
363       password      => $cinder_dsn[4],
364       host          => $cinder_dsn[5],
365       dbname        => $cinder_dsn[6],
366       allowed_hosts => $allowed_hosts,
367       require       => Exec['galera-ready'],
368     }
369     $heat_dsn = split(hiera('heat::database_connection'), '[@:/?]')
370     class { 'heat::db::mysql':
371       user          => $heat_dsn[3],
372       password      => $heat_dsn[4],
373       host          => $heat_dsn[5],
374       dbname        => $heat_dsn[6],
375       allowed_hosts => $allowed_hosts,
376       require       => Exec['galera-ready'],
377     }
378     if downcase(hiera('ceilometer_backend')) == 'mysql' {
379       $ceilometer_dsn = split(hiera('ceilometer_mysql_conn_string'), '[@:/?]')
380       class { 'ceilometer::db::mysql':
381         user          => $ceilometer_dsn[3],
382         password      => $ceilometer_dsn[4],
383         host          => $ceilometer_dsn[5],
384         dbname        => $ceilometer_dsn[6],
385         allowed_hosts => $allowed_hosts,
386         require       => Exec['galera-ready'],
387       }
388     }
389   }
390
391   # pre-install swift here so we can build rings
392   include ::swift
393
394   # Ceph
395   $cinder_enable_rbd_backend = hiera('cinder_enable_rbd_backend', false)
396   $enable_ceph = $cinder_enable_rbd_backend
397
398   if $enable_ceph {
399     class { 'ceph::profile::params':
400       mon_initial_members => downcase(hiera('ceph_mon_initial_members'))
401     }
402     include ::ceph::profile::mon
403   }
404
405   if str2bool(hiera('enable_ceph_storage', 'false')) {
406     include ::ceph::profile::client
407     include ::ceph::profile::osd
408   }
409
410
411 } #END STEP 2
412
413 if hiera('step') >= 3 {
414
415   class { '::keystone':
416     sync_db => $sync_db,
417     manage_service => false,
418     enabled => false,
419   }
420
421   #TODO: need a cleanup-keystone-tokens.sh solution here
422   keystone_config {
423     'ec2/driver': value => 'keystone.contrib.ec2.backends.sql.Ec2';
424   }
425   file { [ '/etc/keystone/ssl', '/etc/keystone/ssl/certs', '/etc/keystone/ssl/private' ]:
426     ensure  => 'directory',
427     owner   => 'keystone',
428     group   => 'keystone',
429     require => Package['keystone'],
430   }
431   file { '/etc/keystone/ssl/certs/signing_cert.pem':
432     content => hiera('keystone_signing_certificate'),
433     owner   => 'keystone',
434     group   => 'keystone',
435     notify  => Service['keystone'],
436     require => File['/etc/keystone/ssl/certs'],
437   }
438   file { '/etc/keystone/ssl/private/signing_key.pem':
439     content => hiera('keystone_signing_key'),
440     owner   => 'keystone',
441     group   => 'keystone',
442     notify  => Service['keystone'],
443     require => File['/etc/keystone/ssl/private'],
444   }
445   file { '/etc/keystone/ssl/certs/ca.pem':
446     content => hiera('keystone_ca_certificate'),
447     owner   => 'keystone',
448     group   => 'keystone',
449     notify  => Service['keystone'],
450     require => File['/etc/keystone/ssl/certs'],
451   }
452
453   $glance_backend = downcase(hiera('glance_backend', 'swift'))
454   case $glance_backend {
455       swift: { $glance_store = 'glance.store.swift.Store' }
456       file: { $glance_store = 'glance.store.filesystem.Store' }
457       rbd: { $glance_store = 'glance.store.rbd.Store' }
458       default: { fail('Unrecognized glance_backend parameter.') }
459   }
460
461   # TODO: notifications, scrubber, etc.
462   include ::glance
463   class { 'glance::api':
464     known_stores => [$glance_store],
465     manage_service => false,
466     enabled => false,
467   }
468   class { '::glance::registry' :
469     sync_db => $sync_db,
470     manage_service => false,
471     enabled => false,
472   }
473   include join(['::glance::backend::', $glance_backend])
474
475   include ::nova
476
477   class { '::nova::api' :
478     sync_db => $sync_db,
479     manage_service => false,
480     enabled => false,
481   }
482   class { '::nova::cert' :
483     manage_service => false,
484     enabled => false,
485   }
486   class { '::nova::conductor' :
487     manage_service => false,
488     enabled => false,
489   }
490   class { '::nova::consoleauth' :
491     manage_service => false,
492     enabled => false,
493   }
494   class { '::nova::vncproxy' :
495     manage_service => false,
496     enabled => false,
497   }
498   class { '::nova::scheduler' :
499     manage_service => false,
500     enabled => false,
501   }
502   include ::nova::network::neutron
503
504   # Neutron class definitions
505   include ::neutron
506   class { '::neutron::server' :
507     sync_db => $sync_db,
508     manage_service => false,
509     enabled => false,
510   }
511   class { '::neutron::agents::dhcp' :
512     manage_service => false,
513     enabled => false,
514   }
515   class { '::neutron::agents::l3' :
516     manage_service => false,
517     enabled => false,
518   }
519   class { 'neutron::agents::metadata':
520     manage_service => false,
521     enabled => false,
522   }
523   file { '/etc/neutron/dnsmasq-neutron.conf':
524     content => hiera('neutron_dnsmasq_options'),
525     owner   => 'neutron',
526     group   => 'neutron',
527     notify  => Service['neutron-dhcp-service'],
528     require => Package['neutron'],
529   }
530   class { 'neutron::plugins::ml2':
531     flat_networks   => split(hiera('neutron_flat_networks'), ','),
532     tenant_network_types => [hiera('neutron_tenant_network_type')],
533   }
534   class { 'neutron::agents::ml2::ovs':
535     # manage_service   => false # not implemented
536     enabled          => false,
537     bridge_mappings  => split(hiera('neutron_bridge_mappings'), ','),
538     tunnel_types     => split(hiera('neutron_tunnel_types'), ','),
539   }
540
541   include ::cinder
542   class { '::cinder::api':
543     sync_db => $sync_db,
544     manage_service => false,
545     enabled => false,
546   }
547   class { '::cinder::scheduler' :
548     manage_service => false,
549     enabled => false,
550   }
551   class { '::cinder::volume' :
552     manage_service => false,
553     enabled => false,
554   }
555   include ::cinder::glance
556   class {'cinder::setup_test_volume':
557     size => join([hiera('cinder_lvm_loop_device_size'), 'M']),
558   }
559
560   $cinder_enable_iscsi = hiera('cinder_enable_iscsi_backend', true)
561   if $cinder_enable_iscsi {
562     $cinder_iscsi_backend = 'tripleo_iscsi'
563
564     cinder::backend::iscsi { $cinder_iscsi_backend :
565       iscsi_ip_address => hiera('cinder_iscsi_ip_address'),
566       iscsi_helper     => hiera('cinder_iscsi_helper'),
567     }
568   }
569
570   if $enable_ceph {
571
572     Ceph_pool {
573       pg_num  => hiera('ceph::profile::params::osd_pool_default_pg_num'),
574       pgp_num => hiera('ceph::profile::params::osd_pool_default_pgp_num'),
575       size    => hiera('ceph::profile::params::osd_pool_default_size'),
576     }
577
578     $ceph_pools = hiera('ceph_pools')
579     ceph::pool { $ceph_pools : }
580   }
581
582   if $cinder_enable_rbd_backend {
583     $cinder_rbd_backend = 'tripleo_ceph'
584
585     cinder_config {
586       "${cinder_rbd_backend}/host": value => 'hostgroup';
587     }
588
589     cinder::backend::rbd { $cinder_rbd_backend :
590       rbd_pool        => 'volumes',
591       rbd_user        => 'openstack',
592       rbd_secret_uuid => hiera('ceph::profile::params::fsid'),
593       require         => Ceph::Pool['volumes'],
594     }
595   }
596
597   if hiera('cinder_enable_netapp_backend', false) {
598     $cinder_netapp_backend = hiera('cinder::backend::netapp::title')
599
600     cinder_config {
601       "${cinder_netapp_backend}/host": value => 'hostgroup';
602     }
603
604     if hiera('cinder_netapp_nfs_shares', undef) {
605       $cinder_netapp_nfs_shares = split(hiera('cinder_netapp_nfs_shares', undef), ',')
606     }
607
608     cinder::backend::netapp { $cinder_netapp_backend :
609       nfs_shares => $cinder_netapp_nfs_shares,
610     }
611   }
612
613   $cinder_enabled_backends = delete_undef_values([$cinder_iscsi_backend, $cinder_rbd_backend, $cinder_netapp_backend])
614   class { '::cinder::backends' :
615     enabled_backends => $cinder_enabled_backends,
616   }
617
618   # swift proxy
619   class { '::swift::proxy' :
620     manage_service => $non_pcmk_start,
621     enabled => $non_pcmk_start,
622   }
623   include ::swift::proxy::proxy_logging
624   include ::swift::proxy::healthcheck
625   include ::swift::proxy::cache
626   include ::swift::proxy::keystone
627   include ::swift::proxy::authtoken
628   include ::swift::proxy::staticweb
629   include ::swift::proxy::ceilometer
630   include ::swift::proxy::ratelimit
631   include ::swift::proxy::catch_errors
632   include ::swift::proxy::tempurl
633   include ::swift::proxy::formpost
634
635   # swift storage
636   if str2bool(hiera('enable_swift_storage', 'true')) {
637     class {'::swift::storage::all':
638       mount_check => str2bool(hiera('swift_mount_check'))
639     }
640     class {'::swift::storage::account':
641       manage_service => $non_pcmk_start,
642       enabled => $non_pcmk_start,
643     }
644     class {'::swift::storage::container':
645       manage_service => $non_pcmk_start,
646       enabled => $non_pcmk_start,
647     }
648     class {'::swift::storage::object':
649       manage_service => $non_pcmk_start,
650       enabled => $non_pcmk_start,
651     }
652     if(!defined(File['/srv/node'])) {
653       file { '/srv/node':
654         ensure  => directory,
655         owner   => 'swift',
656         group   => 'swift',
657         require => Package['openstack-swift'],
658       }
659     }
660     $swift_components = ['account', 'container', 'object']
661     swift::storage::filter::recon { $swift_components : }
662     swift::storage::filter::healthcheck { $swift_components : }
663   }
664
665   # Ceilometer
666   $ceilometer_backend = downcase(hiera('ceilometer_backend'))
667   case $ceilometer_backend {
668     /mysql/ : {
669       $ceilometer_database_connection = hiera('ceilometer_mysql_conn_string')
670     }
671     default : {
672       $mongo_node_string = join($mongo_node_ips_with_port, ',')
673       $ceilometer_database_connection = "mongodb://${mongo_node_string}/ceilometer?replicaSet=${mongodb_replset}"
674     }
675   }
676   include ::ceilometer
677   class { '::ceilometer::api' :
678     manage_service => false,
679     enabled => false,
680   }
681   class { '::ceilometer::agent::notification' :
682     manage_service => false,
683     enabled => false,
684   }
685   class { '::ceilometer::agent::central' :
686     manage_service => false,
687     enabled => false,
688   }
689   class { '::ceilometer::alarm::notifier' :
690     manage_service => false,
691     enabled => false,
692   }
693   class { '::ceilometer::alarm::evaluator' :
694     manage_service => false,
695     enabled => false,
696   }
697   class { '::ceilometer::collector' :
698     manage_service => false,
699     enabled => false,
700   }
701   include ::ceilometer::expirer
702   class { '::ceilometer::db' :
703     database_connection => $ceilometer_database_connection,
704     sync_db             => $sync_db,
705   }
706   include ceilometer::agent::auth
707
708   Cron <| title == 'ceilometer-expirer' |> { command => "sleep $((\$(od -A n -t d -N 3 /dev/urandom) % 86400)) && ${::ceilometer::params::expirer_command}" }
709
710   # Heat
711   class { '::heat' :
712     sync_db => $sync_db,
713   }
714   class { '::heat::api' :
715     manage_service => false,
716     enabled => false,
717   }
718   class { '::heat::api_cfn' :
719     manage_service => false,
720     enabled => false,
721   }
722   class { '::heat::api_cloudwatch' :
723     manage_service => false,
724     enabled => false,
725   }
726   class { '::heat::engine' :
727     manage_service => false,
728     enabled => false,
729   }
730
731   # httpd/apache and horizon
732   # NOTE(gfidente): server-status can be consumed by the pacemaker resource agent
733   include ::apache
734   include ::apache::mod::status
735   $vhost_params = {
736     add_listen => false,
737     priority   => 10,
738   }
739   class { 'horizon':
740     cache_server_ip    => hiera('memcache_node_ips', '127.0.0.1'),
741     vhost_extra_params => $vhost_params,
742     server_aliases     => $::hostname,
743   }
744
745   $snmpd_user = hiera('snmpd_readonly_user_name')
746   snmp::snmpv3_user { $snmpd_user:
747     authtype => 'MD5',
748     authpass => hiera('snmpd_readonly_user_password'),
749   }
750   class { 'snmp':
751     agentaddress => ['udp:161','udp6:[::1]:161'],
752     snmpd_config => [ join(['rouser ', hiera('snmpd_readonly_user_name')]), 'proc  cron', 'includeAllDisks  10%', 'master agentx', 'trapsink localhost public', 'iquerySecName internalUser', 'rouser internalUser', 'defaultMonitors yes', 'linkUpDownNotifications yes' ],
753   }
754
755 } #END STEP 3
756
757 if hiera('step') >= 4 {
758   if $pacemaker_master {
759
760     # Keystone
761     pacemaker::resource::service { $::keystone::params::service_name :
762       clone_params => "interleave=true",
763     }
764
765     # Cinder
766     pacemaker::resource::service { $::cinder::params::api_service :
767       clone_params => "interleave=true",
768       require      => Pacemaker::Resource::Service[$::keystone::params::service_name],
769     }
770     pacemaker::resource::service { $::cinder::params::scheduler_service :
771       clone_params => "interleave=true",
772     }
773     pacemaker::resource::service { $::cinder::params::volume_service : }
774
775     pacemaker::constraint::base { 'keystone-then-cinder-api-constraint':
776       constraint_type => 'order',
777       first_resource  => "${::keystone::params::service_name}-clone",
778       second_resource => "${::cinder::params::api_service}-clone",
779       first_action    => 'start',
780       second_action   => 'start',
781       require         => [Pacemaker::Resource::Service[$::cinder::params::api_service],
782                           Pacemaker::Resource::Service[$::keystone::params::service_name]],
783     }
784     pacemaker::constraint::base { 'cinder-api-then-cinder-scheduler-constraint':
785       constraint_type => "order",
786       first_resource => "${::cinder::params::api_service}-clone",
787       second_resource => "${::cinder::params::scheduler_service}-clone",
788       first_action => "start",
789       second_action => "start",
790       require => [Pacemaker::Resource::Service[$::cinder::params::api_service],
791                   Pacemaker::Resource::Service[$::cinder::params::scheduler_service]],
792     }
793     pacemaker::constraint::colocation { 'cinder-scheduler-with-cinder-api-colocation':
794       source => "${::cinder::params::scheduler_service}-clone",
795       target => "${::cinder::params::api_service}-clone",
796       score => "INFINITY",
797       require => [Pacemaker::Resource::Service[$::cinder::params::api_service],
798                   Pacemaker::Resource::Service[$::cinder::params::scheduler_service]],
799     }
800     pacemaker::constraint::base { 'cinder-scheduler-then-cinder-volume-constraint':
801       constraint_type => "order",
802       first_resource => "${::cinder::params::scheduler_service}-clone",
803       second_resource => "${::cinder::params::volume_service}",
804       first_action => "start",
805       second_action => "start",
806       require => [Pacemaker::Resource::Service[$::cinder::params::scheduler_service],
807                   Pacemaker::Resource::Service[$::cinder::params::volume_service]],
808     }
809     pacemaker::constraint::colocation { 'cinder-volume-with-cinder-scheduler-colocation':
810       source => "${::cinder::params::volume_service}",
811       target => "${::cinder::params::scheduler_service}-clone",
812       score => "INFINITY",
813       require => [Pacemaker::Resource::Service[$::cinder::params::scheduler_service],
814                   Pacemaker::Resource::Service[$::cinder::params::volume_service]],
815     }
816
817     # Glance
818     pacemaker::resource::service { $::glance::params::registry_service_name :
819       clone_params => "interleave=true",
820       require      => Pacemaker::Resource::Service[$::keystone::params::service_name],
821     }
822     pacemaker::resource::service { $::glance::params::api_service_name :
823       clone_params => "interleave=true",
824     }
825
826     pacemaker::constraint::base { 'keystone-then-glance-registry-constraint':
827       constraint_type => 'order',
828       first_resource  => "${::keystone::params::service_name}-clone",
829       second_resource => "${::glance::params::registry_service_name}-clone",
830       first_action    => 'start',
831       second_action   => 'start',
832       require         => [Pacemaker::Resource::Service[$::glance::params::registry_service_name],
833                           Pacemaker::Resource::Service[$::keystone::params::service_name]],
834     }
835     pacemaker::constraint::base { 'glance-registry-then-glance-api-constraint':
836       constraint_type => "order",
837       first_resource  => "${::glance::params::registry_service_name}-clone",
838       second_resource => "${::glance::params::api_service_name}-clone",
839       first_action    => "start",
840       second_action   => "start",
841       require => [Pacemaker::Resource::Service[$::glance::params::registry_service_name],
842                   Pacemaker::Resource::Service[$::glance::params::api_service_name]],
843     }
844     pacemaker::constraint::colocation { 'glance-api-with-glance-registry-colocation':
845       source  => "${::glance::params::api_service_name}-clone",
846       target  => "${::glance::params::registry_service_name}-clone",
847       score   => "INFINITY",
848       require => [Pacemaker::Resource::Service[$::glance::params::registry_service_name],
849                   Pacemaker::Resource::Service[$::glance::params::api_service_name]],
850     }
851
852     # Neutron
853     # NOTE(gfidente): Neutron will try to populate the database with some data
854     # as soon as neutron-server is started; to avoid races we want to make this
855     # happen only on one node, before normal Pacemaker initialization
856     # https://bugzilla.redhat.com/show_bug.cgi?id=1233061
857     exec { 'neutron-server-start-wait-stop' :
858       command   => "systemctl start neutron-server && \
859                     sleep 5s && \
860                     systemctl stop neutron-server",
861       path      => ["/usr/bin", "/usr/sbin"],
862     } ->
863     pacemaker::resource::service { $::neutron::params::server_service:
864       op_params => "start timeout=90",
865       clone_params   => "interleave=true",
866       require => Pacemaker::Resource::Service[$::keystone::params::service_name]
867     }
868     pacemaker::resource::service { $::neutron::params::l3_agent_service:
869       clone_params   => "interleave=true",
870     }
871     pacemaker::resource::service { $::neutron::params::dhcp_agent_service:
872       clone_params   => "interleave=true",
873     }
874     pacemaker::resource::service { $::neutron::params::ovs_agent_service:
875       clone_params => "interleave=true",
876     }
877     pacemaker::resource::service { $::neutron::params::metadata_agent_service:
878       clone_params => "interleave=true",
879     }
880     pacemaker::resource::ocf { $::neutron::params::ovs_cleanup_service:
881       ocf_agent_name => "neutron:OVSCleanup",
882       clone_params => "interleave=true",
883     }
884     pacemaker::resource::ocf { 'neutron-netns-cleanup':
885       ocf_agent_name => "neutron:NetnsCleanup",
886       clone_params => "interleave=true",
887     }
888     pacemaker::resource::ocf { 'neutron-scale':
889       ocf_agent_name => "neutron:NeutronScale",
890       clone_params => "globally-unique=true clone-max=3 interleave=true",
891     }
892     pacemaker::constraint::base { 'keystone-to-neutron-server-constraint':
893       constraint_type => "order",
894       first_resource => "${::keystone::params::service_name}-clone",
895       second_resource => "${::neutron::params::server_service}-clone",
896       first_action => "start",
897       second_action => "start",
898       require => [Pacemaker::Resource::Service[$::keystone::params::service_name],
899                   Pacemaker::Resource::Service[$::neutron::params::server_service]],
900     }
901     pacemaker::constraint::base { 'neutron-server-to-neutron-scale-constraint':
902       constraint_type => "order",
903       first_resource => "${::neutron::params::server_service}-clone",
904       second_resource => "neutron-scale-clone",
905       first_action => "start",
906       second_action => "start",
907       require => [Pacemaker::Resource::Service[$::neutron::params::server_service],
908                   Pacemaker::Resource::Ocf['neutron-scale']],
909     }
910     pacemaker::constraint::base { 'neutron-scale-to-ovs-cleanup-constraint':
911       constraint_type => "order",
912       first_resource => "neutron-scale-clone",
913       second_resource => "${::neutron::params::ovs_cleanup_service}-clone",
914       first_action => "start",
915       second_action => "start",
916       require => [Pacemaker::Resource::Ocf['neutron-scale'],
917                   Pacemaker::Resource::Ocf["${::neutron::params::ovs_cleanup_service}"]],
918     }
919     pacemaker::constraint::colocation { 'neutron-scale-to-ovs-cleanup-colocation':
920       source => "${::neutron::params::ovs_cleanup_service}-clone",
921       target => "neutron-scale-clone",
922       score => "INFINITY",
923       require => [Pacemaker::Resource::Ocf['neutron-scale'],
924                   Pacemaker::Resource::Ocf["${::neutron::params::ovs_cleanup_service}"]],
925     }
926     pacemaker::constraint::base { 'neutron-ovs-cleanup-to-netns-cleanup-constraint':
927       constraint_type => "order",
928       first_resource => "${::neutron::params::ovs_cleanup_service}-clone",
929       second_resource => "neutron-netns-cleanup-clone",
930       first_action => "start",
931       second_action => "start",
932       require => [Pacemaker::Resource::Ocf["${::neutron::params::ovs_cleanup_service}"],
933                   Pacemaker::Resource::Ocf['neutron-netns-cleanup']],
934     }
935     pacemaker::constraint::colocation { 'neutron-ovs-cleanup-to-netns-cleanup-colocation':
936       source => "neutron-netns-cleanup-clone",
937       target => "${::neutron::params::ovs_cleanup_service}-clone",
938       score => "INFINITY",
939       require => [Pacemaker::Resource::Ocf["${::neutron::params::ovs_cleanup_service}"],
940                   Pacemaker::Resource::Ocf['neutron-netns-cleanup']],
941     }
942     pacemaker::constraint::base { 'neutron-netns-cleanup-to-openvswitch-agent-constraint':
943       constraint_type => "order",
944       first_resource => "neutron-netns-cleanup-clone",
945       second_resource => "${::neutron::params::ovs_agent_service}-clone",
946       first_action => "start",
947       second_action => "start",
948       require => [Pacemaker::Resource::Ocf["neutron-netns-cleanup"],
949                   Pacemaker::Resource::Service["${::neutron::params::ovs_agent_service}"]],
950     }
951     pacemaker::constraint::colocation { 'neutron-netns-cleanup-to-openvswitch-agent-colocation':
952       source => "${::neutron::params::ovs_agent_service}-clone",
953       target => "neutron-netns-cleanup-clone",
954       score => "INFINITY",
955       require => [Pacemaker::Resource::Ocf["neutron-netns-cleanup"],
956                   Pacemaker::Resource::Service["${::neutron::params::ovs_agent_service}"]],
957     }
958     pacemaker::constraint::base { 'neutron-openvswitch-agent-to-dhcp-agent-constraint':
959       constraint_type => "order",
960       first_resource => "${::neutron::params::ovs_agent_service}-clone",
961       second_resource => "${::neutron::params::dhcp_agent_service}-clone",
962       first_action => "start",
963       second_action => "start",
964       require => [Pacemaker::Resource::Service["${::neutron::params::ovs_agent_service}"],
965                   Pacemaker::Resource::Service["${::neutron::params::dhcp_agent_service}"]],
966
967     }
968     pacemaker::constraint::colocation { 'neutron-openvswitch-agent-to-dhcp-agent-colocation':
969       source => "${::neutron::params::dhcp_agent_service}-clone",
970       target => "${::neutron::params::ovs_agent_service}-clone",
971       score => "INFINITY",
972       require => [Pacemaker::Resource::Service["${::neutron::params::ovs_agent_service}"],
973                   Pacemaker::Resource::Service["${::neutron::params::dhcp_agent_service}"]],
974     }
975     pacemaker::constraint::base { 'neutron-dhcp-agent-to-l3-agent-constraint':
976       constraint_type => "order",
977       first_resource => "${::neutron::params::dhcp_agent_service}-clone",
978       second_resource => "${::neutron::params::l3_agent_service}-clone",
979       first_action => "start",
980       second_action => "start",
981       require => [Pacemaker::Resource::Service["${::neutron::params::dhcp_agent_service}"],
982                   Pacemaker::Resource::Service["${::neutron::params::l3_agent_service}"]]
983     }
984     pacemaker::constraint::colocation { 'neutron-dhcp-agent-to-l3-agent-colocation':
985       source => "${::neutron::params::l3_agent_service}-clone",
986       target => "${::neutron::params::dhcp_agent_service}-clone",
987       score => "INFINITY",
988       require => [Pacemaker::Resource::Service["${::neutron::params::dhcp_agent_service}"],
989                   Pacemaker::Resource::Service["${::neutron::params::l3_agent_service}"]]
990     }
991     pacemaker::constraint::base { 'neutron-l3-agent-to-metadata-agent-constraint':
992       constraint_type => "order",
993       first_resource => "${::neutron::params::l3_agent_service}-clone",
994       second_resource => "${::neutron::params::metadata_agent_service}-clone",
995       first_action => "start",
996       second_action => "start",
997       require => [Pacemaker::Resource::Service["${::neutron::params::l3_agent_service}"],
998                   Pacemaker::Resource::Service["${::neutron::params::metadata_agent_service}"]]
999     }
1000     pacemaker::constraint::colocation { 'neutron-l3-agent-to-metadata-agent-colocation':
1001       source => "${::neutron::params::metadata_agent_service}-clone",
1002       target => "${::neutron::params::l3_agent_service}-clone",
1003       score => "INFINITY",
1004       require => [Pacemaker::Resource::Service["${::neutron::params::l3_agent_service}"],
1005                   Pacemaker::Resource::Service["${::neutron::params::metadata_agent_service}"]]
1006     }
1007
1008     # Nova
1009     pacemaker::resource::service { $::nova::params::api_service_name :
1010       clone_params    => "interleave=true",
1011       op_params       => "monitor start-delay=10s",
1012     }
1013     pacemaker::resource::service { $::nova::params::conductor_service_name :
1014       clone_params    => "interleave=true",
1015       op_params       => "monitor start-delay=10s",
1016     }
1017     pacemaker::resource::service { $::nova::params::consoleauth_service_name :
1018       clone_params    => "interleave=true",
1019       op_params       => "monitor start-delay=10s",
1020       require         => Pacemaker::Resource::Service[$::keystone::params::service_name],
1021     }
1022     pacemaker::resource::service { $::nova::params::vncproxy_service_name :
1023       clone_params    => "interleave=true",
1024       op_params       => "monitor start-delay=10s",
1025     }
1026     pacemaker::resource::service { $::nova::params::scheduler_service_name :
1027       clone_params    => "interleave=true",
1028       op_params       => "monitor start-delay=10s",
1029     }
1030
1031     pacemaker::constraint::base { 'keystone-then-nova-consoleauth-constraint':
1032       constraint_type => 'order',
1033       first_resource  => "${::keystone::params::service_name}-clone",
1034       second_resource => "${::nova::params::consoleauth_service_name}-clone",
1035       first_action    => 'start',
1036       second_action   => 'start',
1037       require         => [Pacemaker::Resource::Service[$::nova::params::consoleauth_service_name],
1038                           Pacemaker::Resource::Service[$::keystone::params::service_name]],
1039     }
1040     pacemaker::constraint::base { 'nova-consoleauth-then-nova-vncproxy-constraint':
1041       constraint_type => "order",
1042       first_resource  => "${::nova::params::consoleauth_service_name}-clone",
1043       second_resource => "${::nova::params::vncproxy_service_name}-clone",
1044       first_action    => "start",
1045       second_action   => "start",
1046       require => [Pacemaker::Resource::Service[$::nova::params::consoleauth_service_name],
1047                   Pacemaker::Resource::Service[$::nova::params::vncproxy_service_name]],
1048     }
1049     pacemaker::constraint::colocation { 'nova-vncproxy-with-nova-consoleauth-colocation':
1050       source => "${::nova::params::vncproxy_service_name}-clone",
1051       target => "${::nova::params::consoleauth_service_name}-clone",
1052       score => "INFINITY",
1053       require => [Pacemaker::Resource::Service[$::nova::params::consoleauth_service_name],
1054                   Pacemaker::Resource::Service[$::nova::params::vncproxy_service_name]],
1055     }
1056     # FIXME(gfidente): novncproxy will not start unless websockify is updated to 0.6
1057     # which is not the case for f20 nor f21; ucomment when it becomes available
1058     #pacemaker::constraint::base { 'nova-vncproxy-then-nova-api-constraint':
1059     #  constraint_type => "order",
1060     #  first_resource  => "${::nova::params::vncproxy_service_name}-clone",
1061     #  second_resource => "${::nova::params::api_service_name}-clone",
1062     #  first_action    => "start",
1063     #  second_action   => "start",
1064     #  require => [Pacemaker::Resource::Service[$::nova::params::vncproxy_service_name],
1065     #              Pacemaker::Resource::Service[$::nova::params::api_service_name]],
1066     #}
1067     #pacemaker::constraint::colocation { 'nova-api-with-nova-vncproxy-colocation':
1068     #  source => "${::nova::params::api_service_name}-clone",
1069     #  target => "${::nova::params::vncproxy_service_name}-clone",
1070     #  score => "INFINITY",
1071     #  require => [Pacemaker::Resource::Service[$::nova::params::vncproxy_service_name],
1072     #              Pacemaker::Resource::Service[$::nova::params::api_service_name]],
1073     #}
1074     pacemaker::constraint::base { 'nova-api-then-nova-scheduler-constraint':
1075       constraint_type => "order",
1076       first_resource  => "${::nova::params::api_service_name}-clone",
1077       second_resource => "${::nova::params::scheduler_service_name}-clone",
1078       first_action    => "start",
1079       second_action   => "start",
1080       require => [Pacemaker::Resource::Service[$::nova::params::api_service_name],
1081                   Pacemaker::Resource::Service[$::nova::params::scheduler_service_name]],
1082     }
1083     pacemaker::constraint::colocation { 'nova-scheduler-with-nova-api-colocation':
1084       source => "${::nova::params::scheduler_service_name}-clone",
1085       target => "${::nova::params::api_service_name}-clone",
1086       score => "INFINITY",
1087       require => [Pacemaker::Resource::Service[$::nova::params::api_service_name],
1088                   Pacemaker::Resource::Service[$::nova::params::scheduler_service_name]],
1089     }
1090     pacemaker::constraint::base { 'nova-scheduler-then-nova-conductor-constraint':
1091       constraint_type => "order",
1092       first_resource  => "${::nova::params::scheduler_service_name}-clone",
1093       second_resource => "${::nova::params::conductor_service_name}-clone",
1094       first_action    => "start",
1095       second_action   => "start",
1096       require => [Pacemaker::Resource::Service[$::nova::params::scheduler_service_name],
1097                   Pacemaker::Resource::Service[$::nova::params::conductor_service_name]],
1098     }
1099     pacemaker::constraint::colocation { 'nova-conductor-with-nova-scheduler-colocation':
1100       source => "${::nova::params::conductor_service_name}-clone",
1101       target => "${::nova::params::scheduler_service_name}-clone",
1102       score => "INFINITY",
1103       require => [Pacemaker::Resource::Service[$::nova::params::scheduler_service_name],
1104                   Pacemaker::Resource::Service[$::nova::params::conductor_service_name]],
1105     }
1106
1107     # Ceilometer
1108     pacemaker::resource::service { $::ceilometer::params::agent_central_service_name :
1109       clone_params => 'interleave=true',
1110       require      => [Pacemaker::Resource::Service[$::keystone::params::service_name],
1111                        Pacemaker::Resource::Service[$::mongodb::params::service_name]],
1112     }
1113     pacemaker::resource::service { $::ceilometer::params::collector_service_name :
1114       clone_params => 'interleave=true',
1115     }
1116     pacemaker::resource::service { $::ceilometer::params::api_service_name :
1117       clone_params => 'interleave=true',
1118     }
1119     pacemaker::resource::service { $::ceilometer::params::alarm_evaluator_service_name :
1120       clone_params => 'interleave=true',
1121     }
1122     pacemaker::resource::service { $::ceilometer::params::alarm_notifier_service_name :
1123       clone_params => 'interleave=true',
1124     }
1125     pacemaker::resource::service { $::ceilometer::params::agent_notification_service_name :
1126       clone_params => 'interleave=true',
1127     }
1128     pacemaker::resource::ocf { 'delay' :
1129       ocf_agent_name  => 'heartbeat:Delay',
1130       clone_params    => 'interleave=true',
1131       resource_params => 'startdelay=10',
1132     }
1133     pacemaker::constraint::base { 'keystone-then-ceilometer-central-constraint':
1134       constraint_type => 'order',
1135       first_resource  => "${::keystone::params::service_name}-clone",
1136       second_resource => "${::ceilometer::params::agent_central_service_name}-clone",
1137       first_action    => 'start',
1138       second_action   => 'start',
1139       require         => [Pacemaker::Resource::Service[$::ceilometer::params::agent_central_service_name],
1140                           Pacemaker::Resource::Service[$::keystone::params::service_name]],
1141     }
1142     pacemaker::constraint::base { 'ceilometer-central-then-ceilometer-collector-constraint':
1143       constraint_type => 'order',
1144       first_resource  => "${::ceilometer::params::agent_central_service_name}-clone",
1145       second_resource => "${::ceilometer::params::collector_service_name}-clone",
1146       first_action    => 'start',
1147       second_action   => 'start',
1148       require         => [Pacemaker::Resource::Service[$::ceilometer::params::agent_central_service_name],
1149                           Pacemaker::Resource::Service[$::ceilometer::params::collector_service_name]],
1150     }
1151     pacemaker::constraint::base { 'ceilometer-collector-then-ceilometer-api-constraint':
1152       constraint_type => 'order',
1153       first_resource  => "${::ceilometer::params::collector_service_name}-clone",
1154       second_resource => "${::ceilometer::params::api_service_name}-clone",
1155       first_action    => 'start',
1156       second_action   => 'start',
1157       require         => [Pacemaker::Resource::Service[$::ceilometer::params::collector_service_name],
1158                           Pacemaker::Resource::Service[$::ceilometer::params::api_service_name]],
1159     }
1160     pacemaker::constraint::colocation { 'ceilometer-api-with-ceilometer-collector-colocation':
1161       source  => "${::ceilometer::params::api_service_name}-clone",
1162       target  => "${::ceilometer::params::collector_service_name}-clone",
1163       score   => 'INFINITY',
1164       require => [Pacemaker::Resource::Service[$::ceilometer::params::api_service_name],
1165                   Pacemaker::Resource::Service[$::ceilometer::params::collector_service_name]],
1166     }
1167     pacemaker::constraint::base { 'ceilometer-api-then-ceilometer-delay-constraint':
1168       constraint_type => 'order',
1169       first_resource  => "${::ceilometer::params::api_service_name}-clone",
1170       second_resource => 'delay-clone',
1171       first_action    => 'start',
1172       second_action   => 'start',
1173       require         => [Pacemaker::Resource::Service[$::ceilometer::params::api_service_name],
1174                           Pacemaker::Resource::Ocf['delay']],
1175     }
1176     pacemaker::constraint::colocation { 'ceilometer-delay-with-ceilometer-api-colocation':
1177       source  => 'delay-clone',
1178       target  => "${::ceilometer::params::api_service_name}-clone",
1179       score   => 'INFINITY',
1180       require => [Pacemaker::Resource::Service[$::ceilometer::params::api_service_name],
1181                   Pacemaker::Resource::Ocf['delay']],
1182     }
1183     pacemaker::constraint::base { 'ceilometer-delay-then-ceilometer-alarm-evaluator-constraint':
1184       constraint_type => 'order',
1185       first_resource  => 'delay-clone',
1186       second_resource => "${::ceilometer::params::alarm_evaluator_service_name}-clone",
1187       first_action    => 'start',
1188       second_action   => 'start',
1189       require         => [Pacemaker::Resource::Service[$::ceilometer::params::alarm_evaluator_service_name],
1190                           Pacemaker::Resource::Ocf['delay']],
1191     }
1192     pacemaker::constraint::colocation { 'ceilometer-alarm-evaluator-with-ceilometer-delay-colocation':
1193       source  => "${::ceilometer::params::alarm_evaluator_service_name}-clone",
1194       target  => 'delay-clone',
1195       score   => 'INFINITY',
1196       require => [Pacemaker::Resource::Service[$::ceilometer::params::api_service_name],
1197                   Pacemaker::Resource::Ocf['delay']],
1198     }
1199     pacemaker::constraint::base { 'ceilometer-alarm-evaluator-then-ceilometer-alarm-notifier-constraint':
1200       constraint_type => 'order',
1201       first_resource  => "${::ceilometer::params::alarm_evaluator_service_name}-clone",
1202       second_resource => "${::ceilometer::params::alarm_notifier_service_name}-clone",
1203       first_action    => 'start',
1204       second_action   => 'start',
1205       require         => [Pacemaker::Resource::Service[$::ceilometer::params::alarm_evaluator_service_name],
1206                           Pacemaker::Resource::Service[$::ceilometer::params::alarm_notifier_service_name]],
1207     }
1208     pacemaker::constraint::colocation { 'ceilometer-alarm-notifier-with-ceilometer-alarm-evaluator-colocation':
1209       source  => "${::ceilometer::params::alarm_notifier_service_name}-clone",
1210       target  => "${::ceilometer::params::alarm_evaluator_service_name}-clone",
1211       score   => 'INFINITY',
1212       require => [Pacemaker::Resource::Service[$::ceilometer::params::alarm_evaluator_service_name],
1213                   Pacemaker::Resource::Service[$::ceilometer::params::alarm_notifier_service_name]],
1214     }
1215     pacemaker::constraint::base { 'ceilometer-alarm-notifier-then-ceilometer-notification-constraint':
1216       constraint_type => 'order',
1217       first_resource  => "${::ceilometer::params::alarm_notifier_service_name}-clone",
1218       second_resource => "${::ceilometer::params::agent_notification_service_name}-clone",
1219       first_action    => 'start',
1220       second_action   => 'start',
1221       require         => [Pacemaker::Resource::Service[$::ceilometer::params::agent_notification_service_name],
1222                           Pacemaker::Resource::Service[$::ceilometer::params::alarm_notifier_service_name]],
1223     }
1224     pacemaker::constraint::colocation { 'ceilometer-notification-with-ceilometer-alarm-notifier-colocation':
1225       source  => "${::ceilometer::params::agent_notification_service_name}-clone",
1226       target  => "${::ceilometer::params::alarm_notifier_service_name}-clone",
1227       score   => 'INFINITY',
1228       require => [Pacemaker::Resource::Service[$::ceilometer::params::agent_notification_service_name],
1229                   Pacemaker::Resource::Service[$::ceilometer::params::alarm_notifier_service_name]],
1230     }
1231     if downcase(hiera('ceilometer_backend')) == 'mongodb' {
1232       pacemaker::constraint::base { 'mongodb-then-ceilometer-central-constraint':
1233         constraint_type => 'order',
1234         first_resource  => "${::mongodb::params::service_name}-clone",
1235         second_resource => "${::ceilometer::params::agent_central_service_name}-clone",
1236         first_action    => 'start',
1237         second_action   => 'start',
1238         require         => [Pacemaker::Resource::Service[$::ceilometer::params::agent_central_service_name],
1239                             Pacemaker::Resource::Service[$::mongodb::params::service_name]],
1240       }
1241     }
1242     pacemaker::constraint::base { 'vip-redis-then-ceilometer-central':
1243       constraint_type => 'order',
1244       first_resource  => "ip-${redis_vip}",
1245       second_resource => "${::ceilometer::params::agent_central_service_name}-clone",
1246       first_action    => 'start',
1247       second_action   => 'start',
1248       require => [Pacemaker::Resource::Service[$::ceilometer::params::agent_central_service_name],
1249                   Pacemaker::Resource::Ip['vip-redis']],
1250     }
1251
1252     # Heat
1253     pacemaker::resource::service { $::heat::params::api_service_name :
1254       clone_params => 'interleave=true',
1255     }
1256     pacemaker::resource::service { $::heat::params::api_cloudwatch_service_name :
1257       clone_params => 'interleave=true',
1258     }
1259     pacemaker::resource::service { $::heat::params::api_cfn_service_name :
1260       clone_params => 'interleave=true',
1261     }
1262     pacemaker::resource::service { $::heat::params::engine_service_name :
1263       clone_params => 'interleave=true',
1264     }
1265     pacemaker::constraint::base { 'keystone-then-heat-api-constraint':
1266       constraint_type => 'order',
1267       first_resource  => "${::keystone::params::service_name}-clone",
1268       second_resource => "${::heat::params::api_service_name}-clone",
1269       first_action    => 'start',
1270       second_action   => 'start',
1271       require         => [Pacemaker::Resource::Service[$::heat::params::api_service_name],
1272                           Pacemaker::Resource::Service[$::keystone::params::service_name]],
1273     }
1274     pacemaker::constraint::base { 'heat-api-then-heat-api-cfn-constraint':
1275       constraint_type => 'order',
1276       first_resource  => "${::heat::params::api_service_name}-clone",
1277       second_resource => "${::heat::params::api_cfn_service_name}-clone",
1278       first_action    => 'start',
1279       second_action   => 'start',
1280       require => [Pacemaker::Resource::Service[$::heat::params::api_service_name],
1281                   Pacemaker::Resource::Service[$::heat::params::api_cfn_service_name]],
1282     }
1283     pacemaker::constraint::colocation { 'heat-api-cfn-with-heat-api-colocation':
1284       source  => "${::heat::params::api_cfn_service_name}-clone",
1285       target  => "${::heat::params::api_service_name}-clone",
1286       score   => 'INFINITY',
1287       require => [Pacemaker::Resource::Service[$::heat::params::api_cfn_service_name],
1288                   Pacemaker::Resource::Service[$::heat::params::api_service_name]],
1289     }
1290     pacemaker::constraint::base { 'heat-api-cfn-then-heat-api-cloudwatch-constraint':
1291       constraint_type => 'order',
1292       first_resource  => "${::heat::params::api_cfn_service_name}-clone",
1293       second_resource => "${::heat::params::api_cloudwatch_service_name}-clone",
1294       first_action    => 'start',
1295       second_action   => 'start',
1296       require => [Pacemaker::Resource::Service[$::heat::params::api_cloudwatch_service_name],
1297                   Pacemaker::Resource::Service[$::heat::params::api_cfn_service_name]],
1298     }
1299     pacemaker::constraint::colocation { 'heat-api-cloudwatch-with-heat-api-cfn-colocation':
1300       source  => "${::heat::params::api_cloudwatch_service_name}-clone",
1301       target  => "${::heat::params::api_cfn_service_name}-clone",
1302       score   => 'INFINITY',
1303       require => [Pacemaker::Resource::Service[$::heat::params::api_cfn_service_name],
1304                   Pacemaker::Resource::Service[$::heat::params::api_cloudwatch_service_name]],
1305     }
1306     pacemaker::constraint::base { 'heat-api-cloudwatch-then-heat-engine-constraint':
1307       constraint_type => 'order',
1308       first_resource  => "${::heat::params::api_cloudwatch_service_name}-clone",
1309       second_resource => "${::heat::params::engine_service_name}-clone",
1310       first_action    => 'start',
1311       second_action   => 'start',
1312       require => [Pacemaker::Resource::Service[$::heat::params::api_cloudwatch_service_name],
1313                   Pacemaker::Resource::Service[$::heat::params::engine_service_name]],
1314     }
1315     pacemaker::constraint::colocation { 'heat-engine-with-heat-api-cloudwatch-colocation':
1316       source  => "${::heat::params::engine_service_name}-clone",
1317       target  => "${::heat::params::api_cloudwatch_service_name}-clone",
1318       score   => 'INFINITY',
1319       require => [Pacemaker::Resource::Service[$::heat::params::api_cloudwatch_service_name],
1320                   Pacemaker::Resource::Service[$::heat::params::engine_service_name]],
1321     }
1322     pacemaker::constraint::base { 'ceilometer-notification-then-heat-api-constraint':
1323       constraint_type => 'order',
1324       first_resource  => "${::ceilometer::params::agent_notification_service_name}-clone",
1325       second_resource => "${::heat::params::api_service_name}-clone",
1326       first_action    => 'start',
1327       second_action   => 'start',
1328       require         => [Pacemaker::Resource::Service[$::heat::params::api_service_name],
1329                           Pacemaker::Resource::Service[$::ceilometer::params::agent_notification_service_name]],
1330     }
1331
1332     # Horizon
1333     pacemaker::resource::service { $::horizon::params::http_service:
1334         clone_params => "interleave=true",
1335     }
1336
1337
1338   }
1339
1340 } #END STEP 4