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}}AllNodesDeployment:
218 type: OS::Heat::StructuredDeployments
220 name: {{role.name}}AllNodesDeployment
221 config: {get_attr: [allNodesConfig, config_id]}
222 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
224 bootstrap_nodeid: {get_attr: [{{role.name}}, resource.0.hostname]}
225 bootstrap_nodeid_ip: {get_attr: [{{role.name}}, resource.0.ip_address]}
227 {{role.name}}AllNodesValidationDeployment:
228 type: OS::Heat::StructuredDeployments
229 depends_on: {{role.name}}AllNodesDeployment
231 name: {{role.name}}AllNodesValidationDeployment
232 config: {get_resource: AllNodesValidationConfig}
233 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
235 {{role.name}}IpListMap:
236 type: OS::TripleO::Network::Ports::NetIpListMap
238 ControlPlaneIpList: {get_attr: [{{role.name}}, ip_address]}
239 ExternalIpList: {get_attr: [{{role.name}}, external_ip_address]}
240 InternalApiIpList: {get_attr: [{{role.name}}, internal_api_ip_address]}
241 StorageIpList: {get_attr: [{{role.name}}, storage_ip_address]}
242 StorageMgmtIpList: {get_attr: [{{role.name}}, storage_mgmt_ip_address]}
243 TenantIpList: {get_attr: [{{role.name}}, tenant_ip_address]}
244 ManagementIpList: {get_attr: [{{role.name}}, management_ip_address]}
245 EnabledServices: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
246 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
247 ServiceHostnameList: {get_attr: [{{role.name}}, hostname]}
249 # Note (shardy) this somewhat complex yaql may be replaced
250 # with a map_deep_merge function in ocata. It merges the
251 # list of maps, but appends to colliding lists so we can
252 # create a map of lists for all nodes for each network
254 expression: dict($.data.where($ != null).flatten().selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
256 - {get_attr: [{{role.name}}, hostname_map]}
259 type: OS::Heat::ResourceGroup
262 count: {get_param: {{role.name}}Count}
263 removal_policies: {get_param: {{role.name}}RemovalPolicies}
265 type: OS::TripleO::{{role.name}}
267 CloudDomain: {get_param: CloudDomain}
268 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
269 EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
272 template: {get_param: {{role.name}}HostnameFormat}
274 '%stackname%': {get_param: 'OS::stack_name'}
276 {% if role.name != 'Compute' %}
277 {{role.name}}SchedulerHints: {get_param: {{role.name}}SchedulerHints}
279 NovaComputeSchedulerHints: {get_param: NovaComputeSchedulerHints}
281 ServiceConfigSettings:
283 - get_attr: [{{role.name}}ServiceChain, role_data, config_settings]
285 - get_attr: [{{r.name}}ServiceChain, role_data, global_config_settings]
287 # This next step combines two yaql passes:
288 # - The inner one does a deep merge on the service_config_settings for all roles
289 # - The outer one filters the map based on the services enabled for the role
290 # then merges the result into one map.
292 expression: let(root => $) -> $.data.map.items().where($[0] in $root.data.services).select($[1]).reduce($1.mergeWith($2), {})
296 expression: $.data.where($ != null).reduce($1.mergeWith($2), {})
299 - get_attr: [{{r.name}}ServiceChain, role_data, service_config_settings]
301 services: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
302 ServiceNames: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
303 MonitoringSubscriptions: {get_attr: [{{role.name}}ServiceChain, role_data, monitoring_subscriptions]}
307 type: OS::TripleO::AllNodes::SoftwareConfig
309 cloud_name_external: {get_param: CloudName}
310 cloud_name_internal_api: {get_param: CloudNameInternal}
311 cloud_name_storage: {get_param: CloudNameStorage}
312 cloud_name_storage_mgmt: {get_param: CloudNameStorageManagement}
313 cloud_name_ctlplane: {get_param: CloudNameCtlplane}
315 {% for role in roles %}
318 - {get_attr: [{{role.name}}, hosts_entry]}
323 {% for role in roles %}
324 - {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
329 $.data.groups.flatten()
332 {% for role in roles %}
333 - {get_attr: [{{role.name}}ServiceChain, role_data, logging_groups]}
338 $.data.sources.flatten()
341 {% for role in roles %}
342 - {get_attr: [{{role.name}}ServiceChain, role_data, logging_sources]}
344 controller_ips: {get_attr: [Controller, ip_address]}
345 controller_names: {get_attr: [Controller, hostname]}
347 # Note (shardy) this somewhat complex yaql may be replaced
348 # with a map_deep_merge function in ocata. It merges the
349 # list of maps, but appends to colliding lists when a service
350 # is deployed on more than one role
352 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
355 {% for role in roles %}
356 - {get_attr: [{{role.name}}IpListMap, service_ips]}
360 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
363 {% for role in roles %}
364 - {get_attr: [{{role.name}}IpListMap, service_hostnames]}
366 short_service_node_names:
368 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
371 {% for role in roles %}
372 - {get_attr: [{{role.name}}IpListMap, short_service_hostnames]}
374 # FIXME(shardy): These require further work to move into service_ips
375 memcache_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, MemcachedNetwork]}]}
376 NetVipMap: {get_attr: [VipMap, net_ip_map]}
377 RedisVirtualIP: {get_attr: [RedisVirtualIP, ip_address]}
378 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
379 DeployIdentifier: {get_param: DeployIdentifier}
380 UpdateIdentifier: {get_param: UpdateIdentifier}
383 type: OS::Heat::RandomString
388 type: OS::Heat::RandomString
391 salt: {get_param: RabbitCookieSalt}
394 type: OS::TripleO::DefaultPasswords
396 DefaultMysqlRootPassword: {get_attr: [MysqlRootPassword, value]}
397 DefaultRabbitCookie: {get_attr: [RabbitCookie, value]}
398 DefaultHeatAuthEncryptionKey: {get_attr: [HeatAuthEncryptionKey, value]}
399 DefaultPcsdPassword: {get_attr: [PcsdPassword, value]}
400 DefaultHorizonSecret: {get_attr: [HorizonSecret, value]}
402 # creates the network architecture
404 type: OS::TripleO::Network
407 type: OS::Neutron::Port
410 name: control_virtual_ip
411 network: {get_param: NeutronControlPlaneID}
412 fixed_ips: {get_param: ControlFixedIPs}
413 replacement_policy: AUTO
417 type: OS::TripleO::Network::Ports::RedisVipPort
419 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
420 ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
421 PortName: redis_virtual_ip
422 NetworkName: {get_attr: [ServiceNetMap, service_net_map, RedisNetwork]}
424 FixedIPs: {get_param: RedisVirtualFixedIPs}
426 # The public VIP is on the External net, falls back to ctlplane
429 type: OS::TripleO::Network::Ports::ExternalVipPort
431 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
432 ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
433 PortName: public_virtual_ip
434 FixedIPs: {get_param: PublicVirtualFixedIPs}
436 InternalApiVirtualIP:
438 type: OS::TripleO::Network::Ports::InternalApiVipPort
440 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
441 PortName: internal_api_virtual_ip
442 FixedIPs: {get_param: InternalApiVirtualFixedIPs}
446 type: OS::TripleO::Network::Ports::StorageVipPort
448 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
449 PortName: storage_virtual_ip
450 FixedIPs: {get_param: StorageVirtualFixedIPs}
452 StorageMgmtVirtualIP:
454 type: OS::TripleO::Network::Ports::StorageMgmtVipPort
456 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
457 PortName: storage_management_virtual_ip
458 FixedIPs: {get_param: StorageMgmtVirtualFixedIPs}
461 type: OS::TripleO::Network::Ports::NetVipMap
463 ControlPlaneIp: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
464 ExternalIp: {get_attr: [PublicVirtualIP, ip_address]}
465 ExternalIpUri: {get_attr: [PublicVirtualIP, ip_address_uri]}
466 InternalApiIp: {get_attr: [InternalApiVirtualIP, ip_address]}
467 InternalApiIpUri: {get_attr: [InternalApiVirtualIP, ip_address_uri]}
468 StorageIp: {get_attr: [StorageVirtualIP, ip_address]}
469 StorageIpUri: {get_attr: [StorageVirtualIP, ip_address_uri]}
470 StorageMgmtIp: {get_attr: [StorageMgmtVirtualIP, ip_address]}
471 StorageMgmtIpUri: {get_attr: [StorageMgmtVirtualIP, ip_address_uri]}
472 # No tenant or management VIP required
474 # All Nodes Validations
475 AllNodesValidationConfig:
476 type: OS::TripleO::AllNodes::Validation
481 - - {get_attr: [Controller, resource.0.external_ip_address]}
482 - {get_attr: [Controller, resource.0.internal_api_ip_address]}
483 - {get_attr: [Controller, resource.0.storage_ip_address]}
484 - {get_attr: [Controller, resource.0.storage_mgmt_ip_address]}
485 - {get_attr: [Controller, resource.0.tenant_ip_address]}
486 - {get_attr: [Controller, resource.0.management_ip_address]}
489 type: OS::TripleO::Tasks::UpdateWorkflow
491 {% for role in roles %}
492 - {{role.name}}AllNodesDeployment
496 {% for role in roles %}
497 {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
500 deploy_identifier: {get_param: DeployIdentifier}
501 update_identifier: {get_param: UpdateIdentifier}
503 # Optional ExtraConfig for all nodes - all roles are passed in here, but
504 # the nested template may configure each role differently (or not at all)
506 type: OS::TripleO::AllNodesExtraConfig
509 {% for role in roles %}
510 - {{role.name}}AllNodesValidationDeployment
513 {% for role in roles %}
514 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
517 # Post deployment steps for all roles
519 type: OS::TripleO::PostDeploySteps
522 {% for role in roles %}
523 {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
526 {% for role in roles %}
527 {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data]}
532 description: Asserts that the keystone endpoints have been provisioned.
535 description: URL for the Overcloud Keystone service
536 value: {get_attr: [EndpointMap, endpoint_map, KeystonePublic, uri]}
538 description: Keystone Admin VIP endpoint
539 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystoneAdminApiNetwork]}]}
541 description: Controller VIP for public API endpoints
542 value: {get_attr: [VipMap, net_ip_map, external]}
544 description: VIP for Aodh API internal endpoint
545 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, AodhApiNetwork]}]}
546 CeilometerInternalVip:
547 description: VIP for Ceilometer API internal endpoint
548 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CeilometerApiNetwork]}]}
550 description: VIP for Ceph RGW internal endpoint
551 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CephRgwNetwork]}]}
553 description: VIP for Cinder API internal endpoint
554 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CinderApiNetwork]}]}
556 description: VIP for Glance API internal endpoint
557 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, GlanceApiNetwork]}]}
559 description: VIP for Gnocchi API internal endpoint
560 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, GnocchiApiNetwork]}]}
562 description: VIP for Heat API internal endpoint
563 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, HeatApiNetwork]}]}
565 description: VIP for Ironic API internal endpoint
566 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, IronicApiNetwork]}]}
568 description: VIP for Keystone API internal endpoint
569 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystonePublicApiNetwork]}]}
571 description: VIP for Manila API internal endpoint
572 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, ManilaApiNetwork]}]}
574 description: VIP for Neutron API internal endpoint
575 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, NeutronApiNetwork]}]}
577 description: VIP for Nova API internal endpoint
578 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, NovaApiNetwork]}]}
579 OpenDaylightInternalVip:
580 description: VIP for OpenDaylight API internal endpoint
581 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, OpenDaylightApiNetwork]}]}
583 description: VIP for Sahara API internal endpoint
584 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, SaharaApiNetwork]}]}
586 description: VIP for Swift Proxy internal endpoint
587 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, SwiftProxyNetwork]}]}
590 Mapping of the resources with the needed info for their endpoints.
591 This includes the protocol used, the IP, port and also a full
592 representation of the URI.
593 value: {get_attr: [EndpointMap, endpoint_map]}
596 The content that should be appended to your /etc/hosts if you want to get
597 hostname-based access to the deployed nodes (useful for testing without
602 - - {get_attr: [allNodesConfig, hosts_entries]}
607 IP: {get_attr: [VipMap, net_ip_map, external]}
608 HOST: {get_param: CloudName}
612 IP: {get_attr: [VipMap, net_ip_map, ctlplane]}
613 HOST: {get_param: CloudNameCtlplane}
617 IP: {get_attr: [VipMap, net_ip_map, internal_api]}
618 HOST: {get_param: CloudNameInternal}
622 IP: {get_attr: [VipMap, net_ip_map, storage]}
623 HOST: {get_param: CloudNameStorage}
627 IP: {get_attr: [VipMap, net_ip_map, storage_mgmt]}
628 HOST: {get_param: CloudNameStorageManagement}
630 description: The services enabled on each role
632 {% for role in roles %}
633 {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}