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
126 description: Number of {{role.name}} nodes to deploy
128 default: {{role.CountDefault|default(0)}}
130 {{role.name}}HostnameFormat:
133 Format for {{role.name}} node hostnames
134 Note %index% is translated into the index of the node, e.g 0/1/2 etc
135 and %stackname% is replaced with the stack name e.g overcloud
136 {% if role.HostnameFormatDefault %}
137 default: "{{role.HostnameFormatDefault}}"
139 default: "%stackname%-{{role.name.lower()}}-%index%"
142 {{role.name}}RemovalPolicies:
146 List of resources to be removed from {{role.name}} ResourceGroup when
147 doing an update which requires removal of specific resources.
148 Example format ComputeRemovalPolicies: [{'resource_list': ['0']}]
150 {% if role.name != 'Compute' %}
151 {{role.name}}SchedulerHints:
153 NovaComputeSchedulerHints:
156 description: Optional scheduler hints to pass to nova
160 # Identifiers to trigger tasks on nodes
165 Setting to a previously unused value during stack-update will trigger
166 package update on all nodes
171 Setting this to a unique value will re-run any deployment tasks which
172 perform configuration on a Heat stack-update.
176 HeatAuthEncryptionKey:
177 type: OS::Heat::RandomString
180 type: OS::Heat::RandomString
185 type: OS::Heat::RandomString
190 type: OS::TripleO::ServiceNetMap
193 type: OS::TripleO::EndpointMap
196 external: {get_param: CloudName}
197 internal_api: {get_param: CloudNameInternal}
198 storage: {get_param: CloudNameStorage}
199 storage_mgmt: {get_param: CloudNameStorageManagement}
200 ctlplane: {get_param: CloudNameCtlplane}
201 NetIpMap: {get_attr: [VipMap, net_ip_map]}
202 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
204 # Jinja loop for Role in roles_data.yaml
205 {% for role in roles %}
206 # Resources generated for {{role.name}} Role
207 {{role.name}}ServiceChain:
208 type: OS::TripleO::Services
211 get_param: {{role.name}}Services
212 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
213 EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
214 DefaultPasswords: {get_attr: [DefaultPasswords, passwords]}
216 {{role.name}}HostsDeployment:
217 type: OS::Heat::StructuredDeployments
219 name: {{role.name}}HostsDeployment
220 config: {get_attr: [hostsConfig, config_id]}
221 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
223 {{role.name}}AllNodesDeployment:
224 type: OS::Heat::StructuredDeployments
226 {% for role_inner in roles %}
227 - {{role_inner.name}}HostsDeployment
230 name: {{role.name}}AllNodesDeployment
231 config: {get_attr: [allNodesConfig, config_id]}
232 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
234 bootstrap_nodeid: {get_attr: [{{role.name}}, resource.0.hostname]}
235 bootstrap_nodeid_ip: {get_attr: [{{role.name}}, resource.0.ip_address]}
237 {{role.name}}AllNodesValidationDeployment:
238 type: OS::Heat::StructuredDeployments
239 depends_on: {{role.name}}AllNodesDeployment
241 name: {{role.name}}AllNodesValidationDeployment
242 config: {get_resource: AllNodesValidationConfig}
243 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
245 {{role.name}}IpListMap:
246 type: OS::TripleO::Network::Ports::NetIpListMap
248 ControlPlaneIpList: {get_attr: [{{role.name}}, ip_address]}
249 ExternalIpList: {get_attr: [{{role.name}}, external_ip_address]}
250 InternalApiIpList: {get_attr: [{{role.name}}, internal_api_ip_address]}
251 StorageIpList: {get_attr: [{{role.name}}, storage_ip_address]}
252 StorageMgmtIpList: {get_attr: [{{role.name}}, storage_mgmt_ip_address]}
253 TenantIpList: {get_attr: [{{role.name}}, tenant_ip_address]}
254 ManagementIpList: {get_attr: [{{role.name}}, management_ip_address]}
255 EnabledServices: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
256 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
257 ServiceHostnameList: {get_attr: [{{role.name}}, hostname]}
259 # Note (shardy) this somewhat complex yaql may be replaced
260 # with a map_deep_merge function in ocata. It merges the
261 # list of maps, but appends to colliding lists so we can
262 # create a map of lists for all nodes for each network
264 expression: dict($.data.where($ != null).flatten().selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
266 - {get_attr: [{{role.name}}, hostname_map]}
269 type: OS::Heat::ResourceGroup
272 count: {get_param: {{role.name}}Count}
273 removal_policies: {get_param: {{role.name}}RemovalPolicies}
275 type: OS::TripleO::{{role.name}}
277 CloudDomain: {get_param: CloudDomain}
278 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
279 EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
282 template: {get_param: {{role.name}}HostnameFormat}
284 '%stackname%': {get_param: 'OS::stack_name'}
286 {% if role.name != 'Compute' %}
287 {{role.name}}SchedulerHints: {get_param: {{role.name}}SchedulerHints}
289 NovaComputeSchedulerHints: {get_param: NovaComputeSchedulerHints}
291 ServiceConfigSettings:
293 - get_attr: [{{role.name}}ServiceChain, role_data, config_settings]
295 - get_attr: [{{r.name}}ServiceChain, role_data, global_config_settings]
297 # This next step combines two yaql passes:
298 # - The inner one does a deep merge on the service_config_settings for all roles
299 # - The outer one filters the map based on the services enabled for the role
300 # then merges the result into one map.
302 expression: let(root => $) -> $.data.map.items().where($[0] in $root.data.services).select($[1]).reduce($1.mergeWith($2), {})
306 expression: $.data.where($ != null).reduce($1.mergeWith($2), {})
309 - get_attr: [{{r.name}}ServiceChain, role_data, service_config_settings]
311 services: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
312 ServiceNames: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
313 MonitoringSubscriptions: {get_attr: [{{role.name}}ServiceChain, role_data, monitoring_subscriptions]}
317 type: OS::TripleO::Hosts::SoftwareConfig
320 {% for role in roles %}
323 - {get_attr: [{{role.name}}, hosts_entry]}
327 type: OS::TripleO::AllNodes::SoftwareConfig
329 cloud_name_external: {get_param: CloudName}
330 cloud_name_internal_api: {get_param: CloudNameInternal}
331 cloud_name_storage: {get_param: CloudNameStorage}
332 cloud_name_storage_mgmt: {get_param: CloudNameStorageManagement}
333 cloud_name_ctlplane: {get_param: CloudNameCtlplane}
337 {% for role in roles %}
338 - {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
343 $.data.groups.flatten()
346 {% for role in roles %}
347 - {get_attr: [{{role.name}}ServiceChain, role_data, logging_groups]}
352 $.data.sources.flatten()
355 {% for role in roles %}
356 - {get_attr: [{{role.name}}ServiceChain, role_data, logging_sources]}
358 controller_ips: {get_attr: [Controller, ip_address]}
359 controller_names: {get_attr: [Controller, hostname]}
361 # Note (shardy) this somewhat complex yaql may be replaced
362 # with a map_deep_merge function in ocata. It merges the
363 # list of maps, but appends to colliding lists when a service
364 # is deployed on more than one role
366 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
369 {% for role in roles %}
370 - {get_attr: [{{role.name}}IpListMap, service_ips]}
374 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
377 {% for role in roles %}
378 - {get_attr: [{{role.name}}IpListMap, service_hostnames]}
380 short_service_node_names:
382 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
385 {% for role in roles %}
386 - {get_attr: [{{role.name}}IpListMap, short_service_hostnames]}
388 # FIXME(shardy): These require further work to move into service_ips
389 memcache_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, MemcachedNetwork]}]}
390 NetVipMap: {get_attr: [VipMap, net_ip_map]}
391 RedisVirtualIP: {get_attr: [RedisVirtualIP, ip_address]}
392 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
393 DeployIdentifier: {get_param: DeployIdentifier}
394 UpdateIdentifier: {get_param: UpdateIdentifier}
397 type: OS::Heat::RandomString
402 type: OS::Heat::RandomString
405 salt: {get_param: RabbitCookieSalt}
408 type: OS::TripleO::DefaultPasswords
410 DefaultMysqlRootPassword: {get_attr: [MysqlRootPassword, value]}
411 DefaultRabbitCookie: {get_attr: [RabbitCookie, value]}
412 DefaultHeatAuthEncryptionKey: {get_attr: [HeatAuthEncryptionKey, value]}
413 DefaultPcsdPassword: {get_attr: [PcsdPassword, value]}
414 DefaultHorizonSecret: {get_attr: [HorizonSecret, value]}
416 # creates the network architecture
418 type: OS::TripleO::Network
421 type: OS::Neutron::Port
424 name: control_virtual_ip
425 network: {get_param: NeutronControlPlaneID}
426 fixed_ips: {get_param: ControlFixedIPs}
427 replacement_policy: AUTO
431 type: OS::TripleO::Network::Ports::RedisVipPort
433 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
434 ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
435 PortName: redis_virtual_ip
436 NetworkName: {get_attr: [ServiceNetMap, service_net_map, RedisNetwork]}
438 FixedIPs: {get_param: RedisVirtualFixedIPs}
440 # The public VIP is on the External net, falls back to ctlplane
443 type: OS::TripleO::Network::Ports::ExternalVipPort
445 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
446 ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
447 PortName: public_virtual_ip
448 FixedIPs: {get_param: PublicVirtualFixedIPs}
450 InternalApiVirtualIP:
452 type: OS::TripleO::Network::Ports::InternalApiVipPort
454 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
455 PortName: internal_api_virtual_ip
456 FixedIPs: {get_param: InternalApiVirtualFixedIPs}
460 type: OS::TripleO::Network::Ports::StorageVipPort
462 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
463 PortName: storage_virtual_ip
464 FixedIPs: {get_param: StorageVirtualFixedIPs}
466 StorageMgmtVirtualIP:
468 type: OS::TripleO::Network::Ports::StorageMgmtVipPort
470 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
471 PortName: storage_management_virtual_ip
472 FixedIPs: {get_param: StorageMgmtVirtualFixedIPs}
475 type: OS::TripleO::Network::Ports::NetVipMap
477 ControlPlaneIp: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
478 ExternalIp: {get_attr: [PublicVirtualIP, ip_address]}
479 ExternalIpUri: {get_attr: [PublicVirtualIP, ip_address_uri]}
480 InternalApiIp: {get_attr: [InternalApiVirtualIP, ip_address]}
481 InternalApiIpUri: {get_attr: [InternalApiVirtualIP, ip_address_uri]}
482 StorageIp: {get_attr: [StorageVirtualIP, ip_address]}
483 StorageIpUri: {get_attr: [StorageVirtualIP, ip_address_uri]}
484 StorageMgmtIp: {get_attr: [StorageMgmtVirtualIP, ip_address]}
485 StorageMgmtIpUri: {get_attr: [StorageMgmtVirtualIP, ip_address_uri]}
486 # No tenant or management VIP required
488 # All Nodes Validations
489 AllNodesValidationConfig:
490 type: OS::TripleO::AllNodes::Validation
495 - - {get_attr: [Controller, resource.0.external_ip_address]}
496 - {get_attr: [Controller, resource.0.internal_api_ip_address]}
497 - {get_attr: [Controller, resource.0.storage_ip_address]}
498 - {get_attr: [Controller, resource.0.storage_mgmt_ip_address]}
499 - {get_attr: [Controller, resource.0.tenant_ip_address]}
500 - {get_attr: [Controller, resource.0.management_ip_address]}
503 type: OS::TripleO::Tasks::UpdateWorkflow
505 {% for role in roles %}
506 - {{role.name}}AllNodesDeployment
510 {% for role in roles %}
511 {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
514 deploy_identifier: {get_param: DeployIdentifier}
515 update_identifier: {get_param: UpdateIdentifier}
517 # Optional ExtraConfig for all nodes - all roles are passed in here, but
518 # the nested template may configure each role differently (or not at all)
520 type: OS::TripleO::AllNodesExtraConfig
523 {% for role in roles %}
524 - {{role.name}}AllNodesValidationDeployment
527 {% for role in roles %}
528 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
531 # Post deployment steps for all roles
533 type: OS::TripleO::PostDeploySteps
534 {% for role in roles %}
536 - {{role.name}}AllNodesDeployment
540 {% for role in roles %}
541 {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
544 {% for role in roles %}
545 {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data]}
550 description: Asserts that the keystone endpoints have been provisioned.
553 description: URL for the Overcloud Keystone service
554 value: {get_attr: [EndpointMap, endpoint_map, KeystonePublic, uri]}
556 description: Keystone Admin VIP endpoint
557 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystoneAdminApiNetwork]}]}
559 description: Controller VIP for public API endpoints
560 value: {get_attr: [VipMap, net_ip_map, external]}
562 description: VIP for Aodh API internal endpoint
563 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, AodhApiNetwork]}]}
565 description: VIP for Barbican API internal endpoint
566 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, BarbicanApiNetwork]}]}
567 CeilometerInternalVip:
568 description: VIP for Ceilometer API internal endpoint
569 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CeilometerApiNetwork]}]}
571 description: VIP for Ceph RGW internal endpoint
572 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CephRgwNetwork]}]}
574 description: VIP for Cinder API internal endpoint
575 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CinderApiNetwork]}]}
577 description: VIP for Glance API internal endpoint
578 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, GlanceApiNetwork]}]}
580 description: VIP for Gnocchi API internal endpoint
581 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, GnocchiApiNetwork]}]}
583 description: VIP for Mistral API internal endpoint
584 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, MistralApiNetwork]}]}
586 description: VIP for Heat API internal endpoint
587 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, HeatApiNetwork]}]}
589 description: VIP for Ironic API internal endpoint
590 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, IronicApiNetwork]}]}
592 description: VIP for Keystone API internal endpoint
593 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystonePublicApiNetwork]}]}
595 description: VIP for Manila API internal endpoint
596 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, ManilaApiNetwork]}]}
598 description: VIP for Neutron API internal endpoint
599 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, NeutronApiNetwork]}]}
601 description: VIP for Nova API internal endpoint
602 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, NovaApiNetwork]}]}
603 OpenDaylightInternalVip:
604 description: VIP for OpenDaylight API internal endpoint
605 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, OpenDaylightApiNetwork]}]}
607 description: VIP for Sahara API internal endpoint
608 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, SaharaApiNetwork]}]}
610 description: VIP for Swift Proxy internal endpoint
611 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, SwiftProxyNetwork]}]}
614 Mapping of the resources with the needed info for their endpoints.
615 This includes the protocol used, the IP, port and also a full
616 representation of the URI.
617 value: {get_attr: [EndpointMap, endpoint_map]}
620 The content that should be appended to your /etc/hosts if you want to get
621 hostname-based access to the deployed nodes (useful for testing without
626 - - {get_attr: [hostsConfig, hosts_entries]}
631 IP: {get_attr: [VipMap, net_ip_map, external]}
632 HOST: {get_param: CloudName}
636 IP: {get_attr: [VipMap, net_ip_map, ctlplane]}
637 HOST: {get_param: CloudNameCtlplane}
641 IP: {get_attr: [VipMap, net_ip_map, internal_api]}
642 HOST: {get_param: CloudNameInternal}
646 IP: {get_attr: [VipMap, net_ip_map, storage]}
647 HOST: {get_param: CloudNameStorage}
651 IP: {get_attr: [VipMap, net_ip_map, storage_mgmt]}
652 HOST: {get_param: CloudNameStorageManagement}
654 description: The services enabled on each role
656 {% for role in roles %}
657 {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}