Compute and controller templates without merge.py
authorTomas Sedovic <tsedovic@redhat.com>
Wed, 6 Aug 2014 11:24:10 +0000 (13:24 +0200)
committerTomas Sedovic <tsedovic@redhat.com>
Mon, 20 Oct 2014 12:12:41 +0000 (14:12 +0200)
This provides three templates: overcloud-without-mergepy.yaml,
compute.yaml and controller.yaml. These can be used in combination with
overcloud-resource-registry.yaml to deploy the overcloud on their own --
without having to do any pre-processing (via merge.py).

To test these you have to add the resource registry environment (in
addition to the existing `-e` option) and use the new overcloud template
in the Heat call in devtest_overcloud.sh (line 374):

    heat $HEAT_OP -e $TRIPLEO_ROOT/overcloud-env.json \
        -e "$TRIPLEO_ROOT/tripleo-heat-templates/overcloud-resource-registry.yaml" \
        -t 360 \
        -f $TRIPLEO_ROOT/tripleo-heat-templates/overcloud-without-mergepy.yaml \
        -P "ExtraConfig=${OVERCLOUD_EXTRA_CONFIG}" \
        $STACKNAME

The existing overcloud Heat environment
($TRIPLE_ROOT/overcloud-env.json) should keep on working.  Scaling is
now being controlled by the `ControllerCount` and `ComputeCount`
template parameters, though.

NOTE: the changes here depend on a fairly recent Heat build (commit
e5f285f6cb from ~7th September, 2014). In other words, this requires
Juno Heat.

Also, passing more than one environment file to Heat requires
python-heatclient version 0.2.11.

Change-Id: I687a00c7dc164ba044f9f2dfca96a02401427855

compute.yaml [new file with mode: 0644]
controller.yaml
overcloud-resource-registry.yaml [new file with mode: 0644]
overcloud-without-mergepy.yaml [new file with mode: 0644]

