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.
177 Set to true to append per network Vips to /etc/hosts on each node.
180 add_vips_to_etc_hosts: {equals : [{get_param: AddVipsToEtcHosts}, True]}
185 type: OS::Heat::Value
194 IP: {get_attr: [VipMap, net_ip_map, external]}
195 HOST: {get_param: CloudName}
199 IP: {get_attr: [VipMap, net_ip_map, ctlplane]}
200 HOST: {get_param: CloudNameCtlplane}
204 IP: {get_attr: [VipMap, net_ip_map, internal_api]}
205 HOST: {get_param: CloudNameInternal}
209 IP: {get_attr: [VipMap, net_ip_map, storage]}
210 HOST: {get_param: CloudNameStorage}
214 IP: {get_attr: [VipMap, net_ip_map, storage_mgmt]}
215 HOST: {get_param: CloudNameStorageManagement}
217 HeatAuthEncryptionKey:
218 type: OS::Heat::RandomString
221 type: OS::Heat::RandomString
226 type: OS::Heat::RandomString
231 type: OS::TripleO::ServiceNetMap
234 type: OS::TripleO::EndpointMap
237 external: {get_param: CloudName}
238 internal_api: {get_param: CloudNameInternal}
239 storage: {get_param: CloudNameStorage}
240 storage_mgmt: {get_param: CloudNameStorageManagement}
241 ctlplane: {get_param: CloudNameCtlplane}
242 NetIpMap: {get_attr: [VipMap, net_ip_map]}
243 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
245 # Jinja loop for Role in roles_data.yaml
246 {% for role in roles %}
247 # Resources generated for {{role.name}} Role
248 {{role.name}}ServiceChain:
249 type: OS::TripleO::Services
252 get_param: {{role.name}}Services
253 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
254 EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
255 DefaultPasswords: {get_attr: [DefaultPasswords, passwords]}
257 {{role.name}}HostsDeployment:
258 type: OS::Heat::StructuredDeployments
260 name: {{role.name}}HostsDeployment
261 config: {get_attr: [hostsConfig, config_id]}
262 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
264 {{role.name}}AllNodesDeployment:
265 type: OS::Heat::StructuredDeployments
267 {% for role_inner in roles %}
268 - {{role_inner.name}}HostsDeployment
271 name: {{role.name}}AllNodesDeployment
272 config: {get_attr: [allNodesConfig, config_id]}
273 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
275 # Note we have to use yaql to look up the first hostname/ip in the
276 # list because heat path based attributes operate on the attribute
277 # inside the ResourceGroup, not the exposed list ref discussion in
278 # https://bugs.launchpad.net/heat/+bug/1640488
279 # The coalesce is needed because $.data is None during heat validation
282 expression: coalesce($.data, []).first(null)
283 data: {get_attr: [{{role.name}}, hostname]}
286 expression: coalesce($.data, []).first(null)
287 data: {get_attr: [{{role.name}}, ip_address]}
289 {{role.name}}AllNodesValidationDeployment:
290 type: OS::Heat::StructuredDeployments
291 depends_on: {{role.name}}AllNodesDeployment
293 name: {{role.name}}AllNodesValidationDeployment
294 config: {get_resource: AllNodesValidationConfig}
295 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
297 {{role.name}}IpListMap:
298 type: OS::TripleO::Network::Ports::NetIpListMap
300 ControlPlaneIpList: {get_attr: [{{role.name}}, ip_address]}
301 ExternalIpList: {get_attr: [{{role.name}}, external_ip_address]}
302 InternalApiIpList: {get_attr: [{{role.name}}, internal_api_ip_address]}
303 StorageIpList: {get_attr: [{{role.name}}, storage_ip_address]}
304 StorageMgmtIpList: {get_attr: [{{role.name}}, storage_mgmt_ip_address]}
305 TenantIpList: {get_attr: [{{role.name}}, tenant_ip_address]}
306 ManagementIpList: {get_attr: [{{role.name}}, management_ip_address]}
307 EnabledServices: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
308 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
309 ServiceHostnameList: {get_attr: [{{role.name}}, hostname]}
311 # Note (shardy) this somewhat complex yaql may be replaced
312 # with a map_deep_merge function in ocata. It merges the
313 # list of maps, but appends to colliding lists so we can
314 # create a map of lists for all nodes for each network
316 expression: dict($.data.where($ != null).flatten().selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
318 - {get_attr: [{{role.name}}, hostname_map]}
321 type: OS::Heat::ResourceGroup
324 count: {get_param: {{role.name}}Count}
325 removal_policies: {get_param: {{role.name}}RemovalPolicies}
327 type: OS::TripleO::{{role.name}}
329 CloudDomain: {get_param: CloudDomain}
330 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
331 EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
334 template: {get_param: {{role.name}}HostnameFormat}
336 '%stackname%': {get_param: 'OS::stack_name'}
338 {% if role.name != 'Compute' %}
339 {{role.name}}SchedulerHints: {get_param: {{role.name}}SchedulerHints}
341 NovaComputeSchedulerHints: {get_param: NovaComputeSchedulerHints}
343 ServiceConfigSettings:
345 - get_attr: [{{role.name}}ServiceChain, role_data, config_settings]
347 - get_attr: [{{r.name}}ServiceChain, role_data, global_config_settings]
349 # This next step combines two yaql passes:
350 # - The inner one does a deep merge on the service_config_settings for all roles
351 # - The outer one filters the map based on the services enabled for the role
352 # then merges the result into one map.
354 expression: let(root => $) -> $.data.map.items().where($[0] in coalesce($root.data.services, [])).select($[1]).reduce($1.mergeWith($2), {})
358 expression: $.data.where($ != null).reduce($1.mergeWith($2), {})
361 - get_attr: [{{r.name}}ServiceChain, role_data, service_config_settings]
363 services: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
364 ServiceNames: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
365 MonitoringSubscriptions: {get_attr: [{{role.name}}ServiceChain, role_data, monitoring_subscriptions]}
369 type: OS::TripleO::Hosts::SoftwareConfig
375 - add_vips_to_etc_hosts
376 - {get_attr: [VipHosts, value]}
379 {% for role in roles %}
382 - {get_attr: [{{role.name}}, hosts_entry]}
386 type: OS::TripleO::AllNodes::SoftwareConfig
388 cloud_name_external: {get_param: CloudName}
389 cloud_name_internal_api: {get_param: CloudNameInternal}
390 cloud_name_storage: {get_param: CloudNameStorage}
391 cloud_name_storage_mgmt: {get_param: CloudNameStorageManagement}
392 cloud_name_ctlplane: {get_param: CloudNameCtlplane}
396 {% for role in roles %}
397 - {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
402 $.data.groups.flatten()
405 {% for role in roles %}
406 - {get_attr: [{{role.name}}ServiceChain, role_data, logging_groups]}
411 $.data.sources.flatten()
414 {% for role in roles %}
415 - {get_attr: [{{role.name}}ServiceChain, role_data, logging_sources]}
417 controller_ips: {get_attr: [Controller, ip_address]}
418 controller_names: {get_attr: [Controller, hostname]}
420 # Note (shardy) this somewhat complex yaql may be replaced
421 # with a map_deep_merge function in ocata. It merges the
422 # list of maps, but appends to colliding lists when a service
423 # is deployed on more than one role
425 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
428 {% for role in roles %}
429 - {get_attr: [{{role.name}}IpListMap, service_ips]}
433 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
436 {% for role in roles %}
437 - {get_attr: [{{role.name}}IpListMap, service_hostnames]}
439 short_service_node_names:
441 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
444 {% for role in roles %}
445 - {get_attr: [{{role.name}}IpListMap, short_service_hostnames]}
447 # FIXME(shardy): These require further work to move into service_ips
448 memcache_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, MemcachedNetwork]}]}
449 NetVipMap: {get_attr: [VipMap, net_ip_map]}
450 RedisVirtualIP: {get_attr: [RedisVirtualIP, ip_address]}
451 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
452 DeployIdentifier: {get_param: DeployIdentifier}
453 UpdateIdentifier: {get_param: UpdateIdentifier}
456 type: OS::Heat::RandomString
461 type: OS::Heat::RandomString
464 salt: {get_param: RabbitCookieSalt}
467 type: OS::TripleO::DefaultPasswords
469 DefaultMysqlRootPassword: {get_attr: [MysqlRootPassword, value]}
470 DefaultRabbitCookie: {get_attr: [RabbitCookie, value]}
471 DefaultHeatAuthEncryptionKey: {get_attr: [HeatAuthEncryptionKey, value]}
472 DefaultPcsdPassword: {get_attr: [PcsdPassword, value]}
473 DefaultHorizonSecret: {get_attr: [HorizonSecret, value]}
475 # creates the network architecture
477 type: OS::TripleO::Network
480 type: OS::TripleO::Network::Ports::ControlPlaneVipPort
483 name: control_virtual_ip
484 network: {get_param: NeutronControlPlaneID}
485 fixed_ips: {get_param: ControlFixedIPs}
486 replacement_policy: AUTO
490 type: OS::TripleO::Network::Ports::RedisVipPort
492 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
493 ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
494 PortName: redis_virtual_ip
495 NetworkName: {get_attr: [ServiceNetMap, service_net_map, RedisNetwork]}
497 FixedIPs: {get_param: RedisVirtualFixedIPs}
499 # The public VIP is on the External net, falls back to ctlplane
502 type: OS::TripleO::Network::Ports::ExternalVipPort
504 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
505 ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
506 PortName: public_virtual_ip
507 FixedIPs: {get_param: PublicVirtualFixedIPs}
509 InternalApiVirtualIP:
511 type: OS::TripleO::Network::Ports::InternalApiVipPort
513 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
514 PortName: internal_api_virtual_ip
515 FixedIPs: {get_param: InternalApiVirtualFixedIPs}
519 type: OS::TripleO::Network::Ports::StorageVipPort
521 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
522 PortName: storage_virtual_ip
523 FixedIPs: {get_param: StorageVirtualFixedIPs}
525 StorageMgmtVirtualIP:
527 type: OS::TripleO::Network::Ports::StorageMgmtVipPort
529 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
530 PortName: storage_management_virtual_ip
531 FixedIPs: {get_param: StorageMgmtVirtualFixedIPs}
534 type: OS::TripleO::Network::Ports::NetVipMap
536 ControlPlaneIp: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
537 ExternalIp: {get_attr: [PublicVirtualIP, ip_address]}
538 ExternalIpUri: {get_attr: [PublicVirtualIP, ip_address_uri]}
539 InternalApiIp: {get_attr: [InternalApiVirtualIP, ip_address]}
540 InternalApiIpUri: {get_attr: [InternalApiVirtualIP, ip_address_uri]}
541 StorageIp: {get_attr: [StorageVirtualIP, ip_address]}
542 StorageIpUri: {get_attr: [StorageVirtualIP, ip_address_uri]}
543 StorageMgmtIp: {get_attr: [StorageMgmtVirtualIP, ip_address]}
544 StorageMgmtIpUri: {get_attr: [StorageMgmtVirtualIP, ip_address_uri]}
545 # No tenant or management VIP required
547 # All Nodes Validations
548 AllNodesValidationConfig:
549 type: OS::TripleO::AllNodes::Validation
554 - - {get_attr: [Controller, resource.0.external_ip_address]}
555 - {get_attr: [Controller, resource.0.internal_api_ip_address]}
556 - {get_attr: [Controller, resource.0.storage_ip_address]}
557 - {get_attr: [Controller, resource.0.storage_mgmt_ip_address]}
558 - {get_attr: [Controller, resource.0.tenant_ip_address]}
559 - {get_attr: [Controller, resource.0.management_ip_address]}
562 type: OS::TripleO::Tasks::UpdateWorkflow
564 {% for role in roles %}
565 - {{role.name}}AllNodesDeployment
569 {% for role in roles %}
570 {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
573 deploy_identifier: {get_param: DeployIdentifier}
574 update_identifier: {get_param: UpdateIdentifier}
576 # Optional ExtraConfig for all nodes - all roles are passed in here, but
577 # the nested template may configure each role differently (or not at all)
579 type: OS::TripleO::AllNodesExtraConfig
582 {% for role in roles %}
583 - {{role.name}}AllNodesValidationDeployment
586 {% for role in roles %}
587 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
590 # Upgrade steps for all roles
591 AllNodesUpgradeSteps:
592 type: OS::TripleO::UpgradeSteps
594 {% for role in roles %}
595 - {{role.name}}AllNodesDeployment
599 {% for role in roles %}
600 {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
603 {% for role in roles %}
604 {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data]}
607 # Post deployment steps for all roles
609 type: OS::TripleO::PostDeploySteps
610 depends_on: AllNodesUpgradeSteps
613 {% for role in roles %}
614 {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
617 {% for role in roles %}
618 {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data]}
623 description: Asserts that the keystone endpoints have been provisioned.
626 description: URL for the Overcloud Keystone service
627 value: {get_attr: [EndpointMap, endpoint_map, KeystonePublic, uri]}
629 description: Keystone Admin VIP endpoint
630 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystoneAdminApiNetwork]}]}
633 Mapping of the resources with the needed info for their endpoints.
634 This includes the protocol used, the IP, port and also a full
635 representation of the URI.
636 value: {get_attr: [EndpointMap, endpoint_map]}
639 The content that should be appended to your /etc/hosts if you want to get
640 hostname-based access to the deployed nodes (useful for testing without
645 - - {get_attr: [hostsConfig, hosts_entries]}
646 - - {get_attr: [VipHosts, value]}
648 description: The services enabled on each role
650 {% for role in roles %}
651 {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
654 description: The configuration data associated with each role
656 {% for role in roles %}
657 {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data]}