Controller: consolidated nested stack
authorDan Prince <dprince@redhat.com>
Wed, 14 Jan 2015 19:58:35 +0000 (14:58 -0500)
committerDan Prince <dprince@redhat.com>
Tue, 27 Jan 2015 14:04:37 +0000 (09:04 -0500)
In I228216a0b55ff2d384b281d9ad2a61b93d58dab9 we split
out just the Controller software config in an effort
to provide hooks for alternate implementations (puppet).

This sort of worked but caused quirky ordering issues
with signal handling. It also causes problems for Tuskar
which would prefer to think of these nested stacks and
not have us split out just the software configs like this.

This patch moves all the controller related stuff for
our two implementations:

 controller.yaml: is used by os-apply-config (uses the
tripleo-image-elements)
 controller-puppet.yaml: uses stackforge puppet-* modules for
configuration

By duplicating the entire controller in this manner we make
it much easier to create dependencies and implement proper
signal handling. The only (temporary) downside is the duplication
of parameters most of which will eventually go away when we move towards
using the global parameters via Heat environment files instead.

Change-Id: Iaf3c889d7c8815f862308cd8e15ce1010059f5c6

controller-config-puppet.yaml [deleted file]
controller-config.yaml [deleted file]
controller-puppet.yaml [new file with mode: 0644]
controller.yaml
overcloud-resource-registry-puppet.yaml
overcloud-resource-registry.yaml