diff --git a/compute.yaml b/compute.yaml
new file mode 100644 (file)
index 0000000..350b5ec
--- /dev/null
@@ -0,0 +1,401 @@
+heat_template_version: 2014-10-16
+
+description: >
+  OpenStack hypervisor node. Can be wrapped in a ResourceGroup for scaling.
+
+parameters:
+  AdminPassword:
+    default: unset
+    description: The password for the keystone admin account, used for monitoring, querying neutron etc.
+    type: string
+    hidden: true
+  CeilometerComputeAgent:
+    description: Indicates whether the Compute agent is present and expects nova-compute to be configured accordingly
+    type: string
+    default: ''
+    constraints:
+    - allowed_values: ['', Present]
+  CeilometerDSN:
+    type: string
+  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
+  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": "force_config_drive",
+                  "value": "always"
+                 }
+                ]
+             },
+             {"section": "cells",
+              "values":
+                [{"option": "driver",
+                  "value": "nova.cells.rpc_driver.CellsRPCDriver"
+                 }
+                ]
+             }
+            ]
+          }
+        }
+    type: json
+  Flavor:
+    description: Flavor for the nova compute node
+    type: string
+    default: baremetal
+  GlanceHost:
+    type: string
+    default: ''  # Has to be here because of the ignored empty value bug
+  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
+  Image:
+    type: string
+    default: overcloud-compute
+  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:
+    description: Name of an existing EC2 KeyPair to enable SSH access to the instances
+    type: string
+    default: default
+  KeystoneHost:
+    type: string
+    default: ''
+  LiveUpdateComputeImage:
+    type: string
+    description: The image ID for live-updates to the overcloud compute nodes.
+    default: ''
+  LiveUpdateHost:
+    type: string
+    description: The IP address for the undercloud Glance API.
+    default: ''
+  LiveUpdatePassword:
+    type: string
+    default: ''
+    description: The live-update password for the undercloud Glance API.
+    hidden: true
+  LiveUpdateTenantName:
+    type: string
+    description: The live-update tenant name for the undercloud Glance API.
+    default: ''
+  LiveUpdateUserName:
+    type: string
+    description: The live-update username for the undercloud Glance API.
+    default: ''
+  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: ""
+  NeutronDSN:
+    type: string
+  NeutronEnableTunnelling:
+    type: string
+    default: "True"
+  NeutronFlatNetworks:
+    type: string
+    default: ''
+    description: >
+      If set, flat networks to configure in neutron plugins.
+  NeutronHost:
+    type: string
+    default: ''  # Has to be here because of the ignored empty value bug
+  NeutronNetworkType:
+    type: string
+    description: The tenant network type for Neutron, either gre or vxlan.
+    default: 'gre'
+  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
+  NeutronPhysicalBridge:
+    default: ''
+    description: An OVS bridge to create for accessing external networks.
+    type: string
+  NeutronPublicInterface:
+    default: ''
+    description: A port to add to the NeutronPhysicalBridge.
+    type: string
+  NeutronTunnelTypes:
+    type: string
+    description: |
+        The tunnel types for the Neutron tenant network. To specify multiple
+        values, use a comma separated string, like so: 'gre,vxlan'
+    default: 'gre'
+  NovaApiHost:
+    type: string
+    default: ''  # Has to be here because of the ignored empty value bug
+  NovaComputeDriver:
+    type: string
+    default: libvirt.LibvirtDriver
+  NovaComputeExtraConfig:
+    default: {}
+    description: |
+      NovaCompute specific configuration to inject into the cluster. Same
+      structure as ExtraConfig.
+    type: json
+  NovaComputeLibvirtType:
+    type: string
+    default: ''
+  NovaDSN:
+    type: string
+  NovaPassword:
+    default: unset
+    description: The password for the nova service account, used by nova-api.
+    type: string
+    hidden: true
+  NovaPublicIP:
+    type: string
+    default: ''  # Has to be here because of the ignored empty value bug
+  NtpServer:
+    type: string
+    default: ''
+  RabbitHost:
+    type: string
+    default: ''  # Has to be here because of the ignored empty value bug
+  RabbitPassword:
+    default: guest
+    description: The password for RabbitMQ
+    type: string
+    hidden: true
+  RabbitUserName:
+    default: guest
+    description: The username for RabbitMQ
+    type: string
+  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
+
+
+resources:
+
+  NovaCompute:
+    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
+
+  NovaComputeConfig:
+    type: OS::Heat::StructuredConfig
+    properties:
+      group: os-apply-config
+      config:
+        nova:
+          compute_driver: { get_input: nova_compute_driver }
+          compute_libvirt_type: { get_input: nova_compute_libvirt_type }
+          db: {get_input: nova_dsn}
+          debug: {get_param: Debug}
+          host: {get_input: nova_api_host}
+          public_ip: {get_input: nova_public_ip}
+          service-password: {get_input: nova_password}
+        ceilometer:
+          db: {get_input: ceilometer_dsn}
+          debug: {get_param: Debug}
+          metering_secret: {get_input: ceilometer_metering_secret}
+          service-password: {get_input: ceilometer_password}
+          compute_agent: {get_input: ceilometer_compute_agent}
+        snmpd:
+          export_MIB: UCD-SNMP-MIB
+          readonly_user_name: {get_input: snmpd_readonly_user_name}
+          readonly_user_password: {get_input: snmpd_readonly_user_password}
+        glance:
+          debug: {get_param: Debug}
+          host: {get_input: glance_host}
+          port: {get_input: glance_port}
+          protocol: {get_input: glance_protocol}
+        keystone:
+          debug: {get_param: Debug}
+          host: {get_input: keystone_host}
+        neutron:
+          debug: {get_param: Debug}
+          flat-networks: {get_input: neutron_flat_networks}
+          host: {get_input: neutron_host}
+          ovs_db: {get_input: neutron_dsn}
+          ovs:
+            local_ip: {get_input: neutron_local_ip}
+            tenant_network_type: {get_input: neutron_tenant_network_type}
+            tunnel_types: {get_input: neutron_tunnel_types}
+            network_vlan_ranges: {get_input: neutron_network_vlan_ranges}
+            bridge_mappings: {get_input: neutron_bridge_mappings}
+            enable_tunneling: {get_input: neutron_enable_tunneling}
+            physical_bridge: {get_input: neutron_physical_bridge}
+            public_interface: {get_input: neutron_public_interface}
+          service-password: {get_input: neutron_password}
+        admin-password: {get_input: admin_password}
+        rabbit:
+          host: {get_input: rabbit_host}
+          username: {get_input: rabbit_username}
+          password: {get_input: rabbit_password}
+        live-update:
+          host: {get_input: live_update_host}
+          username: {get_input: live_update_username}
+          password: {get_input: live_update_password}
+          tenant-name: {get_input: live_update_tenant_name}
+          base_image_id: {get_input: nova_image}
+          live_update_image_id: {get_input: live_update_compute_image}
+        ntp:
+          servers:
+              - {server: {get_input: ntp_server}, fudge: "stratum 0"}
+
+  NovaComputeDeployment:
+    type: OS::Heat::StructuredDeployment
+    properties:
+      signal_transport: NO_SIGNAL
+      config: {get_resource: NovaComputeConfig}
+      server: {get_resource: NovaCompute}
+      input_values:
+        nova_compute_driver: {get_param: NovaComputeDriver}
+        nova_compute_libvirt_type: {get_param: NovaComputeLibvirtType}
+        nova_dsn: {get_param: NovaDSN}
+        nova_public_ip: {get_param: NovaPublicIP}
+        nova_api_host: {get_param: NovaApiHost}
+        nova_password: {get_param: NovaPassword}
+        ceilometer_dsn: {get_param: CeilometerDSN}
+        ceilometer_metering_secret: {get_param: CeilometerMeteringSecret}
+        ceilometer_password: {get_param: CeilometerPassword}
+        ceilometer_compute_agent: {get_param: CeilometerComputeAgent}
+        snmpd_readonly_user_name: {get_param: SnmpdReadonlyUserName}
+        snmpd_readonly_user_password: {get_param: SnmpdReadonlyUserPassword}
+        glance_host: {get_param: GlanceHost}
+        glance_port: {get_param: GlancePort}
+        glance_protocol: {get_param: GlanceProtocol}
+        keystone_host: {get_param: KeystoneHost}
+        neutron_flat_networks: {get_param: NeutronFlatNetworks}
+        neutron_host: {get_param: NeutronHost}
+        neutron_dsn: {get_param: NeutronDSN}
+        neutron_local_ip: {get_attr: [NovaCompute, networks, ctlplane, 0]}
+        neutron_tenant_network_type: {get_param: NeutronNetworkType}
+        neutron_tunnel_types: {get_param: NeutronTunnelTypes}
+        neutron_network_vlan_ranges: {get_param: NeutronNetworkVLANRanges}
+        neutron_bridge_mappings: {get_param: NeutronBridgeMappings}
+        neutron_enable_tunneling: {get_param: NeutronEnableTunnelling}
+        neutron_physical_bridge: {get_param: NeutronPhysicalBridge}
+        neutron_public_interface: {get_param: NeutronPublicInterface}
+        neutron_password: {get_param: NeutronPassword}
+        admin_password: {get_param: AdminPassword}
+        rabbit_host: {get_param: RabbitHost}
+        rabbit_username: {get_param: RabbitUserName}
+        rabbit_password: {get_param: RabbitPassword}
+        live_update_host: {get_param: LiveUpdateHost}
+        live_update_username: {get_param: LiveUpdateUserName}
+        live_update_password: {get_param: LiveUpdatePassword}
+        live_update_tenant_name: {get_param: LiveUpdateTenantName}
+        nova_image: {get_param: Image}
+        live_update_image_id: {get_param: LiveUpdateComputeImage}
+        ntp_server: {get_param: NtpServer}
+
+  NovaComputePassthrough:
+    type: OS::Heat::StructuredConfig
+    properties:
+      group: os-apply-config
+      config: {get_input: passthrough_config}
+
+  NovaComputePassthroughSpecific:
+    type: OS::Heat::StructuredConfig
+    properties:
+      group: os-apply-config
+      config: {get_input: passthrough_config_specific}
+
+  NovaComputePassthroughDeployment:
+    depends_on: [NovaComputeDeployment]
+    type: OS::Heat::StructuredDeployment
+    properties:
+      config: {get_resource: NovaComputePassthrough}
+      server: {get_resource: NovaCompute}
+      signal_transport: NO_SIGNAL
+      input_values:
+        passthrough_config: {get_param: ExtraConfig}
+
+  NovaComputePassthroughDeploymentSpecific:
+    depends_on: [NovaComputePassthroughDeployment]
+    type: OS::Heat::StructuredDeployment
+    properties:
+      config: {get_resource: NovaComputePassthroughSpecific}
+      server: {get_resource: NovaCompute}
+      signal_transport: NO_SIGNAL
+      input_values:
+        passthrough_config_specific: {get_param: NovaComputeExtraConfig}
+
+outputs:
+  ip_address:
+    description: IP address of the server in the ctlplane network
+    value: {get_attr: [NovaCompute, networks, ctlplane, 0]}
+  hostname:
+    description: Hostname of the server
+    value: {get_attr: [NovaCompute, name]}
+  hosts_entry:
+    description: >
+      Server's IP address and hostname in the /etc/hosts format
+    value:
+      str_replace:
+        template: "IP HOST HOST.novalocal"
+        params:
+          IP: {get_attr: [NovaCompute, networks, ctlplane, 0]}
+          HOST: {get_attr: [NovaCompute, name]}
+  nova_server_resource:
+    description: Heat resource handle for the Nova compute server
+    value:
+      {get_resource: NovaCompute}
index 4123fc0..885d089 100644 (file)
-description: Nova API,Keystone,Heat Engine and API,Glance,Neutron,Dedicated MySQL
-  server,Dedicated RabbitMQ Server
-heat_template_version: 2013-05-23
+heat_template_version: 2014-10-16
+
+description: >
+  OpenStack control plane node. Can be wrapped in a ResourceGroup for scaling.
+
 parameters:
