1 heat_template_version: 2016-10-14
4 Deploy an OpenStack environment, consisting of several node types (roles),
5 Controller, Compute, BlockStorage, SwiftStorage and CephStorage. The Storage
6 roles enable independent scaling of the storage components, but the minimal
7 deployment is one Controller and one Compute node.
10 # TODO(shadower): we should probably use the parameter groups to put
14 # Common parameters (not specific to a role)
16 default: overcloud.localdomain
17 description: The DNS name of this cloud. E.g. ci-overcloud.tripleo.org
20 default: overcloud.internalapi.localdomain
22 The DNS name of this cloud's internal API endpoint. E.g.
23 'ci-overcloud.internalapi.tripleo.org'.
26 default: overcloud.storage.localdomain
28 The DNS name of this cloud's storage endpoint. E.g.
29 'ci-overcloud.storage.tripleo.org'.
31 CloudNameStorageManagement:
32 default: overcloud.storagemgmt.localdomain
34 The DNS name of this cloud's storage management endpoint. E.g.
35 'ci-overcloud.storagemgmt.tripleo.org'.
38 default: overcloud.ctlplane.localdomain
40 The DNS name of this cloud's storage management endpoint. E.g.
41 'ci-overcloud.management.tripleo.org'.
45 description: Should be used for arbitrary ips.
47 InternalApiVirtualFixedIPs:
50 Control the IP allocation for the InternalApiVirtualInterface port. E.g.
51 [{'ip_address':'1.2.3.4'}]
53 NeutronControlPlaneID:
56 description: Neutron ID or name for ctlplane network.
57 NeutronPublicInterface:
59 description: What interface to bridge onto br-ex for network nodes.
61 PublicVirtualFixedIPs:
64 Control the IP allocation for the PublicVirtualInterface port. E.g.
65 [{'ip_address':'1.2.3.4'}]
70 description: Salt for the rabbit cookie, change this to force the randomly generated rabbit cookie to change.
71 StorageVirtualFixedIPs:
74 Control the IP allocation for the StorageVirtualInterface port. E.g.
75 [{'ip_address':'1.2.3.4'}]
77 StorageMgmtVirtualFixedIPs:
80 Control the IP allocation for the StorageMgmgVirtualInterface port. E.g.
81 [{'ip_address':'1.2.3.4'}]
86 Control the IP allocation for the virtual IP used by Redis. E.g.
87 [{'ip_address':'1.2.3.4'}]
90 default: 'localdomain'
93 The DNS domain used for the hosts. This should match the dhcp_domain
94 configured in the Undercloud neutron. Defaults to localdomain.
98 Extra properties or metadata passed to Nova for the created nodes in
99 the overcloud. It's accessible via the Nova metadata API.
102 # Compute-specific params
103 # FIXME(shardy) handle these deprecated names as they don't match compute.yaml
104 HypervisorNeutronPhysicalBridge:
107 An OVS bridge to create on each hypervisor. This defaults to br-ex the
108 same as the control plane nodes, as we have a uniform configuration of
109 the openvswitch agent. Typically should not need to be changed.
111 HypervisorNeutronPublicInterface:
113 description: What interface to add to the HypervisorNeutronPhysicalBridge.
116 # Jinja loop for Role in role_data.yaml
117 {% for role in roles %}
118 # Parameters generated for {{role.name}} Role
119 {{role.name}}Services:
120 description: A list of service resources (configured in the Heat
121 resource_registry) which represent nested stacks
122 for each service that should get installed on the {{role.name}} role.
123 type: comma_delimited_list
124 default: {{role.ServicesDefault|default([])}}
127 description: Number of {{role.name}} nodes to deploy
129 default: {{role.CountDefault|default(0)}}
131 {{role.name}}HostnameFormat:
134 Format for {{role.name}} node hostnames
135 Note %index% is translated into the index of the node, e.g 0/1/2 etc
136 and %stackname% is replaced with the stack name e.g overcloud
137 {% if role.HostnameFormatDefault %}
138 default: "{{role.HostnameFormatDefault}}"
140 default: "%stackname%-{{role.name.lower()}}-%index%"
143 {{role.name}}RemovalPolicies:
147 List of resources to be removed from {{role.name}} ResourceGroup when
148 doing an update which requires removal of specific resources.
149 Example format ComputeRemovalPolicies: [{'resource_list': ['0']}]
151 {% if role.name != 'Compute' %}
152 {{role.name}}SchedulerHints:
154 NovaComputeSchedulerHints:
157 description: Optional scheduler hints to pass to nova
161 # Identifiers to trigger tasks on nodes
166 Setting to a previously unused value during stack-update will trigger
167 package update on all nodes
172 Setting this to a unique value will re-run any deployment tasks which
173 perform configuration on a Heat stack-update.
177 HeatAuthEncryptionKey:
178 type: OS::Heat::RandomString
181 type: OS::Heat::RandomString
186 type: OS::Heat::RandomString
191 type: OS::TripleO::ServiceNetMap
194 type: OS::TripleO::EndpointMap
197 external: {get_param: CloudName}
198 internal_api: {get_param: CloudNameInternal}
199 storage: {get_param: CloudNameStorage}
200 storage_mgmt: {get_param: CloudNameStorageManagement}
201 ctlplane: {get_param: CloudNameCtlplane}
202 NetIpMap: {get_attr: [VipMap, net_ip_map]}
203 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
205 # Jinja loop for Role in roles_data.yaml
206 {% for role in roles %}
207 # Resources generated for {{role.name}} Role
208 {{role.name}}ServiceChain:
209 type: OS::TripleO::Services
212 get_param: {{role.name}}Services
213 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
214 EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
215 DefaultPasswords: {get_attr: [DefaultPasswords, passwords]}
217 {{role.name}}HostsDeployment:
218 type: OS::Heat::StructuredDeployments
220 name: {{role.name}}HostsDeployment
221 config: {get_attr: [hostsConfig, config_id]}
222 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
224 {{role.name}}AllNodesDeployment:
225 type: OS::Heat::StructuredDeployments
227 {% for role_inner in roles %}
228 - {{role_inner.name}}HostsDeployment
231 name: {{role.name}}AllNodesDeployment
232 config: {get_attr: [allNodesConfig, config_id]}
233 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
235 bootstrap_nodeid: {get_attr: [{{role.name}}, resource.0.hostname]}
236 bootstrap_nodeid_ip: {get_attr: [{{role.name}}, resource.0.ip_address]}
238 {{role.name}}AllNodesValidationDeployment:
239 type: OS::Heat::StructuredDeployments
240 depends_on: {{role.name}}AllNodesDeployment
242 name: {{role.name}}AllNodesValidationDeployment
243 config: {get_resource: AllNodesValidationConfig}
244 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
246 {{role.name}}IpListMap:
247 type: OS::TripleO::Network::Ports::NetIpListMap
249 ControlPlaneIpList: {get_attr: [{{role.name}}, ip_address]}
250 ExternalIpList: {get_attr: [{{role.name}}, external_ip_address]}
251 InternalApiIpList: {get_attr: [{{role.name}}, internal_api_ip_address]}
252 StorageIpList: {get_attr: [{{role.name}}, storage_ip_address]}
253 StorageMgmtIpList: {get_attr: [{{role.name}}, storage_mgmt_ip_address]}
254 TenantIpList: {get_attr: [{{role.name}}, tenant_ip_address]}
255 ManagementIpList: {get_attr: [{{role.name}}, management_ip_address]}
256 EnabledServices: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
257 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
258 ServiceHostnameList: {get_attr: [{{role.name}}, hostname]}
260 # Note (shardy) this somewhat complex yaql may be replaced
261 # with a map_deep_merge function in ocata. It merges the
262 # list of maps, but appends to colliding lists so we can
263 # create a map of lists for all nodes for each network
265 expression: dict($.data.where($ != null).flatten().selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
267 - {get_attr: [{{role.name}}, hostname_map]}
270 type: OS::Heat::ResourceGroup
273 count: {get_param: {{role.name}}Count}
274 removal_policies: {get_param: {{role.name}}RemovalPolicies}
276 type: OS::TripleO::{{role.name}}
278 CloudDomain: {get_param: CloudDomain}
279 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
280 EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
283 template: {get_param: {{role.name}}HostnameFormat}
285 '%stackname%': {get_param: 'OS::stack_name'}
287 {% if role.name != 'Compute' %}
288 {{role.name}}SchedulerHints: {get_param: {{role.name}}SchedulerHints}
290 NovaComputeSchedulerHints: {get_param: NovaComputeSchedulerHints}
292 ServiceConfigSettings:
294 - get_attr: [{{role.name}}ServiceChain, role_data, config_settings]
296 - get_attr: [{{r.name}}ServiceChain, role_data, global_config_settings]
298 # This next step combines two yaql passes:
299 # - The inner one does a deep merge on the service_config_settings for all roles
300 # - The outer one filters the map based on the services enabled for the role
301 # then merges the result into one map.
303 expression: let(root => $) -> $.data.map.items().where($[0] in $root.data.services).select($[1]).reduce($1.mergeWith($2), {})
307 expression: $.data.where($ != null).reduce($1.mergeWith($2), {})
310 - get_attr: [{{r.name}}ServiceChain, role_data, service_config_settings]
312 services: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
313 ServiceNames: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
314 MonitoringSubscriptions: {get_attr: [{{role.name}}ServiceChain, role_data, monitoring_subscriptions]}
318 type: OS::TripleO::Hosts::SoftwareConfig
321 {% for role in roles %}
324 - {get_attr: [{{role.name}}, hosts_entry]}
328 type: OS::TripleO::AllNodes::SoftwareConfig
330 cloud_name_external: {get_param: CloudName}
331 cloud_name_internal_api: {get_param: CloudNameInternal}
332 cloud_name_storage: {get_param: CloudNameStorage}
333 cloud_name_storage_mgmt: {get_param: CloudNameStorageManagement}
334 cloud_name_ctlplane: {get_param: CloudNameCtlplane}
338 {% for role in roles %}
339 - {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
344 $.data.groups.flatten()
347 {% for role in roles %}
348 - {get_attr: [{{role.name}}ServiceChain, role_data, logging_groups]}
353 $.data.sources.flatten()
356 {% for role in roles %}
357 - {get_attr: [{{role.name}}ServiceChain, role_data, logging_sources]}
359 controller_ips: {get_attr: [Controller, ip_address]}
360 controller_names: {get_attr: [Controller, hostname]}
362 # Note (shardy) this somewhat complex yaql may be replaced
363 # with a map_deep_merge function in ocata. It merges the
364 # list of maps, but appends to colliding lists when a service
365 # is deployed on more than one role
367 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
370 {% for role in roles %}
371 - {get_attr: [{{role.name}}IpListMap, service_ips]}
375 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
378 {% for role in roles %}
379 - {get_attr: [{{role.name}}IpListMap, service_hostnames]}
381 short_service_node_names:
383 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
386 {% for role in roles %}
387 - {get_attr: [{{role.name}}IpListMap, short_service_hostnames]}
389 # FIXME(shardy): These require further work to move into service_ips
390 memcache_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, MemcachedNetwork]}]}
391 NetVipMap: {get_attr: [VipMap, net_ip_map]}
392 RedisVirtualIP: {get_attr: [RedisVirtualIP, ip_address]}
393 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
394 DeployIdentifier: {get_param: DeployIdentifier}
395 UpdateIdentifier: {get_param: UpdateIdentifier}
398 type: OS::Heat::RandomString
403 type: OS::Heat::RandomString
406 salt: {get_param: RabbitCookieSalt}
409 type: OS::TripleO::DefaultPasswords
411 DefaultMysqlRootPassword: {get_attr: [MysqlRootPassword, value]}
412 DefaultRabbitCookie: {get_attr: [RabbitCookie, value]}
413 DefaultHeatAuthEncryptionKey: {get_attr: [HeatAuthEncryptionKey, value]}
414 DefaultPcsdPassword: {get_attr: [PcsdPassword, value]}
415 DefaultHorizonSecret: {get_attr: [HorizonSecret, value]}
417 # creates the network architecture
419 type: OS::TripleO::Network
422 type: OS::Neutron::Port
425 name: control_virtual_ip
426 network: {get_param: NeutronControlPlaneID}
427 fixed_ips: {get_param: ControlFixedIPs}
428 replacement_policy: AUTO
432 type: OS::TripleO::Network::Ports::RedisVipPort
434 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
435 ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
436 PortName: redis_virtual_ip
437 NetworkName: {get_attr: [ServiceNetMap, service_net_map, RedisNetwork]}
439 FixedIPs: {get_param: RedisVirtualFixedIPs}
441 # The public VIP is on the External net, falls back to ctlplane
444 type: OS::TripleO::Network::Ports::ExternalVipPort
446 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
447 ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
448 PortName: public_virtual_ip
449 FixedIPs: {get_param: PublicVirtualFixedIPs}
451 InternalApiVirtualIP:
453 type: OS::TripleO::Network::Ports::InternalApiVipPort
455 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
456 PortName: internal_api_virtual_ip
457 FixedIPs: {get_param: InternalApiVirtualFixedIPs}
461 type: OS::TripleO::Network::Ports::StorageVipPort
463 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
464 PortName: storage_virtual_ip
465 FixedIPs: {get_param: StorageVirtualFixedIPs}
467 StorageMgmtVirtualIP:
469 type: OS::TripleO::Network::Ports::StorageMgmtVipPort
471 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
472 PortName: storage_management_virtual_ip
473 FixedIPs: {get_param: StorageMgmtVirtualFixedIPs}
476 type: OS::TripleO::Network::Ports::NetVipMap
478 ControlPlaneIp: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
479 ExternalIp: {get_attr: [PublicVirtualIP, ip_address]}
480 ExternalIpUri: {get_attr: [PublicVirtualIP, ip_address_uri]}
481 InternalApiIp: {get_attr: [InternalApiVirtualIP, ip_address]}
482 InternalApiIpUri: {get_attr: [InternalApiVirtualIP, ip_address_uri]}
483 StorageIp: {get_attr: [StorageVirtualIP, ip_address]}
484 StorageIpUri: {get_attr: [StorageVirtualIP, ip_address_uri]}
485 StorageMgmtIp: {get_attr: [StorageMgmtVirtualIP, ip_address]}
486 StorageMgmtIpUri: {get_attr: [StorageMgmtVirtualIP, ip_address_uri]}
487 # No tenant or management VIP required
489 # All Nodes Validations
490 AllNodesValidationConfig:
491 type: OS::TripleO::AllNodes::Validation
496 - - {get_attr: [Controller, resource.0.external_ip_address]}
497 - {get_attr: [Controller, resource.0.internal_api_ip_address]}
498 - {get_attr: [Controller, resource.0.storage_ip_address]}
499 - {get_attr: [Controller, resource.0.storage_mgmt_ip_address]}
500 - {get_attr: [Controller, resource.0.tenant_ip_address]}
501 - {get_attr: [Controller, resource.0.management_ip_address]}
504 type: OS::TripleO::Tasks::UpdateWorkflow
506 {% for role in roles %}
507 - {{role.name}}AllNodesDeployment
511 {% for role in roles %}
512 {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
515 deploy_identifier: {get_param: DeployIdentifier}
516 update_identifier: {get_param: UpdateIdentifier}
518 # Optional ExtraConfig for all nodes - all roles are passed in here, but
519 # the nested template may configure each role differently (or not at all)
521 type: OS::TripleO::AllNodesExtraConfig
524 {% for role in roles %}
525 - {{role.name}}AllNodesValidationDeployment
528 {% for role in roles %}
529 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
532 # Post deployment steps for all roles
534 type: OS::TripleO::PostDeploySteps
535 {% for role in roles %}
537 - {{role.name}}AllNodesDeployment
541 {% for role in roles %}
542 {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
545 {% for role in roles %}
546 {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data]}
551 description: Asserts that the keystone endpoints have been provisioned.
554 description: URL for the Overcloud Keystone service
555 value: {get_attr: [EndpointMap, endpoint_map, KeystonePublic, uri]}
557 description: Keystone Admin VIP endpoint
558 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystoneAdminApiNetwork]}]}
560 description: Controller VIP for public API endpoints
561 value: {get_attr: [VipMap, net_ip_map, external]}
563 description: VIP for Aodh API internal endpoint
564 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, AodhApiNetwork]}]}
565 CeilometerInternalVip:
566 description: VIP for Ceilometer API internal endpoint
567 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CeilometerApiNetwork]}]}
569 description: VIP for Ceph RGW internal endpoint
570 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CephRgwNetwork]}]}
572 description: VIP for Cinder API internal endpoint
573 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CinderApiNetwork]}]}
575 description: VIP for Glance API internal endpoint
576 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, GlanceApiNetwork]}]}
578 description: VIP for Gnocchi API internal endpoint
579 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, GnocchiApiNetwork]}]}
581 description: VIP for Heat API internal endpoint
582 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, HeatApiNetwork]}]}
584 description: VIP for Ironic API internal endpoint
585 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, IronicApiNetwork]}]}
587 description: VIP for Keystone API internal endpoint
588 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystonePublicApiNetwork]}]}
590 description: VIP for Manila API internal endpoint
591 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, ManilaApiNetwork]}]}
593 description: VIP for Neutron API internal endpoint
594 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, NeutronApiNetwork]}]}
596 description: VIP for Nova API internal endpoint
597 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, NovaApiNetwork]}]}
598 OpenDaylightInternalVip:
599 description: VIP for OpenDaylight API internal endpoint
600 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, OpenDaylightApiNetwork]}]}
602 description: VIP for Sahara API internal endpoint
603 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, SaharaApiNetwork]}]}
605 description: VIP for Swift Proxy internal endpoint
606 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, SwiftProxyNetwork]}]}
609 Mapping of the resources with the needed info for their endpoints.
610 This includes the protocol used, the IP, port and also a full
611 representation of the URI.
612 value: {get_attr: [EndpointMap, endpoint_map]}
615 The content that should be appended to your /etc/hosts if you want to get
616 hostname-based access to the deployed nodes (useful for testing without
621 - - {get_attr: [hostsConfig, hosts_entries]}
626 IP: {get_attr: [VipMap, net_ip_map, external]}
627 HOST: {get_param: CloudName}
631 IP: {get_attr: [VipMap, net_ip_map, ctlplane]}
632 HOST: {get_param: CloudNameCtlplane}
636 IP: {get_attr: [VipMap, net_ip_map, internal_api]}
637 HOST: {get_param: CloudNameInternal}
641 IP: {get_attr: [VipMap, net_ip_map, storage]}
642 HOST: {get_param: CloudNameStorage}
646 IP: {get_attr: [VipMap, net_ip_map, storage_mgmt]}
647 HOST: {get_param: CloudNameStorageManagement}
649 description: The services enabled on each role
651 {% for role in roles %}
652 {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}