diff --git a/controller-config-puppet.yaml b/controller-config-puppet.yaml
deleted file mode 100644 (file)
index 06d991d..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-# Copyright 2014 Red Hat, Inc.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-heat_template_version: 2014-10-16
-
-description: >
-  Puppet Software Config for the Controller.
-
-parameters:
-  controller_id:
-    type: string
-    hidden: true
-
-resources:
-
-  # The first manifest we execute is to setup HAProxy/Keepalived.
-  # NOTE(dprince): this example uses a composition class
-  # on the puppet side (loadbalancer.pp). This seemed like the
-  # cleanest way to encapulate the puppet resources definitions
-  # for HAProxy and Keepalived.
-  ControllerLoadbalancerPuppetConfig:
-    type: OS::Heat::SoftwareConfig
-    properties:
-      group: puppet
-      options:
-        enable_hiera: True
-        enable_facter: False
-      inputs:
-      outputs:
-      - name: result
-      config:
-        get_file: puppet/loadbalancer.pp
-
-  ControllerLoadbalancerPuppetDeployment:
-    type: OS::Heat::StructuredDeployment
-    properties:
-      name: puppet_1
-      server: {get_param: controller_id}
-      config: {get_resource: ControllerLoadbalancerPuppetConfig}
-      input_values:
-      signal_transport: NO_SIGNAL
-
-  ControllerPuppetConfig:
-    type: OS::Heat::SoftwareConfig
-    properties:
-      group: puppet
-      options:
-        enable_hiera: True
-        enable_facter: False
-      inputs:
-      - name: step
-      outputs:
-      - name: result
-      config:
-        get_file: puppet/overcloud_controller.pp
-
-  # Step through a series of two more Puppet runs using the same manifest.
-  # NOTE(dprince): Heat breakpoints would make for a really cool way to step
-  # through breakpoints in a controlled manner across the entire cluster
-  ControllerPuppetDeploymentTwo:
-    type: OS::Heat::StructuredDeployment
-    properties:
-      name: puppet_2
-      server: {get_param: controller_id}
-      config: {get_resource: ControllerPuppetConfig}
-      input_values:
-        step: 1
-      signal_transport: NO_SIGNAL
-      actions: ['CREATE'] # no need for two passes on an UPDATE
-
-  ControllerPuppetDeploymentThree:
-    type: OS::Heat::StructuredDeployment
-    properties:
-      name: puppet_3
-      server: {get_param: controller_id}
-      config: {get_resource: ControllerPuppetConfig}
-      input_values:
-        step: 2
-      signal_transport: NO_SIGNAL
-
-  # Map heat metadata into hiera datafiles
-  ControllerConfigImpl:
-    type: OS::Heat::StructuredConfig
-    properties:
-      group: os-apply-config
-      config:
-        hiera:
-          hierarchy:
-            - heat_config_%{::deploy_config_name}
-            - controller
-            - common
-          datafiles:
-            common:
-              raw_data: {get_file: puppet/hieradata/common.yaml}
-            controller:
-              raw_data: {get_file: puppet/hieradata/controller.yaml}
-              oac_data: # data we map in from other OAC configurations
-                bootstrap_nodeid: bootstrap_host.bootstrap_nodeid
-              mapped_data: # data supplied directly to this deployment configuration, etc
-                debug: {get_input: debug}
-                bootstack_nodeid: {get_input: bootstack_nodeid}
-                controller_host: {get_input: controller_host} #local-ipv4
-                # Cinder
-                cinder_lvm_loop_device_size: {get_input: cinder_lvm_loop_device_size}
-                cinder::volume::iscsi::iscsi_helper: {get_input: cinder_iscsi_helper}
-                cinder::volume::iscsi::iscsi_ip_address: {get_input: controller_host}
-                cinder::database_connection: {get_input: cinder_dsn}
-                cinder::api::keystone_password: {get_input: cinder_password}
-                cinder::api::keystone_auth_host: {get_input: controller_virtual_ip}
-                cinder::api::bind_host: {get_input: controller_host}
-                cinder::rabbit_userid: {get_input: rabbit_username}
-                cinder::rabbit_password: {get_input: rabbit_password}
-                #cinder::debug: {get_input: debug}
-                # Glance
-                glance::api::bind_port: {get_input: glance_port}
-                glance::api::bind_host: {get_input: controller_host}
-                glance::api::auth_host: {get_input: controller_virtual_ip}
-                glance::api::registry_host: {get_input: controller_host}
-                glance::api::keystone_password: {get_input: glance_password}
-                # used to construct glance_api_servers
-                glance_port: {get_input: glance_port}
-                glance_protocol: {get_input: glance_protocol}
-                glance_notifier_strategy: {get_input: glance_notifier_strategy}
-                glance_log_file: {get_input: glance_log_file}
-                glance_log_file: {get_input: glance_log_file}
-                glance::api::database_connection: {get_input: glance_dsn}
-                glance::registry::keystone_password: {get_input: glance_password}
-                glance::registry::database_connection: {get_input: glance_dsn}
-                glance::registry::bind_host: {get_input: controller_host}
-                glance::registry::auth_host: {get_input: controller_virtual_ip}
-                # Heat
-                heat_password: {get_input: heat_password}
-                heat_stack_domain_admin_password: {get_input: heat_stack_domain_admin_password}
-                heat_dsn: {get_input: heat_dsn}
-                heat.watch_server_url: {get_input: heat.watch_server_url}
-                heat.metadata_server_url: {get_input: heat.metadata_server_url}
-                heat.waitcondition_server_url: {get_input: heat.waitcondition_server_url}
-                # Keystone
-                keystone::admin_token: {get_input: admin_token}
-                keystone_ca_certificate: {get_input: keystone_ca_certificate}
-                keystone_signing_key: {get_input: keystone_signing_key}
-                keystone_signing_certificate: {get_input: keystone_signing_certificate}
-                keystone_ssl_certificate: {get_input: keystone_ssl_certificate}
-                keystone_ssl_certificate_key: {get_input: keystone_ssl_certificate_key}
-                keystone::database_connection: {get_input: keystone_dsn}
-                keystone::public_bind_host: {get_input: controller_host}
-                keystone::admin_bind_host: {get_input: controller_host}
-                #keystone::debug: {get_input: debug}
-                # MySQL
-                admin_password: {get_input: admin_password}
-                mysql_innodb_buffer_pool_size: {get_input: mysql_innodb_buffer_pool_size}
-                mysql_root_password: {get_input: mysql_root_password}
-                mysql_cluster_name: {get_input: mysql_cluster_name}
-                # Neutron
-                neutron::bind_host: {get_input: controller_host}
-                neutron::rabbit_password: {get_input: rabbit_password}
-                neutron::rabbit_user: {get_input: rabbit_user}
-                #neutron::debug: {get_input: debug}
-                neutron::server::auth_host: {get_input: controller_virtual_ip}
-                neutron::server::database_connection: {get_input: neutron_dsn}
-                neutron::agents::ml2::ovs::enable_tunneling: {get_input: neutron_enable_tunneling}
-                neutron::agents::ml2::ovs::local_ip: {get_input: controller_host}
-                neutron_flat_networks: {get_input: neutron_flat_networks}
-                neutron::agents::metadata::shared_secret: {get_input: neutron_metadata_proxy_shared_secret}
-                neutron_agent_mode: {get_input: neutron_agent_mode}
-                neutron_router_distributed: {get_input: neutron_router_distributed}
-                neutron_mechanism_drivers: {get_input: neutron_mechanism_drivers}
-                neutron_allow_l3agent_failover: {get_input: neutron_allow_l3agent_failover}
-                neutron::plugins::ml2::network_vlan_ranges: {get_input: neutron_network_vlan_ranges}
-                neutron_bridge_mappings: {get_input: neutron_bridge_mappings}
-                neutron_public_interface: {get_input: neutron_public_interface}
-                neutron_public_interface_raw_device: {get_input: neutron_public_interface_raw_device}
-                neutron_public_interface_default_route: {get_input: neutron_public_interface_default_route}
-                neutron_public_interface_tag: {get_input: neutron_public_interface_tag}
-                neutron_tenant_network_type: {get_input: neutron_tenant_network_type}
-                neutron_tunnel_types: {get_input: neutron_tunnel_types}
-                neutron::server::auth_password: {get_input: neutron_password}
-                neutron::agents::metadata::auth_password: {get_input: neutron_password}
-                neutron_dnsmasq_options: {get_input: neutron_dnsmasq_options}
-                neutron_dsn: {get_input: neutron_dsn}
-                # Ceilometer
-                ceilometer_metering_secret: {get_input: ceilometer_metering_secret}
-                ceilometer_password: {get_input: ceilometer_password}
-                ceilometer_dsn: {get_input: ceilometer_dsn}
-                snmpd_readonly_user_name: {get_input: snmpd_readonly_user_name}
-                snmpd_readonly_user_password: {get_input: snmpd_readonly_user_password}
-                # Nova
-                nova::rabbit_userid: {get_input: rabbit_username}
-                nova::rabbit_password: {get_input: rabbit_password}
-                nova::api::auth_host: {get_input: controller_virtual_ip}
-                nova::api::api_bind_address: {get_input: controller_host}
-                nova::api::metadata_listen: {get_input: controller_host}
-                nova::api::admin_password: {get_input: nova_password}
-                nova::database_connection: {get_input: nova_dsn}
-                nova::api::neutron_metadata_proxy_shared_secret: {get_input: neutron_metadata_proxy_shared_secret}
-                # Rabbit
-                rabbit_username: {get_input: rabbit_username}
-                rabbit_password: {get_input: rabbit_password}
-                rabbit_cookie: {get_input: rabbit_cookie}
-                rabbit_client_use_ssl: {get_input: rabbit_client_use_ssl}
-                rabbit_client_port: {get_input: rabbit_client_port}
-                # Misc
-                neutron_public_interface_ip: {get_input: neutron_public_interface_ip}
-                ntp_server: {get_input: ntp_server}
-                control_virtual_interface: {get_input: control_virtual_interface}
-                controller_virtual_ip: {get_input: controller_virtual_ip}
-                public_virtual_interface: {get_input: public_virtual_interface}
-                public_virtual_ip: {get_input: public_virtual_ip}
-                # Load Balancer (composition class parameters)
-                tripleo::loadbalancer::keystone_admin: true
-                tripleo::loadbalancer::keystone_public: true
-                tripleo::loadbalancer::neutron: true
-                tripleo::loadbalancer::cinder: true
-                tripleo::loadbalancer::glance_api: true
-                tripleo::loadbalancer::glance_registry: true
-                tripleo::loadbalancer::nova_ec2: true
-                tripleo::loadbalancer::nova_osapi: true
-                tripleo::loadbalancer::nova_metadata: true
-                tripleo::loadbalancer::nova_novncproxy: true
-                tripleo::loadbalancer::mysql: true
-                tripleo::loadbalancer::rabbitmq: true
-
-outputs:
-  config_id:
-    description: The ID of the ControllerConfigImpl resource.
-    value:
-      {get_resource: ControllerConfigImpl}
diff --git a/controller-config.yaml b/controller-config.yaml
deleted file mode 100644 (file)
index 30cc5c6..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-heat_template_version: 2014-10-16
-
-description: >
-  Controller Config for Controller.
-
-parameters:
-  # unused here but is a placeholder for other compute-config templates
-  # which may choose to create in-templates resources that require controller
-  controller_id:
-    type: string
-    hidden: true
-
-resources:
-
-  ControllerConfigImpl:
-    type: OS::Heat::StructuredConfig
-    properties:
-      group: os-apply-config
-      config:
-        admin-password: {get_input: admin_password}
-        admin-token: {get_input: admin_token}
-        bootstack:
-          public_interface_ip: {get_input: neutron_public_interface_ip}
-        bootstrap_host:
-          nodeid: {get_input: bootstack_nodeid}
-        cinder:
-          db: {get_input: cinder_dsn}
-          debug: {get_input: debug}
-          volume_size_mb: {get_input: cinder_lvm_loop_device_size}
-          service-password: {get_input: cinder_password}
-          iscsi-helper: {get_input: CinderISCSIHelper}
-        controller-address: {get_input: controller_host}
-        corosync:
-          bindnetaddr: {get_input: controller_host}
-          mcastport: 5577
-        pacemaker:
-          stonith_enabled : false
-          recheck_interval : 5
-          quorum_policy : ignore
-        db-password: unset
-        glance:
-          registry:
-            host: {get_input: controller_virtual_ip}
-          backend: swift
-          db: {get_input: glance_dsn}
-          debug: {get_input: debug}
-          host: {get_input: controller_virtual_ip}
-          port: {get_input: glance_port}
-          protocol: {get_input: glance_protocol}
-          service-password: {get_input: glance_password}
-          swift-store-user: service:glance
-          swift-store-key: {get_input: glance_password}
-          notifier-strategy: {get_input: glance_notifier_strategy}
-          log-file: {get_input: glance_log_file}
-        heat:
-          admin_password: {get_input: heat_password}
-          admin_tenant_name: service
-          admin_user: heat
-          auth_encryption_key: unset___________
-          db: {get_input: heat_dsn}
-          debug: {get_input: debug}
-          stack_domain_admin_password: {get_input: heat_stack_domain_admin_password}
-          watch_server_url: {get_input: heat.watch_server_url}
-          metadata_server_url: {get_input: heat.metadata_server_url}
-          waitcondition_server_url: {get_input: heat.waitcondition_server_url}
-        keystone:
-          db: {get_input: keystone_dsn}
-          debug: {get_input: debug}
-          host: {get_input: controller_virtual_ip}
-          ca_certificate: {get_input: keystone_ca_certificate}
-          signing_key: {get_input: keystone_signing_key}
-          signing_certificate: {get_input: keystone_signing_certificate}
-          ssl:
-              certificate: {get_input: keystone_ssl_certificate}
-              certificate_key: {get_input: keystone_ssl_certificate_key}
-        mysql:
-          innodb_buffer_pool_size: {get_input: mysql_innodb_buffer_pool_size}
-          local_bind: true
-          root-password: {get_input: mysql_root_password}
-          cluster_name: {get_input: mysql_cluster_name}
-        neutron:
-          debug: {get_input: debug}
-          flat-networks: {get_input: neutron_flat_networks}
-          host: {get_input: controller_virtual_ip}
-          metadata_proxy_shared_secret: {get_input: neutron_metadata_proxy_shared_secret}
-          agent_mode: {get_input: neutron_agent_mode}
-          router_distributed: {get_input: neutron_router_distributed}
-          mechanism_drivers: {get_input: neutron_mechanism_drivers}
-          allow_automatic_l3agent_failover: {get_input: neutron_allow_l3agent_failover}
-          l3_ha: {get_input: neutron_l3_ha}
-          ovs:
-            enable_tunneling: {get_input: neutron_enable_tunneling}
-            local_ip: {get_input: controller_host}
-            network_vlan_ranges: {get_input: neutron_network_vlan_ranges}
-            bridge_mappings: {get_input: neutron_bridge_mappings}
-            public_interface: {get_input: neutron_public_interface}
-            public_interface_raw_device: {get_input: neutron_public_interface_raw_device}
-            public_interface_route: {get_input: neutron_public_interface_default_route}
-            public_interface_tag: {get_input: neutron_public_interface_tag}
-            physical_bridge: br-ex
-            tenant_network_type: {get_input: neutron_tenant_network_type}
-            tunnel_types: {get_input: neutron_tunnel_types}
-          ovs_db: {get_input: neutron_dsn}
-          service-password: {get_input: neutron_password}
-          dnsmasq-options: {get_input: neutron_dnsmasq_options}
-        ceilometer:
-          db: {get_input: ceilometer_dsn}
-          debug: {get_input: debug}
-          metering_secret: {get_input: ceilometer_metering_secret}
-          service-password: {get_input: ceilometer_password}
-        snmpd:
-          export_MIB: UCD-SNMP-MIB
-          readonly_user_name: {get_input: snmpd_readonly_user_name}
-          readonly_user_password: {get_input: snmpd_readonly_user_password}
-        nova:
-          compute_driver: libvirt.LibvirtDriver
-          db: {get_input: nova_dsn}
-          default_floating_pool:
-            ext-net
-          host: {get_input: controller_virtual_ip}
-          metadata-proxy: true
-          service-password: {get_input: nova_password}
-        rabbit:
-          host: {get_input: controller_virtual_ip}
-          username: {get_input: rabbit_username}
-          password: {get_input: rabbit_password}
-          cookie: {get_input: rabbit_cookie}
-          rabbit_client_use_ssl: {get_input: rabbit_client_use_ssl}
-          rabbit_port: {get_input: rabbit_client_port}
-        ntp:
-          servers:
-              - {server: {get_input: ntp_server}}
-        virtual_interfaces:
-          instances:
-            - vrrp_instance_name: VI_CONTROL
-              virtual_router_id: 51
-              keepalive_interface: {get_input: control_virtual_interface}
-              priority: 101
-              virtual_ips:
-              - ip: {get_input: controller_virtual_ip}
-                interface: {get_input: control_virtual_interface}
-            - vrrp_instance_name: VI_PUBLIC
-              virtual_router_id: 52
-              keepalive_interface: {get_input: public_virtual_interface}
-              priority: 101
-              virtual_ips:
-              - ip: {get_input: public_virtual_ip}
-                interface: {get_input: public_virtual_interface}
-          vrrp_sync_groups:
-            - name: VG1
-              members:
-                - VI_CONTROL
-                - VI_PUBLIC
-        keepalived:
-          keepalive_interface: {get_input: public_virtual_interface}
-          priority: 101
-        virtual_ips:
-            -
-              ip: {get_input: controller_virtual_ip}
-              interface: {get_input: control_virtual_interface}
-            -
-              ip: {get_input: public_virtual_ip}
-              interface: {get_input: public_virtual_interface}
-        haproxy:
-          net_binds:
-            - ip: {get_input: controller_virtual_ip}
-          options:
-            - option httpchk GET /
-          services:
-            - name: keystone_admin
-              port: 35357
-              net_binds: &public_binds
-                - ip: {get_input: controller_virtual_ip}
-                - ip: {get_input: public_virtual_ip}
-            - name: keystone_public
-              port: 5000
-              net_binds: *public_binds
-            - name: horizon
-              port: 80
-              net_binds: *public_binds
-            - name: neutron
-              port: 9696
-              net_binds: *public_binds
-            - name: cinder
-              port: 8776
-              net_binds: *public_binds
-            - name: glance_api
-              port: 9292
-              net_binds: *public_binds
-            - name: glance_registry
-              port: 9191
-              net_binds: *public_binds
-              options: # overwrite options as glace_reg needs auth for http req
-            - name: heat_api
-              port: 8004
-              net_binds: *public_binds
-            - name: heat_cloudwatch
-              port: 8003
-              net_binds: *public_binds
-            - name: heat_cfn
-              port: 8000
-              net_binds: *public_binds
-            - name: mysql
-              port: 3306
-              extra_server_params:
-                - backup
-              options:
-                - timeout client 0
-                - timeout server 0
-            - name: nova_ec2
-              port: 8773
-            - name: nova_osapi
-              port: 8774
-              net_binds: *public_binds
-            - name: nova_metadata
-              port: 8775
-              net_binds: *public_binds
-            - name: nova_novncproxy
-              port: 6080
-              net_binds: *public_binds
-            - name: ceilometer
-              port: 8777
-              net_binds: *public_binds
-              options: # overwrite options as ceil needs auth for http req
-            - name: swift_proxy_server
-              port: 8080
-              net_binds: *public_binds
-              options:
-                - option httpchk GET /info
-            - name: rabbitmq
-              port: 5672
-              options:
-                - timeout client 0
-                - timeout server 0
-                - maxconn 1500
-
-outputs:
-  config_id:
-    description: The ID of the ControllerConfigImpl resource.
-    value:
-      {get_resource: ControllerConfigImpl}
diff --git a/controller-puppet.yaml b/controller-puppet.yaml
new file mode 100644 (file)
index 0000000..970df79
--- /dev/null
@@ -0,0 +1,776 @@
+heat_template_version: 2014-10-16
+
+description: >
+  OpenStack controller node configured by Puppet.
+
+parameters:
+  AdminPassword:
+    default: unset
+    description: The password for the keystone admin account, used for monitoring, querying neutron etc.
+    type: string
+    hidden: true
+  AdminToken:
+    default: unset
+    description: The keystone auth secret.
+    type: string
+    hidden: true
+  CeilometerMeteringSecret:
+    default: unset
+    description: Secret shared by the ceilometer services.
+    type: string
+    hidden: true
+  CeilometerPassword:
+    default: unset
+    description: The password for the ceilometer service account.
+    type: string
+    hidden: true
+  CinderISCSIHelper:
+    default: tgtadm
+    description: The iSCSI helper to use with cinder.
+    type: string
+  CinderLVMLoopDeviceSize:
+    default: 5000
+    description: The size of the loopback file used by the cinder LVM driver.
+    type: number
+  CinderPassword:
+    default: unset
+    description: The password for the cinder service account, used by cinder-api.
+    type: string
+    hidden: true
+  CloudName:
+    default: ''
+    description: The DNS name of this cloud. E.g. ci-overcloud.tripleo.org
+    type: string
+  ControllerExtraConfig:
+    default: {}
+    description: |
+      Controller specific configuration to inject into the cluster. Same
+      structure as ExtraConfig.
+    type: json
+  ControlVirtualInterface:
+    default: 'br-ex'
+    description: Interface where virtual ip will be assigned.
+    type: string
+  Debug:
+    default: ''
+    description: Set to True to enable debugging on all services.
+    type: string
+  ExtraConfig:
+    default: {}
+    description: |
+      Additional configuration to inject into the cluster. The JSON should have
+      the following structure:
+        {"FILEKEY":
+          {"config":
+            [{"section": "SECTIONNAME",
+              "values":
+                [{"option": "OPTIONNAME",
+                  "value": "VALUENAME"
+                 }
+                ]
+             }
+            ]
+          }
+        }
+      For instance:
+        {"nova":
+          {"config":
+            [{"section": "default",
+              "values":
+                [{"option": "compute_manager",
+                  "value": "ironic.nova.compute.manager.ClusterComputeManager"
+                 }
+                ]
+             },
+             {"section": "cells",
+              "values":
+                [{"option": "driver",
+                  "value": "nova.cells.rpc_driver.CellsRPCDriver"
+                 }
+                ]
+             }
+            ]
+          }
+        }
+    type: json
+  Flavor:
+    description: Flavor for control nodes to request when deploying.
+    type: string
+    constraints:
+      - custom_constraint: nova.flavor
+  GlanceNotifierStrategy:
+    description: Strategy to use for Glance notification queue
+    type: string
+    default: noop
+  GlanceLogFile:
+    description: The filepath of the file to use for logging messages from Glance.
+    type: string
+    default: ''
+  GlancePassword:
+    default: unset
+    description: The password for the glance service account, used by the glance services.
+    type: string
+    hidden: true
+  GlancePort:
+    default: "9292"
+    description: Glance port.
+    type: string
+  GlanceProtocol:
+    default: http
+    description: Protocol to use when connecting to glance, set to https for SSL.
+    type: string
+  HeatPassword:
+    default: unset
+    description: The password for the Heat service account, used by the Heat services.
+    type: string
+    hidden: true
+  HeatStackDomainAdminPassword:
+    description: Password for heat_domain_admin user.
+    type: string
+    default: ''
+    hidden: true
+  Image:
+    type: string
+    default: overcloud-control
+    constraints:
+      - custom_constraint: glance.image
+  ImageUpdatePolicy:
+    default: 'REBUILD_PRESERVE_EPHEMERAL'
+    description: What policy to use when reconstructing instances. REBUILD for rebuilds, REBUILD_PRESERVE_EPHEMERAL to preserve /mnt.
+    type: string
+  KeyName:
+    default: default
+    description: Name of an existing EC2 KeyPair to enable SSH access to the instances
+    type: string
+    constraints:
+      - custom_constraint: nova.keypair
+  KeystoneCACertificate:
+    default: ''
+    description: Keystone self-signed certificate authority certificate.
+    type: string
+  KeystoneSigningCertificate:
+    default: ''
+    description: Keystone certificate for verifying token validity.
+    type: string
+  KeystoneSigningKey:
+    default: ''
+    description: Keystone key for signing tokens.
+    type: string
+    hidden: true
+  KeystoneSSLCertificate:
+    default: ''
+    description: Keystone certificate for verifying token validity.
+    type: string
+  KeystoneSSLCertificateKey:
+    default: ''
+    description: Keystone key for signing tokens.
+    type: string
+    hidden: true
+  MysqlClusterUniquePart:
+    description: A unique identifier of the MySQL cluster the controller is in.
+    type: string
+    default: 'unset'  # Has to be here because of the ignored empty value bug
+    # Drop the validation: https://bugs.launchpad.net/tripleo/+bug/1405446
+    # constraints:
+    # - length: {min: 4, max: 10}
+  MysqlInnodbBufferPoolSize:
+    description: >
+        Specifies the size of the buffer pool in megabytes. Setting to
+        zero should be interpreted as "no value" and will defer to the
+        lower level default.
+    type: number
+    default: 0
+  MysqlRootPassword:
+    type: string
+    hidden: true
+    default: ''  # Has to be here because of the ignored empty value bug
+  NeutronBridgeMappings:
+    description: >
+      The OVS logical->physical bridge mappings to use. See the Neutron
+      documentation for details. Defaults to mapping br-ex - the external
+      bridge on hosts - to a physical name 'datacentre' which can be used
+      to create provider networks (and we use this for the default floating
+      network) - if changing this either use different post-install network
+      scripts or be sure to keep 'datacentre' as a mapping network name.
+    type: string
+    default: ""
+  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 gre tunnel overhead.
+    type: string
+  NeutronAgentMode:
+    default: 'dvr_snat'
+    description: Agent mode for the neutron-l3-agent on the controller hosts
+    type: string
+  NeutronL3HA: #FIXME this isn't wired in
+    default: 'False'
+    description: Whether to enable l3-agent HA
+    type: string
+  NeutronDVR:
+    default: 'False'
+    description: Whether to configure Neutron Distributed Virtual Routers
+    type: string
+  NeutronMetadataProxySharedSecret:
+    default: 'unset'
+    description: Shared secret to prevent spoofing
+    type: string
+  NeutronMechanismDrivers:
+    default: 'openvswitch'
+    description: |
+        The mechanism drivers for the Neutron tenant network. To specify multiple
+        values, use a comma separated string, like so: 'openvswitch,l2_population'
+    type: string
+  NeutronAllowL3AgentFailover:
+    default: 'True'
+    description: Allow automatic l3-agent failover
+    type: string
+  NeutronEnableTunnelling:
+    type: string
+    default: "True"
+  NeutronFlatNetworks:
+    type: string
+    default: ''
+    description: If set, flat networks to configure in neutron plugins.
+  NeutronNetworkType:
+    default: 'gre'
+    description: The tenant network type for Neutron, either gre or vxlan.
+    type: string
+  NeutronNetworkVLANRanges:
+    default: 'datacentre'
+    description: >
+      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
+  NeutronPassword:
+    default: unset
+    description: The password for the neutron service account, used by neutron agents.
+    type: string
+    hidden: true
+  NeutronPublicInterface:
+    default: nic1
+    description: What interface to bridge onto br-ex for network nodes.
+    type: string
+  NeutronPublicInterfaceTag:
+    default: ''
+    description: >
+      VLAN tag for creating a public VLAN. The tag will be used to
+      create an access port on the exterior bridge for each control plane node,
+      and that port will be given the IP address returned by neutron from the
+      public network. Set CONTROLEXTRA=overcloud-vlan-port.yaml when compiling
+      overcloud.yaml to include the deployment of VLAN ports to the control
+      plane.
+    type: string
+  NeutronPublicInterfaceDefaultRoute:
+    default: ''
+    description: A custom default route for the NeutronPublicInterface.
+    type: string
+  NeutronPublicInterfaceIP:
+    default: ''
+    description: A custom IP address to put onto the NeutronPublicInterface.
+    type: string
+  NeutronPublicInterfaceRawDevice:
+    default: ''
+    description: If set, the public interface is a vlan with this device as the raw device.
+    type: string
+  NeutronTunnelTypes:
+    default: 'gre'
+    description: |
+        The tunnel types for the Neutron tenant network. To specify multiple
+        values, use a comma separated string, like so: 'gre,vxlan'
+    type: string
+  NovaPassword:
+    default: unset
+    description: The password for the nova service account, used by nova-api.
+    type: string
+    hidden: true
+  NtpServer:
+    type: string
+    default: ''
+  PublicVirtualInterface:
+    default: 'br-ex'
+    description: >
+        Specifies the interface where the public-facing virtual ip will be assigned.
+        This should be int_public when a VLAN is being used.
+    type: string
+  PublicVirtualIP:
+    type: string
+    default: ''  # Has to be here because of the ignored empty value bug
+  RabbitCookie:
+    type: string
+    default: ''  # Has to be here because of the ignored empty value bug
+    hidden: true
+  RabbitPassword:
+    default: guest
+    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
+  SnmpdReadonlyUserName:
+    default: ro_snmp_user
+    description: The user name for SNMPd with readonly rights running on all Overcloud nodes
+    type: string
+  SnmpdReadonlyUserPassword:
+    default: unset
+    description: The user password for SNMPd with readonly rights running on all Overcloud nodes
+    type: string
+    hidden: true
+  SSLCACertificate:
+    default: ''
+    description: If set, the contents of an SSL certificate authority file.
+    type: string
+  SSLCertificate:
+    default: ''
+    description: If set, the contents of an SSL certificate .crt file for encrypting SSL endpoints.
+    type: string
+    hidden: true
+  SSLKey:
+    default: ''
+    description: If set, the contents of an SSL certificate .key file for encrypting SSL endpoints.
+    type: string
+    hidden: true
+  SwiftHashSuffix:
+    default: unset
+    description: A random string to be used as a salt when hashing to determine mappings
+      in the ring.
+    hidden: true
+    type: string
+  SwiftMountCheck:
+    default: 'false'
+    description: Value of mount_check in Swift account/container/object -server.conf
+    type: boolean
+  SwiftMinPartHours:
+    type: number
+    default: 1
+    description: The minimum time (in hours) before a partition in a ring can be moved following a rebalance.
+  SwiftPartPower:
+    default: 10
+    description: Partition Power to use when building Swift rings
+    type: number
+  SwiftPassword:
+    default: unset
+    description: The password for the swift service account, used by the swift proxy
+      services.
+    hidden: true
+    type: string
+  SwiftReplicas:
+    type: number
+    default: 1
+    description: How many replicas to use in the swift rings.
+  VirtualIP:
+    type: string
+    default: ''  # Has to be here because of the ignored empty value bug
+
+
+resources:
+
+  Controller:
+    type: OS::Nova::Server
+    properties:
+      image: {get_param: Image}
+      image_update_policy: {get_param: ImageUpdatePolicy}
+      flavor: {get_param: Flavor}
+      key_name: {get_param: KeyName}
+      networks:
+        - network: ctlplane
+      user_data_format: SOFTWARE_CONFIG
+
+  NetworkConfig:
+    type: OS::TripleO::Net::SoftwareConfig
+
+  NetworkDeployment:
+    type: OS::TripleO::SoftwareDeployment
+    properties:
+      signal_transport: NO_SIGNAL
+      config: {get_attr: [NetworkConfig, config_id]}
+      server: {get_resource: Controller}
+      input_values:
+        bridge_name: br-ex
+        interface_name: {get_param: NeutronPublicInterface}
+
+  ControllerDeployment:
+    type: OS::TripleO::SoftwareDeployment
+    properties:
+      signal_transport: NO_SIGNAL
+      config: {get_resource: ControllerConfig}
+      server: {get_resource: Controller}
+      input_values:
+        bootstack_nodeid: {get_attr: [Controller, name]}
+        controller_host: {get_attr: [Controller, networks, ctlplane, 0]}
+        controller_virtual_ip: {get_param: VirtualIP}
+        neutron_enable_tunneling: {get_param: NeutronEnableTunnelling}
+        heat.watch_server_url:
+          list_join:
+            - ''
+            - - 'http://'
+              - {get_param: VirtualIP}
+              - ':8003'
+        heat.metadata_server_url:
+          list_join:
+            - ''
+            - - 'http://'
+              - {get_param: VirtualIP}
+              - ':8000'
+        heat.waitcondition_server_url:
+          list_join:
+            - ''
+            - - 'http://'
+              - {get_param: VirtualIP}
+              - ':8000/v1/waitcondition'
+        admin_password: {get_param: AdminPassword}
+        admin_token: {get_param: AdminToken}
+        neutron_public_interface_ip: {get_param: NeutronPublicInterfaceIP}
+        debug: {get_param: Debug}
+        cinder_lvm_loop_device_size: {get_param: CinderLVMLoopDeviceSize}
+        cinder_password: {get_param: CinderPassword}
+        cinder_iscsi_helper: {get_param: CinderISCSIHelper}
+        cinder_dsn:
+          list_join:
+            - ''
+            - - 'mysql://cinder:unset@'
+              - {get_param: VirtualIP}
+              - '/cinder'
+        glance_port: {get_param: GlancePort}
+        glance_protocol: {get_param: GlanceProtocol}
+        glance_password: {get_param: GlancePassword}
+        glance_notifier_strategy: {get_param: GlanceNotifierStrategy}
+        glance_log_file: {get_param: GlanceLogFile}
+        glance_dsn:
+          list_join:
+            - ''
+            - - 'mysql://glance:unset@'
+              - {get_param: VirtualIP}
+              - '/glance'
+        heat_password: {get_param: HeatPassword}
+        heat_stack_domain_admin_password: {get_param: HeatStackDomainAdminPassword}
+        heat_dsn:
+          list_join:
+            - ''
+            - - 'mysql://heat:unset@'
+              - {get_param: VirtualIP}
+              - '/heat'
+        keystone_ca_certificate: {get_param: KeystoneCACertificate}
+        keystone_signing_key: {get_param: KeystoneSigningKey}
+        keystone_signing_certificate: {get_param: KeystoneSigningCertificate}
+        keystone_ssl_certificate: {get_param: KeystoneSSLCertificate}
+        keystone_ssl_certificate_key: {get_param: KeystoneSSLCertificateKey}
+        keystone_dsn:
+          list_join:
+            - ''
+            - - 'mysql://keystone:unset@'
+              - {get_param: VirtualIP}
+              - '/keystone'
+        mysql_innodb_buffer_pool_size: {get_param: MysqlInnodbBufferPoolSize}
+        mysql_root_password: {get_param: MysqlRootPassword}
+        mysql_cluster_name:
+          str_replace:
+            template: tripleo-CLUSTER
+            params:
+              CLUSTER: {get_param: MysqlClusterUniquePart}
+        neutron_flat_networks: {get_param: NeutronFlatNetworks}
+        neutron_metadata_proxy_shared_secret: {get_param: NeutronMetadataProxySharedSecret}
+        neutron_agent_mode: {get_param: NeutronAgentMode}
+        neutron_router_distributed: {get_param: NeutronDVR}
+        neutron_mechanism_drivers: {get_param: NeutronMechanismDrivers}
+        neutron_allow_l3agent_failover: {get_param: NeutronAllowL3AgentFailover}
+        neutron_network_vlan_ranges: {get_param: NeutronNetworkVLANRanges}
+        neutron_bridge_mappings: {get_param: NeutronBridgeMappings}
+        neutron_public_interface: {get_param: NeutronPublicInterface}
+        neutron_public_interface_raw_device: {get_param: NeutronPublicInterfaceRawDevice}
+        neutron_public_interface_default_route: {get_param: NeutronPublicInterfaceDefaultRoute}
+        neutron_public_interface_tag: {get_param: NeutronPublicInterfaceTag}
+        neutron_tenant_network_type: {get_param: NeutronNetworkType}
+        neutron_tunnel_types: {get_param: NeutronTunnelTypes}
+        neutron_password: {get_param: NeutronPassword}
+        neutron_dnsmasq_options: {get_param: NeutronDnsmasqOptions}
+        neutron_dsn:
+          list_join:
+            - ''
+            - - 'mysql://neutron:unset@'
+              - {get_param: VirtualIP}
+              - '/ovs_neutron?charset=utf8'
+        ceilometer_metering_secret: {get_param: CeilometerMeteringSecret}
+        ceilometer_password: {get_param: CeilometerPassword}
+        ceilometer_dsn:
+          list_join:
+            - ''
+            - - 'mysql://ceilometer:unset@'
+              - {get_param: VirtualIP}
+              - '/ceilometer'
+        snmpd_readonly_user_name: {get_param: SnmpdReadonlyUserName}
+        snmpd_readonly_user_password: {get_param: SnmpdReadonlyUserPassword}
+        nova_password: {get_param: NovaPassword}
+        nova_dsn:
+          list_join:
+            - ''
+            - - 'mysql://nova:unset@'
+              - {get_param: VirtualIP}
+              - '/nova'
+        rabbit_username: {get_param: RabbitUserName}
+        rabbit_password: {get_param: RabbitPassword}
+        rabbit_cookie: {get_param: RabbitCookie}
+        rabbit_client_use_ssl: {get_param: RabbitClientUseSSL}
+        rabbit_client_port: {get_param: RabbitClientPort}
+        ntp_server: {get_param: NtpServer}
+        control_virtual_interface: {get_param: ControlVirtualInterface}
+        public_virtual_interface: {get_param: PublicVirtualInterface}
+        public_virtual_ip: {get_param: PublicVirtualIP}
+
+
+  # Map heat metadata into hiera datafiles
+  ControllerConfig:
+    type: OS::Heat::StructuredConfig
+    properties:
+      group: os-apply-config
+      config:
+        hiera:
+          hierarchy:
+            - heat_config_%{::deploy_config_name}
+            - controller
+            - common
+          datafiles:
+            common:
+              raw_data: {get_file: puppet/hieradata/common.yaml}
+            controller:
+              raw_data: {get_file: puppet/hieradata/controller.yaml}
+              oac_data: # data we map in from other OAC configurations
+                bootstrap_nodeid: bootstrap_host.bootstrap_nodeid
+              mapped_data: # data supplied directly to this deployment configuration, etc
+                debug: {get_input: debug}
+                bootstack_nodeid: {get_input: bootstack_nodeid}
+                controller_host: {get_input: controller_host} #local-ipv4
+                # Cinder
+                cinder_lvm_loop_device_size: {get_input: cinder_lvm_loop_device_size}
+                cinder::volume::iscsi::iscsi_helper: {get_input: cinder_iscsi_helper}
+                cinder::volume::iscsi::iscsi_ip_address: {get_input: controller_host}
+                cinder::database_connection: {get_input: cinder_dsn}
+                cinder::api::keystone_password: {get_input: cinder_password}
+                cinder::api::keystone_auth_host: {get_input: controller_virtual_ip}
+                cinder::api::bind_host: {get_input: controller_host}
+                cinder::rabbit_userid: {get_input: rabbit_username}
+                cinder::rabbit_password: {get_input: rabbit_password}
+                #cinder::debug: {get_input: debug}
+                # Glance
+                glance::api::bind_port: {get_input: glance_port}
+                glance::api::bind_host: {get_input: controller_host}
+                glance::api::auth_host: {get_input: controller_virtual_ip}
+                glance::api::registry_host: {get_input: controller_host}
+                glance::api::keystone_password: {get_input: glance_password}
+                # used to construct glance_api_servers
+                glance_port: {get_input: glance_port}
+                glance_protocol: {get_input: glance_protocol}
+                glance_notifier_strategy: {get_input: glance_notifier_strategy}
+                glance_log_file: {get_input: glance_log_file}
+                glance_log_file: {get_input: glance_log_file}
+                glance::api::database_connection: {get_input: glance_dsn}
+                glance::registry::keystone_password: {get_input: glance_password}
+                glance::registry::database_connection: {get_input: glance_dsn}
+                glance::registry::bind_host: {get_input: controller_host}
+                glance::registry::auth_host: {get_input: controller_virtual_ip}
+                # Heat
+                heat_password: {get_input: heat_password}
+                heat_stack_domain_admin_password: {get_input: heat_stack_domain_admin_password}
+                heat_dsn: {get_input: heat_dsn}
+                heat.watch_server_url: {get_input: heat.watch_server_url}
+                heat.metadata_server_url: {get_input: heat.metadata_server_url}
+                heat.waitcondition_server_url: {get_input: heat.waitcondition_server_url}
+                # Keystone
+                keystone::admin_token: {get_input: admin_token}
+                keystone_ca_certificate: {get_input: keystone_ca_certificate}
+                keystone_signing_key: {get_input: keystone_signing_key}
+                keystone_signing_certificate: {get_input: keystone_signing_certificate}
+                keystone_ssl_certificate: {get_input: keystone_ssl_certificate}
+                keystone_ssl_certificate_key: {get_input: keystone_ssl_certificate_key}
+                keystone::database_connection: {get_input: keystone_dsn}
+                keystone::public_bind_host: {get_input: controller_host}
+                keystone::admin_bind_host: {get_input: controller_host}
+                #keystone::debug: {get_input: debug}
+                # MySQL
+                admin_password: {get_input: admin_password}
+                mysql_innodb_buffer_pool_size: {get_input: mysql_innodb_buffer_pool_size}
+                mysql_root_password: {get_input: mysql_root_password}
+                mysql_cluster_name: {get_input: mysql_cluster_name}
+                # Neutron
+                neutron::bind_host: {get_input: controller_host}
+                neutron::rabbit_password: {get_input: rabbit_password}
+                neutron::rabbit_user: {get_input: rabbit_user}
+                #neutron::debug: {get_input: debug}
+                neutron::server::auth_host: {get_input: controller_virtual_ip}
+                neutron::server::database_connection: {get_input: neutron_dsn}
+                neutron::agents::ml2::ovs::enable_tunneling: {get_input: neutron_enable_tunneling}
+                neutron::agents::ml2::ovs::local_ip: {get_input: controller_host}
+                neutron_flat_networks: {get_input: neutron_flat_networks}
+                neutron::agents::metadata::shared_secret: {get_input: neutron_metadata_proxy_shared_secret}
+                neutron_agent_mode: {get_input: neutron_agent_mode}
+                neutron_router_distributed: {get_input: neutron_router_distributed}
+                neutron_mechanism_drivers: {get_input: neutron_mechanism_drivers}
+                neutron_allow_l3agent_failover: {get_input: neutron_allow_l3agent_failover}
+                neutron::plugins::ml2::network_vlan_ranges: {get_input: neutron_network_vlan_ranges}
+                neutron_bridge_mappings: {get_input: neutron_bridge_mappings}
+                neutron_public_interface: {get_input: neutron_public_interface}
+                neutron_public_interface_raw_device: {get_input: neutron_public_interface_raw_device}
+                neutron_public_interface_default_route: {get_input: neutron_public_interface_default_route}
+                neutron_public_interface_tag: {get_input: neutron_public_interface_tag}
+                neutron_tenant_network_type: {get_input: neutron_tenant_network_type}
+                neutron_tunnel_types: {get_input: neutron_tunnel_types}
+                neutron::server::auth_password: {get_input: neutron_password}
+                neutron::agents::metadata::auth_password: {get_input: neutron_password}
+                neutron_dnsmasq_options: {get_input: neutron_dnsmasq_options}
+                neutron_dsn: {get_input: neutron_dsn}
+                # Ceilometer
+                ceilometer_metering_secret: {get_input: ceilometer_metering_secret}
+                ceilometer_password: {get_input: ceilometer_password}
+                ceilometer_dsn: {get_input: ceilometer_dsn}
+                snmpd_readonly_user_name: {get_input: snmpd_readonly_user_name}
+                snmpd_readonly_user_password: {get_input: snmpd_readonly_user_password}
+                # Nova
+                nova::rabbit_userid: {get_input: rabbit_username}
+                nova::rabbit_password: {get_input: rabbit_password}
+                nova::api::auth_host: {get_input: controller_virtual_ip}
+                nova::api::api_bind_address: {get_input: controller_host}
+                nova::api::metadata_listen: {get_input: controller_host}
+                nova::api::admin_password: {get_input: nova_password}
+                nova::database_connection: {get_input: nova_dsn}
+                nova::api::neutron_metadata_proxy_shared_secret: {get_input: neutron_metadata_proxy_shared_secret}
+                # Rabbit
+                rabbit_username: {get_input: rabbit_username}
+                rabbit_password: {get_input: rabbit_password}
+                rabbit_cookie: {get_input: rabbit_cookie}
+                rabbit_client_use_ssl: {get_input: rabbit_client_use_ssl}
+                rabbit_client_port: {get_input: rabbit_client_port}
+                # Misc
+                neutron_public_interface_ip: {get_input: neutron_public_interface_ip}
+                ntp_server: {get_input: ntp_server}
+                control_virtual_interface: {get_input: control_virtual_interface}
+                controller_virtual_ip: {get_input: controller_virtual_ip}
+                public_virtual_interface: {get_input: public_virtual_interface}
+                public_virtual_ip: {get_input: public_virtual_ip}
+                # Load Balancer (composition class parameters)
+                tripleo::loadbalancer::keystone_admin: true
+                tripleo::loadbalancer::keystone_public: true
+                tripleo::loadbalancer::neutron: true
+                tripleo::loadbalancer::cinder: true
+                tripleo::loadbalancer::glance_api: true
+                tripleo::loadbalancer::glance_registry: true
+                tripleo::loadbalancer::nova_ec2: true
+                tripleo::loadbalancer::nova_osapi: true
+                tripleo::loadbalancer::nova_metadata: true
+                tripleo::loadbalancer::nova_novncproxy: true
+                tripleo::loadbalancer::mysql: true
+                tripleo::loadbalancer::rabbitmq: true
+
+  # NOTE(dprince): this example uses a composition class
+  # on the puppet side (loadbalancer.pp). This seemed like the
+  # cleanest way to encapulate the puppet resources definitions
+  # for HAProxy and Keepalived.
+  ControllerLoadbalancerPuppetConfig:
+    type: OS::Heat::SoftwareConfig
+    properties:
+      group: puppet
+      options:
+        enable_hiera: True
+        enable_facter: False
+      inputs:
+      outputs:
+      - name: result
+      config:
+        get_file: puppet/loadbalancer.pp
+
+  ControllerLoadbalancerPuppetDeployment:
+    type: OS::Heat::StructuredDeployment
+    properties:
+      name: puppet_1
+      server: {get_resource: Controller}
+      config: {get_resource: ControllerLoadbalancerPuppetConfig}
+
+  ControllerPuppetConfig:
+    type: OS::Heat::SoftwareConfig
+    properties:
+      group: puppet
+      options:
+        enable_hiera: True
+        enable_facter: False
+      inputs:
+      - name: step
+      outputs:
+      - name: result
+      config:
+        get_file: puppet/overcloud_controller.pp
+
+  # Step through a series of two more Puppet runs using the same manifest.
+  # NOTE(dprince): Heat breakpoints would make for a really cool way to step
+  # through breakpoints in a controlled manner across the entire cluster
+  ControllerPuppetDeploymentTwo:
+    type: OS::Heat::StructuredDeployment
+    properties:
+      name: puppet_2
+      server: {get_resource: Controller}
+      config: {get_resource: ControllerPuppetConfig}
+      input_values:
+        step: 1
+      actions: ['CREATE'] # no need for two passes on an UPDATE
+
+  ControllerPuppetDeploymentThree:
+    type: OS::Heat::StructuredDeployment
+    properties:
+      name: puppet_3
+      server: {get_resource: Controller}
+      config: {get_resource: ControllerPuppetConfig}
+      input_values:
+        step: 2
+
+outputs:
+  ip_address:
+    description: IP address of the server in the ctlplane network
+    value: {get_attr: [Controller, networks, ctlplane, 0]}
+  hostname:
+    description: Hostname of the server
+    value: {get_attr: [Controller, name]}
+  corosync_node:
+    description: >
+      Node object in the format {ip: ..., name: ...} format that the corosync
+      element expects
+    value:
+      ip: {get_attr: [Controller, networks, ctlplane, 0]}
+      name: {get_attr: [Controller, name]}
+  hosts_entry:
+    description: >
+      Server's IP address and hostname in the /etc/hosts format
+    value:
+      str_replace:
+        template: IP HOST HOST.novalocal CLOUDNAME
+        params:
+          IP: {get_attr: [Controller, networks, ctlplane, 0]}
+          HOST: {get_attr: [Controller, name]}
+          CLOUDNAME: {get_param: CloudName}
+  nova_server_resource:
+    description: Heat resource handle for the Nova compute server
+    value:
+      {get_resource: Controller}
+  swift_device:
+    description: Swift device formatted for swift-ring-builder
+    value:
+      str_replace:
+        template: 'r1z1-IP:%PORT%/d1'
+        params:
+          IP: {get_attr: [Controller, networks, ctlplane, 0]}
+  swift_proxy_memcache:
+    description: Swift proxy-memcache value
+    value:
+      str_replace:
+        template: "IP:11211"
+        params:
+          IP: {get_attr: [Controller, networks, ctlplane, 0]}
index 9b7e3e0..4ab62d5 100644 (file)
@@ -401,12 +401,6 @@ resources:
         bridge_name: br-ex
         interface_name: {get_param: NeutronPublicInterface}
 