-  AdminToken:
+  AdminPassword:
+    default: unset
+    description: The password for the keystone admin account, used for monitoring, querying neutron etc.
     type: string
-  BootstrapDumpPassword:
-    default: ''
-    description: Password to use for mysqldump from Bootstrap Host
+    hidden: true
+  AdminToken:
+    default: unset
+    description: The keystone auth secret.
     type: string
     hidden: true
-  BootstrapHost:
-    default: ''
-    description: Load mysqldump from this Host
+  CeilometerMeteringSecret:
+    default: unset
+    description: Secret shared by the ceilometer services.
     type: string
-  BootstrapRootPassword:
-    default: ''
-    description: Root password for localhost access after bootstrap
+    hidden: true
+  CeilometerPassword:
+    default: unset
+    description: The password for the ceilometer service account.
     type: string
     hidden: true
-  BootstrapSlavePassword:
-    default: ''
-    description: Password to use with BootstrapSlaveUser
+  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
-  BootstrapSlaveUser:
+  CloudName:
     default: ''
-    description: User to use for replication from bootstrap host
+    description: The DNS name of this cloud. E.g. ci-overcloud.tripleo.org
     type: string
-  controllerImage:
+  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
-  GlanceDBPassword:
-    description: Password for connecting to glance database
+  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:
+    default: baremetal
+    description: Flavor for control nodes to request when deploying.
     type: string
-    hidden: true
   GlanceNotifierStrategy:
     description: Strategy to use for Glance notification queue
     type: string
@@ -41,8 +105,22 @@ parameters:
     description: The filepath of the file to use for logging messages from Glance.
     type: string
     default: ''
-  HeatDBPassword:
-    description: Password for accessing Heat database.
+  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:
@@ -50,168 +128,589 @@ parameters:
     type: string
     default: ''
     hidden: true
-  InstanceType:
-    default: baremetal
-    description: Use this flavor
+  Image:
+    type: string
+    default: overcloud-control
+  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
-  KeystoneDBPassword:
-    description: Password for connecting to keystone
+  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
-  NeutronDBPassword:
-    description: Password for connecting to neutron database
+  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
+    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
-  NeutronInterfaces:
-    default: eth0
+    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
+  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
-  NovaDBPassword:
-    description: Password for connecting to nova database
+  NeutronPassword:
+    default: unset
+    description: The password for the neutron service account, used by neutron agents.
     type: string
     hidden: true
-  NovaInterfaces:
+  NeutronPublicInterface:
     default: eth0
+    description: What interface to bridge onto br-ex for network nodes.
     type: string
-  RabbitMQPassword:
-    description: Password for RabbitMQ
+  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
+  SnmpdReadonlyUserName:
+    default: ro_snmp_user
+    description: The user name for SNMPd with readonly rights running on all Overcloud nodes
     type: string
-  ServicePassword:
-    description: admin_password for setting up auth in nova.
+  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
+  VirtualIP:
+    type: string
+    default: ''  # Has to be here because of the ignored empty value bug
+
+
 resources:
-  AccessPolicy:
+
+  Controller:
+    type: OS::Nova::Server
     properties:
-      AllowedResources:
-      - controller0
-    type: OS::Heat::AccessPolicy
-  controller0Key:
+      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
+
+  ControllerConfig:
+    type: OS::Heat::StructuredConfig
     properties:
