Merge "Add SwiftMountCheck to overcloud-without-mergepy"
[apex-tripleo-heat-templates.git] / controller.yaml
index f7a8633..3d767c5 100644 (file)
-Description: Nova API,Keystone,Heat Engine and API,Glance,Neutron,Dedicated MySQL
-  server,Dedicated RabbitMQ Server
-HeatTemplateFormatVersion: '2012-12-12'
-Parameters:
+heat_template_version: 2014-10-16
+
+description: >
+  OpenStack control plane 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
   AdminToken:
-    Type: String
-  BootstrapDumpPassword:
-    Default: ''
-    Description: Password to use for mysqldump from Bootstrap Host
-    Type: String
-    NoEcho: true
-  BootstrapHost:
-    Default: ''
-    Description: Load mysqldump from this Host
-    Type: String
-  BootstrapRootPassword:
-    Default: ''
-    Description: Root password for localhost access after bootstrap
-    Type: String
-    NoEcho: true
-  BootstrapSlavePassword:
-    Default: ''
-    Description: Password to use with BootstrapSlaveUser
-    Type: String
-    NoEcho: true
-  BootstrapSlaveUser:
-    Default: ''
-    Description: User to use for replication from bootstrap host
-    Type: String
-  GlanceDBPassword:
-    Description: Password for connecting to glance database
-    Type: String
-    NoEcho: true
+    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
+    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: ''
-  HeatDBPassword:
-    Description: Password for accessing Heat database.
-    Type: String
-    NoEcho: true
-  InstanceType:
-    Default: baremetal
-    Description: Use this flavor
-    Type: String
+    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
-  KeystoneDBPassword:
-    Description: Password for connecting to keystone
-    Type: String
-    NoEcho: true
-  NovaDBPassword:
-    Description: Password for connecting to nova database
-    Type: String
-    NoEcho: true
-  NovaInterfaces:
-    Default: eth0
-    Type: String
-  NeutronDBPassword:
-    Description: Password for connecting to neutron database
-    Type: String
-    NoEcho: true
-  NeutronInterfaces:
-    Default: eth0
-    Type: String
-  RabbitMQPassword:
-    Description: Password for RabbitMQ
-    Type: String
-    NoEcho: true
-  RabbitUserName:
-    Type: String
+    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
+  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:
-    Type: String
-    NoEcho: true
-  ServicePassword:
-    Description: admin_password for setting up auth in nova.
-    Type: String
-    NoEcho: true
-  controllerImage:
-    Type: String
-  HeatStackDomainAdminPassword:
-    Description: Password for heat_domain_admin user.
-    Type: String
-    Default: ''
-    NoEcho: true
-Resources:
-  AccessPolicy:
-    Properties:
-      AllowedResources:
-      - controller0
-    Type: OS::Heat::AccessPolicy
-  controller0Key:
-    Properties:
-      UserName:
-        Ref: User
-    Type: AWS::IAM::AccessKey
-  User:
-    Properties:
-      Policies:
-      - Ref: AccessPolicy
-    Type: AWS::IAM::User
-  controller0:
-    Metadata:
-      admin-password:
-        Ref: ServicePassword
-      admin-token:
-        Ref: AdminToken
-      mysql:
-        create-users:
-          - database: keystone
-            username: keystone
-            password: {Ref: KeystoneDBPassword}
-          - database: heat
-            username: heat
-            password: {Ref: HeatDBPassword}
-          - database: glance
-            username: glance
-            password: {Ref: GlanceDBPassword}
-          - database: nova
-            username: nova
-            password: {Ref: NovaDBPassword}
-          - database: neutron
-            username: neutron
-            password: {Ref: NeutronDBPassword}
-      glance:
-        db:
-          Fn::Join:
+    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}
+
+  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:
+      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::TripleO::SoftwareDeployment
+    properties:
+      signal_transport: NO_SIGNAL
+      config: {get_attr: [ControllerConfig, config_id]}
+      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://glance:'
-              - {Ref: GlanceDBPassword}
-              - '@127.0.0.1/glance'
-          notifier-strategy:
-            Ref: GlanceNotifierStrategy
-          log-file:
-            Ref: GlanceLogFile
-      heat:
-        db:
-          Fn::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://heat:'
-              - {Ref: HeatDBPassword}
-              - '@127.0.0.1/heat'
-        access_key_id:
-          Ref: controller0Key
-        refresh:
-        - resource: controller0
-        secret_key:
-          Fn::GetAtt:
-          - controller0Key
-          - SecretAccessKey
-        stack:
-          name:
-            Ref: AWS::StackName
-          region:
-            Ref: AWS::Region
-        auth_encryption_key: unset
-        stack_domain_admin_password: {Ref: HeatStackDomainAdminPassword}
-      interfaces:
-        control:
-          Ref: NovaInterfaces
-      keystone:
-        host:
-          '127.0.0.1'
-        db:
-          Fn::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://keystone:'
-              - {Ref: KeystoneDBPassword}
-              - '@127.0.0.1/keystone'
-      nova:
-        db:
-          Fn::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://nova:'
-              - {Ref: NovaDBPassword}
-              - '@127.0.0.1/nova'
-      neutron:
-        host:
-          '127.0.0.1'
-        ovs_db:
-          Fn::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://neutron:'
-              - {Ref: NeutronDBPassword}
-              - '@127.0.0.1/ovs_neutron'
-      rabbit:
-        host:
-          '127.0.0.1'
-        username:
-          Ref: RabbitUserName
-        password:
-          Ref: RabbitPassword
-        users:
-          username:
-            Ref: RabbitUserName
-          password:
-            Ref: RabbitPassword
-        cookie:
-          Fn::GetAtt:
-          - RabbitCookie
-          - value
-      service-password:
-        Ref: ServicePassword
-    Properties:
-      ImageId:
-        Ref: controllerImage
-      InstanceType:
-        Ref: InstanceType
-      KeyName:
-        Ref: KeyName
-    Type: AWS::EC2::Instance
+            - - '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}
+
+  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:
+      config: {get_resource: ControllerPassthroughConfigSpecific}
+      server: {get_resource: Controller}
+      signal_transport: NO_SIGNAL
+      input_values:
+        passthrough_config_specific: {get_param: ControllerExtraConfig}
+
+  SwiftConfig:
+    type: OS::Heat::StructuredConfig
+    properties:
+      group: os-apply-config
+      config:
+        swift:
+          hash: { get_input: swift_hash_suffix }
+          part-power: { get_input: swift_part_power }
+          mount-check: { get_input: swift_mount_check }
+          min-part-hours: { get_input: swift_min_part_hours }
+          replicas: {get_input: swift_replicas }
+          service-password: { get_input: swift_password }
+
+  SwiftStorageDeploy:
+    type: OS::Heat::StructuredDeployment
+    properties:
+      server: {get_resource: Controller}
+      config: {get_resource: SwiftConfig}
+      signal_transport: NO_SIGNAL
+      input_values:
+        swift_hash_suffix: {get_param: SwiftHashSuffix}
+        swift_mount_check: {get_param: SwiftMountCheck}
+        swift_password: {get_param: SwiftPassword}
+        swift_min_part_hours: {get_param: SwiftMinPartHours}
+        swift_part_power: {get_param: SwiftPartPower}
+        swift_replicas: { get_param: SwiftReplicas}
+
+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]}