-  ControllerConfig:
-    type: OS::TripleO::Controller::SoftwareConfig
-    properties:
-      # allow configs to create sub-resources attached to the controller
-      controller_id: {get_resource: Controller}
-
   ControllerPassthroughConfig:
     type: OS::Heat::StructuredConfig
     properties:
@@ -419,11 +413,233 @@ resources:
       group: os-apply-config
       config: {get_input: passthrough_config_specific}
 
+  ControllerConfig:
+    type: OS::Heat::StructuredConfig
+    properties:
+      group: os-apply-config
+      config:
+        admin-password: {get_input: admin_password}
+        admin-token: {get_input: admin_token}
+        bootstack:
+          public_interface_ip: {get_input: neutron_public_interface_ip}
+        bootstrap_host:
+          nodeid: {get_input: bootstack_nodeid}
+        cinder:
+          db: {get_input: cinder_dsn}
+          debug: {get_input: debug}
+          volume_size_mb: {get_input: cinder_lvm_loop_device_size}
+          service-password: {get_input: cinder_password}
+          iscsi-helper: {get_input: CinderISCSIHelper}
+        controller-address: {get_input: controller_host}
+        corosync:
+          bindnetaddr: {get_input: controller_host}
+          mcastport: 5577
+        pacemaker:
+          stonith_enabled : false
+          recheck_interval : 5
+          quorum_policy : ignore
+        db-password: unset
+        glance:
+          registry:
+            host: {get_input: controller_virtual_ip}
+          backend: swift
+          db: {get_input: glance_dsn}
+          debug: {get_input: debug}
+          host: {get_input: controller_virtual_ip}
+          port: {get_input: glance_port}
+          protocol: {get_input: glance_protocol}
+          service-password: {get_input: glance_password}
+          swift-store-user: service:glance
+          swift-store-key: {get_input: glance_password}
+          notifier-strategy: {get_input: glance_notifier_strategy}
+          log-file: {get_input: glance_log_file}
+        heat:
+          admin_password: {get_input: heat_password}
+          admin_tenant_name: service
+          admin_user: heat
+          auth_encryption_key: unset___________
+          db: {get_input: heat_dsn}
+          debug: {get_input: debug}
+          stack_domain_admin_password: {get_input: heat_stack_domain_admin_password}
+          watch_server_url: {get_input: heat.watch_server_url}
+          metadata_server_url: {get_input: heat.metadata_server_url}
+          waitcondition_server_url: {get_input: heat.waitcondition_server_url}
+        keystone:
+          db: {get_input: keystone_dsn}
+          debug: {get_input: debug}
+          host: {get_input: controller_virtual_ip}
+          ca_certificate: {get_input: keystone_ca_certificate}
+          signing_key: {get_input: keystone_signing_key}
+          signing_certificate: {get_input: keystone_signing_certificate}
+          ssl:
+              certificate: {get_input: keystone_ssl_certificate}
+              certificate_key: {get_input: keystone_ssl_certificate_key}
+        mysql:
+          innodb_buffer_pool_size: {get_input: mysql_innodb_buffer_pool_size}
+          local_bind: true
+          root-password: {get_input: mysql_root_password}
+          cluster_name: {get_input: mysql_cluster_name}
+        neutron:
+          debug: {get_input: debug}
+          flat-networks: {get_input: neutron_flat_networks}
+          host: {get_input: controller_virtual_ip}
+          metadata_proxy_shared_secret: {get_input: neutron_metadata_proxy_shared_secret}
+          agent_mode: {get_input: neutron_agent_mode}
+          router_distributed: {get_input: neutron_router_distributed}
+          mechanism_drivers: {get_input: neutron_mechanism_drivers}
+          allow_automatic_l3agent_failover: {get_input: neutron_allow_l3agent_failover}
+          l3_ha: {get_input: neutron_l3_ha}
+          ovs:
+            enable_tunneling: {get_input: neutron_enable_tunneling}
+            local_ip: {get_input: controller_host}
+            network_vlan_ranges: {get_input: neutron_network_vlan_ranges}
+            bridge_mappings: {get_input: neutron_bridge_mappings}
+            public_interface: {get_input: neutron_public_interface}
+            public_interface_raw_device: {get_input: neutron_public_interface_raw_device}
+            public_interface_route: {get_input: neutron_public_interface_default_route}
+            public_interface_tag: {get_input: neutron_public_interface_tag}
+            physical_bridge: br-ex
+            tenant_network_type: {get_input: neutron_tenant_network_type}
+            tunnel_types: {get_input: neutron_tunnel_types}
+          ovs_db: {get_input: neutron_dsn}
+          service-password: {get_input: neutron_password}
+          dnsmasq-options: {get_input: neutron_dnsmasq_options}
+        ceilometer:
+          db: {get_input: ceilometer_dsn}
+          debug: {get_input: debug}
+          metering_secret: {get_input: ceilometer_metering_secret}
+          service-password: {get_input: ceilometer_password}
+        snmpd:
+          export_MIB: UCD-SNMP-MIB
+          readonly_user_name: {get_input: snmpd_readonly_user_name}
+          readonly_user_password: {get_input: snmpd_readonly_user_password}
+        nova:
+          compute_driver: libvirt.LibvirtDriver
+          db: {get_input: nova_dsn}
+          default_floating_pool:
+            ext-net
+          host: {get_input: controller_virtual_ip}
+          metadata-proxy: true
+          service-password: {get_input: nova_password}
+        rabbit:
+          host: {get_input: controller_virtual_ip}
+          username: {get_input: rabbit_username}
+          password: {get_input: rabbit_password}
+          cookie: {get_input: rabbit_cookie}
+          rabbit_client_use_ssl: {get_input: rabbit_client_use_ssl}
+          rabbit_port: {get_input: rabbit_client_port}
+        ntp:
+          servers:
+              - {server: {get_input: ntp_server}}
+        virtual_interfaces:
+          instances:
+            - vrrp_instance_name: VI_CONTROL
+              virtual_router_id: 51
+              keepalive_interface: {get_input: control_virtual_interface}
+              priority: 101
+              virtual_ips:
+              - ip: {get_input: controller_virtual_ip}
+                interface: {get_input: control_virtual_interface}
+            - vrrp_instance_name: VI_PUBLIC
+              virtual_router_id: 52
+              keepalive_interface: {get_input: public_virtual_interface}
+              priority: 101
+              virtual_ips:
+              - ip: {get_input: public_virtual_ip}
+                interface: {get_input: public_virtual_interface}
+          vrrp_sync_groups:
+            - name: VG1
+              members:
+                - VI_CONTROL
+                - VI_PUBLIC
+        keepalived:
+          keepalive_interface: {get_input: public_virtual_interface}
+          priority: 101
+        virtual_ips:
+            -
+              ip: {get_input: controller_virtual_ip}
+              interface: {get_input: control_virtual_interface}
+            -
+              ip: {get_input: public_virtual_ip}
+              interface: {get_input: public_virtual_interface}
+        haproxy:
+          net_binds:
+            - ip: {get_input: controller_virtual_ip}
+          options:
+            - option httpchk GET /
+          services:
+            - name: keystone_admin
+              port: 35357
+              net_binds: &public_binds
+                - ip: {get_input: controller_virtual_ip}
+                - ip: {get_input: public_virtual_ip}
+            - name: keystone_public
+              port: 5000
+              net_binds: *public_binds
+            - name: horizon
+              port: 80
+              net_binds: *public_binds
+            - name: neutron
+              port: 9696
+              net_binds: *public_binds
+            - name: cinder
+              port: 8776
+              net_binds: *public_binds
+            - name: glance_api
+              port: 9292
+              net_binds: *public_binds
+            - name: glance_registry
+              port: 9191
+              net_binds: *public_binds
+              options: # overwrite options as glace_reg needs auth for http req
+            - name: heat_api
+              port: 8004
+              net_binds: *public_binds
+            - name: heat_cloudwatch
+              port: 8003
+              net_binds: *public_binds
+            - name: heat_cfn
+              port: 8000
+              net_binds: *public_binds
+            - name: mysql
+              port: 3306
+              extra_server_params:
+                - backup
+              options:
+                - timeout client 0
+                - timeout server 0
+            - name: nova_ec2
+              port: 8773
+            - name: nova_osapi
+              port: 8774
+              net_binds: *public_binds
+            - name: nova_metadata
+              port: 8775
+              net_binds: *public_binds
+            - name: nova_novncproxy
+              port: 6080
+              net_binds: *public_binds
+            - name: ceilometer
+              port: 8777
+              net_binds: *public_binds
+              options: # overwrite options as ceil needs auth for http req
+            - name: swift_proxy_server
+              port: 8080
+              net_binds: *public_binds
+              options:
+                - option httpchk GET /info
+            - name: rabbitmq
+              port: 5672
+              options:
+                - timeout client 0
+                - timeout server 0
+                - maxconn 1500
+
   ControllerDeployment:
     type: OS::TripleO::SoftwareDeployment
     properties:
       signal_transport: NO_SIGNAL