-      UserName:
-        get_resource: User
-    type: AWS::IAM::AccessKey
-  User:
+      group: os-apply-config
+      config:
+        admin-password: {get_param: AdminPassword}
+        admin-token: {get_param: AdminToken}
+        bootstack:
+          public_interface_ip: {get_param: NeutronPublicInterfaceIP}
+        bootstrap_host:
+          nodeid: {get_input: bootstack_nodeid}
+        database:
+          host: &database_host
+            {get_param: VirtualIP}
+        cinder:
+          db:
+            list_join:
+              - ''
+              - - mysql://cinder:unset@
+                - *database_host
+                - /cinder
+          debug: {get_param: Debug}
+          volume_size_mb: {get_param: CinderLVMLoopDeviceSize}
+          service-password: {get_param: CinderPassword}
+          iscsi-helper: {get_param: 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:
+            list_join:
+              - ''
+              - - mysql://glance:unset@
+                - *database_host
+                - /glance
+          debug: {get_param: Debug}
+          host: {get_input: controller_virtual_ip}
+          port: {get_param: GlancePort}
+          protocol: {get_param: GlanceProtocol}
+          service-password: {get_param: GlancePassword}
+          swift-store-user: service:glance
+          swift-store-key: {get_param: GlancePassword}
+          notifier-strategy: {get_param: GlanceNotifierStrategy}
+          log-file: {get_param: GlanceLogFile}
+        heat:
+          admin_password: {get_param: HeatPassword}
+          admin_tenant_name: service
+          admin_user: heat
+          auth_encryption_key: unset___________
+          db:
+            list_join:
+              - ''
+              - - mysql://heat:unset@
+                - *database_host
+                - /heat
+          debug: {get_param: Debug}
+          stack_domain_admin_password: {get_param: HeatStackDomainAdminPassword}
+          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:
+            list_join:
+              - ''
+              - - mysql://keystone:unset@
+                - *database_host
+                - /keystone
+          debug: {get_param: Debug}
+          host: {get_input: controller_virtual_ip}
+          ca_certificate: {get_param: KeystoneCACertificate}
+          signing_key: {get_param: KeystoneSigningKey}
+          signing_certificate: {get_param: KeystoneSigningCertificate}
+        mysql:
+          innodb_buffer_pool_size: {get_param: MysqlInnodbBufferPoolSize}
+          local_bind: true
+          root-password: {get_param: MysqlRootPassword}
+          cluster_name:
+            str_replace:
+              template: tripleo-CLUSTER
+              params:
+                CLUSTER: {get_param: MysqlClusterUniquePart}
+        neutron:
+          debug: {get_param: Debug}
+          flat-networks: {get_param: NeutronFlatNetworks}
+          host: {get_input: controller_virtual_ip}
+          metadata_proxy_shared_secret: unset
+          ovs:
+            enable_tunneling: {get_input: neutron_enable_tunneling}
+            local_ip: {get_input: controller_host}
+            network_vlan_ranges: {get_param: NeutronNetworkVLANRanges}
+            bridge_mappings: {get_param: NeutronBridgeMappings}
+            public_interface: {get_param: NeutronPublicInterface}
+            public_interface_raw_device: {get_param: NeutronPublicInterfaceRawDevice}
+            public_interface_route: {get_param: NeutronPublicInterfaceDefaultRoute}
+            public_interface_tag: {get_param: NeutronPublicInterfaceTag}
+            physical_bridge: br-ex
+            tenant_network_type: {get_param: NeutronNetworkType}
+            tunnel_types: {get_param: NeutronTunnelTypes}
+          ovs_db:
+            list_join:
+              - ''
+              - - mysql://neutron:unset@
+                - *database_host
+                - /ovs_neutron?charset=utf8
+          service-password: {get_param: NeutronPassword}
+          dnsmasq-options: {get_param: NeutronDnsmasqOptions}
+        ceilometer:
+          db:
+            list_join:
+              - ''
+              - - mysql://ceilometer:unset@
+                - *database_host
+                - /ceilometer
+          debug: {get_param: Debug}
+          metering_secret: {get_param: CeilometerMeteringSecret}
+          service-password: {get_param: CeilometerPassword}
+        snmpd:
+          export_MIB: UCD-SNMP-MIB
+          readonly_user_name: {get_param: SnmpdReadonlyUserName}
+          readonly_user_password: {get_param: SnmpdReadonlyUserPassword}
+        nova:
+          compute_driver: libvirt.LibvirtDriver
+          db:
+            list_join:
+              - ''
+              - - mysql://nova:unset@
+                - *database_host
+                - /nova
+          default_floating_pool:
+            ext-net
+          host: {get_input: controller_virtual_ip}
+          metadata-proxy: true
+          service-password: {get_param: NovaPassword}
+        rabbit:
+          host: {get_input: controller_virtual_ip}
+          username: {get_param: RabbitUserName}
+          password: {get_param: RabbitPassword}
+          cookie: {get_param: RabbitCookie}
+        ntp:
+          servers:
+              - {server: {get_param: NtpServer}, fudge: "stratum 0"}
+        virtual_interfaces:
+          instances:
+            - vrrp_instance_name: VI_CONTROL
+              virtual_router_id: 51
+              keepalive_interface: {get_param: ControlVirtualInterface}
+              priority: 101
+              virtual_ips:
+              - ip: {get_param: VirtualIP}
+                interface: {get_param: ControlVirtualInterface}
+            - vrrp_instance_name: VI_PUBLIC
+              virtual_router_id: 52
+              keepalive_interface: {get_param: PublicVirtualInterface}
+              priority: 101
+              virtual_ips:
+              - ip: {get_param: PublicVirtualIP}
+                interface: {get_param: PublicVirtualInterface}
+          vrrp_sync_groups:
+            - name: VG1
+              members:
+                - VI_CONTROL
+                - VI_PUBLIC
+        keepalived:
+          keepalive_interface: {get_param: PublicVirtualInterface}
+          priority: 101
+        virtual_ips:
+            -
+              ip: {get_param: VirtualIP}
+              interface: {get_param: ControlVirtualInterface}
+            -
+              ip: {get_param: PublicVirtualIP}
+              interface: {get_param: PublicVirtualInterface}
+        haproxy:
+          net_binds:
+            - ip: {get_param: VirtualIP}
+          services:
+            - name: keystone_admin
+              port: 35357
+              net_binds: &public_binds
+                - ip: {get_param: VirtualIP}
+                - ip: {get_param: PublicVirtualIP}
+            - 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
+            - 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: ceilometer
+              port: 8777
+              net_binds: *public_binds
+            - name: swift_proxy_server
+              port: 8080
+              net_binds: *public_binds
+            - name: rabbitmq
+              port: 5672
+              options:
+                - timeout client 0
+                - timeout server 0
+
+  ControllerPassthroughConfig:
+    type: OS::Heat::StructuredConfig
     properties:
-      Policies:
-      - get_resource: AccessPolicy
-    type: AWS::IAM::User
-  controller0:
-    metadata:
-      admin-password:
-        get_param: ServicePassword
-      admin-token:
-        get_param: AdminToken
-      mysql:
-        create-users:
-          - database: keystone
-            username: keystone
-            password: {get_param: KeystoneDBPassword}
-          - database: heat
-            username: heat
-            password: {get_param: HeatDBPassword}
-          - database: glance
-            username: glance
-            password: {get_param: GlanceDBPassword}
-          - database: nova
-            username: nova
-            password: {get_param: NovaDBPassword}
-          - database: neutron
-            username: neutron
-            password: {get_param: NeutronDBPassword}
-      glance:
-        db:
-          Fn::Join:
-            - ''
-            - - 'mysql://glance:'
-              - {get_param: GlanceDBPassword}
-              - '@127.0.0.1/glance'
-          notifier-strategy:
-            get_param: GlanceNotifierStrategy
-          log-file:
-            get_param: GlanceLogFile
-      heat:
-        db:
-          Fn::Join:
-            - ''
-            - - 'mysql://heat:'
-              - {get_param: HeatDBPassword}
-              - '@127.0.0.1/heat'
-        access_key_id:
-          get_resource: controller0Key
-        refresh:
-        - resource: controller0
-        secret_key:
-          get_attr:
-          - controller0Key
-          - SecretAccessKey
-        stack:
-          name:
-            get_param: AWS::StackName
-          region:
-            get_param: AWS::Region
-        auth_encryption_key: unset
-        stack_domain_admin_password: {get_param: HeatStackDomainAdminPassword}
-      interfaces:
-        control:
-          get_param: NovaInterfaces
-      keystone:
-        host:
-          '127.0.0.1'
-        db:
-          Fn::Join:
+      group: os-apply-config
+      config: {get_input: passthrough_config}
+
+  ControllerPassthroughConfigSpecific:
+    type: OS::Heat::StructuredConfig
+    properties:
+      group: os-apply-config
+      config: {get_input: passthrough_config_specific}
+
+  ControllerDeployment:
+    type: OS::Heat::StructuredDeployment
+    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:
             - ''
-            - - 'mysql://keystone:'
-              - {get_param: KeystoneDBPassword}
-              - '@127.0.0.1/keystone'
-      nova:
-        db:
-          Fn::Join:
+            - - 'http://'
+              - {get_param: VirtualIP}
+              - ':8003'
+        heat.metadata_server_url:
+          list_join:
             - ''
-            - - 'mysql://nova:'
-              - {get_param: NovaDBPassword}
-              - '@127.0.0.1/nova'
-      neutron:
-        host:
-          '127.0.0.1'
-        ovs_db:
-          Fn::Join:
+            - - 'http://'
+              - {get_param: VirtualIP}
+              - ':8000'
+        heat.waitcondition_server_url:
+          list_join:
             - ''
-            - - 'mysql://neutron:'
-              - {get_param: NeutronDBPassword}
-              - '@127.0.0.1/ovs_neutron'
-      rabbit:
-        host:
-          '127.0.0.1'
-        username:
-          get_param: RabbitUserName
-        password:
-          get_param: RabbitPassword
-        users:
-          username:
-            get_param: RabbitUserName
-          password:
-            get_param: RabbitPassword
-        cookie:
-          get_attr:
-          - RabbitCookie
-          - value
-      service-password:
-        get_param: ServicePassword
+            - - 'http://'
+              - {get_param: VirtualIP}
+              - ':8000/v1/waitcondition'
+
+  SSLConfig:
+    type: OS::Heat::StructuredConfig
+    properties:
+      group: os-apply-config
+      config:
+        ssl:
+          ca_certificate: {get_input: ssl_ca_certificate}
+        stunnel:
+          cert: {get_input: ssl_certificate}
+          key: {get_input: ssl_key}
+          cacert: {get_input: ssl_ca_certificate}
+          ports:
+           - name: 'ec2'
+             accept: 13773
+             connect: 8773
+             connect_host: {get_input: controller_host}
+           - name: 'image'
+             accept: 13292
+             connect: 9292
+             connect_host: {get_input: controller_host}
+           - name: 'identity'
+             accept: 13000
+             connect: 5000
+             connect_host: {get_input: controller_host}
+           - name: 'network'
+             accept: 13696
+             connect: 9696
+             connect_host: {get_input: controller_host}
+           - name: 'compute'
+             accept: 13774
+             connect: 8774
+             connect_host: {get_input: controller_host}
+           - name: 'swift-proxy'
+             accept: 13080
+             connect: 8080
+             connect_host: {get_input: controller_host}
+           - name: 'cinder'
+             accept: 13776
+             connect: 8776
+             connect_host: {get_input: controller_host}
+           - name: 'ceilometer'
+             accept: 13777
+             connect: 8777
+             connect_host: {get_input: controller_host}
+
+  ControllerSSLDeployment:
+    type: OS::Heat::StructuredDeployment
+    properties:
+      config: {get_resource: SSLConfig}
+      server: {get_resource: Controller}
+      signal_transport: NO_SIGNAL
+      input_values:
+        controller_host: {get_attr: [Controller, networks, ctlplane, 0]}
+        ssl_certificate: {get_param: SSLCertificate}
+        ssl_key: {get_param: SSLKey}
+        ssl_ca_certificate: {get_param: SSLCACertificate}
+
+  ControllerPassthroughDeployment:
+    type: OS::Heat::StructuredDeployment
+    properties:
+      config: {get_resource: ControllerPassthroughConfig}
+      server: {get_resource: Controller}
+      signal_transport: NO_SIGNAL
+      input_values:
+        passthrough_config: {get_param: ExtraConfig}
+
+  ControllerPassthroughSpecificDeployment:
+    depends_on: [ControllerPassthroughDeployment]
+    type: OS::Heat::StructuredDeployment
     properties:
-      ImageId:
-        get_param: controllerImage
-      InstanceType:
-        get_param: InstanceType
-      KeyName:
-        get_param: KeyName
-    type: AWS::EC2::Instance
+      config: {get_resource: ControllerPassthroughConfigSpecific}
+      server: {get_resource: Controller}
+      signal_transport: NO_SIGNAL
+      input_values:
+        passthrough_config_specific: {get_param: ControllerExtraConfig}
+
+
+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]}
diff --git a/overcloud-resource-registry.yaml b/overcloud-resource-registry.yaml
new file mode 100644 (file)
index 0000000..29074fc
--- /dev/null
@@ -0,0 +1,3 @@
+resource_registry:
+  OS::TripleO::Compute: compute.yaml
+  OS::TripleO::Controller: controller.yaml
diff --git a/overcloud-without-mergepy.yaml b/overcloud-without-mergepy.yaml
new file mode 100644 (file)
index 0000000..cb4f25c
--- /dev/null
@@ -0,0 +1,677 @@
+heat_template_version: 2014-10-16
+
+description: >
+  Nova API,Keystone,Heat Engine and API,Glance,Neutron,Dedicated MySQL
+  server,Dedicated RabbitMQ Server,Group of Nova Computes
+
+
+# TODO(shadower): we should probably use the parameter groups to put
+# some order in here.
+parameters:
+
+  # Common parameters (not specific to a role)
+  AdminPassword:
+    default: unset
+    description: The password for the keystone admin account, used for monitoring, querying neutron etc.
+    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
+  CloudName:
+    default: ''
+    description: The DNS name of this cloud. E.g. ci-overcloud.tripleo.org
+    type: string
+  ControlFixedIPs:
+    default: []
+    description: Should be used for arbitrary ips.
+    type: json
+  Debug:
+    default: ''
+    description: Set to True to enable debugging on all services.
+    type: string
+  DefaultSignalTransport:
+    default: CFN_SIGNAL
+    description: Transport to use for software-config signals.
+    type: string
+    constraints:
+      - allowed_values: [ CFN_SIGNAL, HEAT_SIGNAL, NO_SIGNAL ]
+  GlancePort:
+    default: "9292"
+    description: Glance port.
+    type: string
+  GlanceProtocol:
+    default: http
+    description: Protocol to use when connecting to glance, set to https for SSL.
+    type: string
+  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
+  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: "datacentre:br-ex"
+  NeutronControlPlaneID:
+    default: ''
+    type: string
+    description: Neutron ID for ctlplane network.
+  NeutronEnableTunnelling:
+    type: string
+    default: "True"
+  NeutronFlatNetworks:
+    type: string
+    default: 'datacentre'
+    description: >
+      If set, flat networks to configure in neutron plugins. Defaults to
+      'datacentre' to permit external network creation.
+  NeutronNetworkType:
+    default: 'gre'
+    description: The tenant network type for Neutron, either gre or vxlan.
+    type: string
+  NeutronPassword:
+    default: unset
+    description: The password for the neutron service account, used by neutron agents.
+    type: string
+    hidden: true
+  NeutronPublicInterface:
+    default: eth0
+    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
+  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: ''
+  PublicVirtualFixedIPs:
+    default: []
+    description: >
+        Control the IP allocation for the PublicVirtualInterface port. E.g.
+        [{'ip_address':'1.2.3.4'}]
+    type: json
+  PublicVirtualNetwork:
+    default: 'ctlplane'
+    type: string
+    description: >
+        Neutron network to allocate public virtual IP port on.
+  RabbitCookieSalt:
+    type: string
+    default: unset
+    description: Salt for the rabbit cookie, change this to force the randomly generated rabbit cookie to change.
+  RabbitUserName:
+    default: guest
+    description: The username for RabbitMQ
+    type: string
+  RabbitPassword:
+    default: guest
+    description: The password for RabbitMQ
+    type: string
+    hidden: true
+  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
+
+
+  # Controller-specific params
+  AdminToken:
+    default: unset
+    description: The keystone auth secret.
+    type: string
+    hidden: true
+  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
+  CinderISCSIHelper:
+    default: tgtadm
+    description: The iSCSI helper to use with cinder.
+    type: string
+  ControllerCount:
+    type: number
+    default: 1
+  controllerExtraConfig:
+    default: {}
+    description: |
+      Controller specific configuration to inject into the cluster. Same
+      structure as ExtraConfig.
+    type: json
+  controllerImage:
+    type: string
+    default: overcloud-control
+  OvercloudControlFlavor:
+    default: baremetal
+    description: Flavor for control nodes to request when deploying.
+    type: string
+  ControlVirtualInterface:
+    default: 'br-ex'
+    description: Interface where virtual ip will be assigned.
+    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": "force_config_drive",
+                  "value": "always"
+                 }
+                ]
+             },
+             {"section": "cells",
+              "values":
+                [{"option": "driver",
+                  "value": "nova.cells.rpc_driver.CellsRPCDriver"
+                 }
+                ]
+             }
+            ]
+          }
+        }
+    type: json
+  GlanceLogFile:
+    description: The filepath of the file to use for logging messages from Glance.
+    type: string
+    default: ''
+  GlanceNotifierStrategy:
+    description: Strategy to use for Glance notification queue
+    type: string
+    default: noop
+  GlancePassword:
+    default: unset
+    description: The password for the glance service account, used by the glance services.
+    type: string
+    hidden: true
+  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
+  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
+  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
+  NeutronDnsmasqOptions:
+    default: 'dhcp-option-force=26,1400'
+    description: Dnsmasq options for neutron-dhcp-agent. The default value here forces MTU to be set to 1400 to account for the tunnel overhead.
+    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
+  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
+  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
+  SSLCACertificate:
+    default: ''
+    description: If set, the contents of an SSL certificate authority file.
+    type: string
+  SwiftHashSuffix:
+    default: unset
+    description: A random string to be used as a salt when hashing to determine mappings in the ring.
+    type: string
+    hidden: true
+  SwiftPassword:
+    default: unset
+    description: The password for the swift service account, used by the swift proxy services.
+    type: string
+    hidden: true
+  SwiftPartPower:
+    default: 10
+    description: Partition Power to use when building Swift rings
+    type: number
+  SwiftReplicas:
+    type: number
+    default: 1
+    description: How many replicas to use in the swift rings.
+
+# Compute-specific params
+  CeilometerComputeAgent:
+    description: Indicates whether the Compute agent is present and expects nova-compute to be configured accordingly
+    type: string
+    default: ''
+    constraints:
+    - allowed_values: ['', Present]
+  ComputeCount:
+    type: number
+    default: 1
+  HypervisorNeutronPhysicalBridge:
+    default: 'br-ex'
+    description: >
+      An OVS bridge to create on each hypervisor. This defaults to br-ex the
+      same as the control plane nodes, as we have a uniform configuration of
+      the openvswitch agent. Typically should not need to be changed.
+    type: string
+  HypervisorNeutronPublicInterface:
+    default: 'eth0'
+    description: What interface to add to the HypervisorNeutronPhysicalBridge.
+    type: string
+  LiveUpdateComputeImage:
+    type: string
+    description: The image ID for live-updates to the overcloud compute nodes.
+    default: ''
+  LiveUpdateHost:
+    type: string
+    description: The IP address for the undercloud Glance API.
+    default: ''
+  LiveUpdatePassword:
+    type: string
+    default: ''
+    description: The live-update password for the undercloud Glance API.
+    hidden: true
+  LiveUpdateTenantName:
+    type: string
+    description: The live-update tenant name for the undercloud Glance API.
+    default: ''
+  LiveUpdateUserName:
+    type: string
+    description: The live-update username for the undercloud Glance API.
+    default: ''
+  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
+  NovaComputeDriver:
+    type: string
+    default: libvirt.LibvirtDriver
+  NovaComputeExtraConfig:
+    default: {}
+    description: |
+      NovaCompute specific configuration to inject into the cluster. Same
+      structure as ExtraConfig.
+    type: json
+  NovaComputeLibvirtType:
+    default: ''
+    type: string
+  NovaImage:
+    type: string
+    default: overcloud-compute
+  OvercloudComputeFlavor:
+    description: Use this flavor
+    type: string
+    default: baremetal
+
+
+resources:
+
+  Controller:
+    type: OS::Heat::ResourceGroup
+    properties:
+      count: {get_param: ControllerCount}
+      resource_def:
+        type: OS::TripleO::Controller
+        properties:
+          AdminPassword: {get_param: AdminPassword}
+          AdminToken: {get_param: AdminToken}
+          CeilometerMeteringSecret: {get_param: CeilometerMeteringSecret}
+          CeilometerPassword: {get_param: CeilometerPassword}
+          CinderLVMLoopDeviceSize: {get_param: CinderLVMLoopDeviceSize}
+          CinderPassword: {get_param: CinderPassword}
+          CinderISCSIHelper: {get_param: CinderISCSIHelper}
+          CloudName: {get_param: CloudName}
+          ControlVirtualInterface: {get_param: ControlVirtualInterface}
+          ControllerExtraConfig: {get_param: controllerExtraConfig}
+          ExtraConfig: {get_param: ExtraConfig}
+          Flavor: {get_param: OvercloudControlFlavor}
+          GlancePort: {get_param: GlancePort}
+          GlanceProtocol: {get_param: GlanceProtocol}
+          GlancePassword: {get_param: GlancePassword}
+          GlanceNotifierStrategy: {get_param: GlanceNotifierStrategy}
+          GlanceLogFile: {get_param: GlanceLogFile}
+          HeatPassword: {get_param: HeatPassword}
+          HeatStackDomainAdminPassword: {get_param: HeatStackDomainAdminPassword}
+          Image: {get_param: controllerImage}
+          ImageUpdatePolicy: {get_param: ImageUpdatePolicy}
+          KeyName: {get_param: KeyName}
+          KeystoneCACertificate: {get_param: KeystoneCACertificate}
+          KeystoneSigningCertificate: {get_param: KeystoneSigningCertificate}
+          KeystoneSigningKey: {get_param: KeystoneSigningKey}
+          MysqlClusterUniquePart: {get_attr: [MysqlClusterUniquePart, value]}
+          MysqlInnodbBufferPoolSize: {get_param: MysqlInnodbBufferPoolSize}
+          MysqlRootPassword: {get_attr: [MysqlRootPassword, value]}
+          NeutronPublicInterfaceIP: {get_param: NeutronPublicInterfaceIP}
+          NeutronFlatNetworks: {get_param: NeutronFlatNetworks}
+          NeutronBridgeMappings: {get_param: NeutronBridgeMappings}
+          NeutronNetworkVLANRanges: {get_param: NeutronNetworkVLANRanges}
+          NeutronPublicInterface: {get_param: NeutronPublicInterface}
+          NeutronPublicInterfaceDefaultRoute: {get_param: NeutronPublicInterfaceDefaultRoute}
+          NeutronPublicInterfaceRawDevice: {get_param: NeutronPublicInterfaceRawDevice}
+          NeutronPassword: {get_param: NeutronPassword}
+          NeutronDnsmasqOptions: {get_param: NeutronDnsmasqOptions}
+          NovaPassword: {get_param: NovaPassword}
+          NtpServer: {get_param: NtpServer}
+          PublicVirtualInterface: {get_param: PublicVirtualInterface}
+          RabbitUserName: {get_param: RabbitUserName}
+          RabbitPassword: {get_param: RabbitPassword}
+          RabbitCookie: {get_attr: [RabbitCookie, value]}
+          SnmpdReadonlyUserName: {get_param: SnmpdReadonlyUserName}
+          SnmpdReadonlyUserPassword: {get_param: SnmpdReadonlyUserPassword}
+          SSLCertificate: {get_param: SSLCertificate}
+          SSLKey: {get_param: SSLKey}
+          SSLCACertificate: {get_param: SSLCACertificate}
+          VirtualIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+          PublicVirtualIP: {get_attr: [PublicVirtualIP, fixed_ips, 0, ip_address]}
+
+  Compute:
+    type: OS::Heat::ResourceGroup
+    properties:
+      count: {get_param: ComputeCount}
+      resource_def:
+        type: OS::TripleO::Compute
+        properties:
+          AdminPassword: {get_param: AdminPassword}
+          CeilometerComputeAgent: {get_param: CeilometerComputeAgent}
+          CeilometerMeteringSecret: {get_param: CeilometerMeteringSecret}
+          CeilometerPassword: {get_param: CeilometerPassword}
+          ExtraConfig: {get_param: ExtraConfig}
+          Flavor: {get_param: OvercloudComputeFlavor}
+          GlanceHost: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+          GlancePort: {get_param: GlancePort}
+          GlanceProtocol: {get_param: GlanceProtocol}
+          Image: {get_param: NovaImage}
+          ImageUpdatePolicy: {get_param: ImageUpdatePolicy}
+          KeyName: {get_param: KeyName}
+          KeystoneHost: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+          LiveUpdateComputeImage: {get_param: LiveUpdateComputeImage}
+          LiveUpdateHost: {get_param: LiveUpdateHost}
+          LiveUpdatePassword: {get_param: LiveUpdatePassword}
+          LiveUpdateTenantName: {get_param: LiveUpdateTenantName}
+          LiveUpdateUserName: {get_param: LiveUpdateUserName}
+          NeutronBridgeMappings: {get_param: NeutronBridgeMappings}
+          NeutronEnableTunnelling: {get_param: NeutronEnableTunnelling}
+          NeutronFlatNetworks: {get_param: NeutronFlatNetworks}
+          NeutronHost: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+          NeutronNetworkType: {get_param: NeutronNetworkType}
+          NeutronTunnelTypes: {get_param: NeutronTunnelTypes}
+          NeutronNetworkVLANRanges: {get_param: NeutronNetworkVLANRanges}
+          NeutronPassword: {get_param: NeutronPassword}
+          NeutronPhysicalBridge: {get_param: HypervisorNeutronPhysicalBridge}
+          NeutronPublicInterface: {get_param: HypervisorNeutronPublicInterface}
+          NovaApiHost: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+          NovaComputeDriver: {get_param: NovaComputeDriver}
+          NovaComputeExtraConfig: {get_param: NovaComputeExtraConfig}
+          NovaComputeLibvirtType: {get_param: NovaComputeLibvirtType}
+          NovaPublicIP: {get_attr: [PublicVirtualIP, fixed_ips, 0, ip_address]}
+          NovaPassword: {get_param: NovaPassword}
+          NtpServer: {get_param: NtpServer}
+          RabbitHost: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+          RabbitPassword: {get_param: RabbitPassword}
+          RabbitUserName: {get_param: RabbitUserName}
+          SnmpdReadonlyUserName: {get_param: SnmpdReadonlyUserName}
+          SnmpdReadonlyUserPassword: {get_param: SnmpdReadonlyUserPassword}
+          NovaDSN:
+            list_join:
+              - ''
+              - - mysql://nova:unset@
+                - &compute_database_host {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+                - /nova
+          CeilometerDSN:
+            list_join:
+              - ''
+              - - mysql://ceilometer:unset@
+                - *compute_database_host
+                - /ceilometer
+          NeutronDSN:
+            list_join:
+              - ''
+              - - mysql://neutron:unset@
+                - *compute_database_host
+                - /ovs_neutron
+
+  allNodesConfig:
+    type: OS::Heat::StructuredConfig
+    properties:
+      config:
+        completion-signal: {get_input: deploy_signal_id}
+        hosts:
+          list_join:
+          - "\n"
+          - - list_join:
+              - "\n"
+              - {get_attr: [Compute, hosts_entry]}
+            - list_join:
+              - "\n"
+              - {get_attr: [Controller, hosts_entry]}
+              # TODO: ADD BLOCK STORAGE ENTRY HERE
+              # TODO: ADD SWIFT STORAGE ENTRY HERE
+        rabbit:
+          nodes:
+            list_join:
+            - ','
+            - {get_attr: [Controller, hostname]}
+
+  MysqlRootPassword:
+    type: OS::Heat::RandomString
+    properties:
+      length: 10
+
+  MysqlClusterUniquePart:
+    type: OS::Heat::RandomString
+    properties:
+      length: 10
+
+  RabbitCookie:
+    type: OS::Heat::RandomString
+    properties:
+      length: 20
+      salt: {get_param: RabbitCookieSalt}
+
+  ControlVirtualIP:
+    type: OS::Neutron::Port
+    properties:
+      name: control_virtual_ip
+      network_id: {get_param: NeutronControlPlaneID}
+      fixed_ips: {get_param: ControlFixedIPs}
+
+  PublicVirtualIP:
+    type: OS::Neutron::Port
+    properties:
+      name: public_virtual_ip
+      network: {get_param: PublicVirtualNetwork}
+      fixed_ips: {get_param: PublicVirtualFixedIPs}
+
+  ControllerBootstrapNodeConfig:
+    type: OS::Heat::StructuredConfig
+    properties:
+      group: os-apply-config
+      config:
+        bootstrap_host:
+          bootstrap_nodeid: {get_attr: [Controller, resource.0.hostname]}
+
+  ControllerBootstrapNodeDeployment:
+    type: OS::Heat::StructuredDeployments
+    properties:
+      config: {get_resource: ControllerBootstrapNodeConfig}
+      servers: {get_attr: [Controller, attributes, nova_server_resource]}
+      signal_transport: NO_SIGNAL
+
+  ControllerSwiftDeployment:
+    type: OS::Heat::StructuredDeployments
+    properties:
+      config: {get_resource: ControllerSwiftConfig}
+      servers: {get_attr: [Controller, attributes, nova_server_resource]}
+      signal_transport: NO_SIGNAL
+      input_values:
+        swift_hash_suffix: {get_param: SwiftHashSuffix}
+        swift_password: {get_param: SwiftPassword}
+        swift_part_power: {get_param: SwiftPartPower}
+        swift_replicas: { get_param: SwiftReplicas}
+
+  ControllerSwiftConfig:
+    type: OS::Heat::StructuredConfig
+    properties:
+      group: os-apply-config
+      config:
+        swift:
+          devices:
+            list_join:
+            - ", "
+            - - list_join:
+                - ", "
+                - {get_attr: [Controller, swift_device]}
+              - list_join:
+                - ", "
+                # TODO: replace the empty list with this:
+                # - {get_attr: [ObjectStorage, swift_device]}
+                # Once we have the swift/object-storage role
+                - []
+          hash: { get_input: swift_hash_suffix }
+          part-power: { get_input: swift_part_power }
+          proxy-memcache:
+            list_join:
+            - ","
+            - {get_attr: [Controller, swift_proxy_memcache]}
+          replicas: {get_input: swift_replicas }
+          service-password: { get_input: swift_password }
+
+  ControllerClusterConfig:
+    type: OS::Heat::StructuredConfig
+    properties:
+      config:
+        corosync:
+          nodes: {get_attr: [Controller, corosync_node]}
+        horizon:
+          caches:
+            memcached:
+              nodes: {get_attr: [Controller, hostname]}
+        mysql:
+          nodes: {get_attr: [Controller, corosync_node]}
+        haproxy:
+          nodes: {get_attr: [Controller, corosync_node]}
+
+  ControllerClusterDeployment:
+    type: OS::Heat::StructuredDeployments
+    properties:
+      config: {get_resource: ControllerClusterConfig}
+      servers: {get_attr: [Controller, attributes, nova_server_resource]}
+      signal_transport: NO_SIGNAL
+
+  ControllerAllNodesDeployment:
+    type: OS::Heat::StructuredDeployments
+    properties:
+      config: {get_resource: allNodesConfig}
+      servers: {get_attr: [Controller, attributes, nova_server_resource]}
+
+  ComputeAllNodesDeployment:
+    type: OS::Heat::StructuredDeployments
+    properties:
+      config: {get_resource: allNodesConfig}
+      servers: {get_attr: [Compute, attributes, nova_server_resource]}
+
+
+outputs:
+  KeystoneURL:
+    description: URL for the Overcloud Keystone service
+    value:
+      list_join:
+      - ''
+      - - http://
+        - {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
+        - :5000/v2.0/