-      config: {get_attr: [ControllerConfig, config_id]}
+      config: {get_resource: ControllerConfig}
       server: {get_resource: Controller}
       input_values:
         bootstack_nodeid: {get_attr: [Controller, name]}
@@ -504,6 +720,7 @@ resources:
         neutron_router_distributed: {get_param: NeutronDVR}
         neutron_mechanism_drivers: {get_param: NeutronMechanismDrivers}
         neutron_allow_l3agent_failover: {get_param: NeutronAllowL3AgentFailover}
+        neutron_l3_ha: {get_param: NeutronL3HA}
         neutron_network_vlan_ranges: {get_param: NeutronNetworkVLANRanges}
         neutron_bridge_mappings: {get_param: NeutronBridgeMappings}
         neutron_public_interface: {get_param: NeutronPublicInterface}
index 56f3aa2..cb3c7c7 100644 (file)
@@ -3,7 +3,6 @@ resource_registry:
   OS::TripleO::Compute: compute.yaml
   OS::TripleO::Compute::SoftwareConfig: compute-config-puppet.yaml
   OS::TripleO::SoftwareDeployment: OS::Heat::StructuredDeployment
-  OS::TripleO::Controller: controller.yaml
-  OS::TripleO::Controller::SoftwareConfig: controller-config-puppet.yaml
+  OS::TripleO::Controller: controller-puppet.yaml
   OS::TripleO::ObjectStorage: swift-storage.yaml
   OS::TripleO::Net::SoftwareConfig: net-config-bridge.yaml
index 249dee9..03e790d 100644 (file)
@@ -4,6 +4,5 @@ resource_registry:
   OS::TripleO::Compute::SoftwareConfig: compute-config.yaml
   OS::TripleO::SoftwareDeployment: OS::Heat::StructuredDeployment
   OS::TripleO::Controller: controller.yaml
-  OS::TripleO::Controller::SoftwareConfig: controller-config.yaml
   OS::TripleO::ObjectStorage: swift-storage.yaml
   OS::TripleO::Net::SoftwareConfig: net-config-noop.yaml