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']}]
152 # Identifiers to trigger tasks on nodes
157 Setting to a previously unused value during stack-update will trigger
158 package update on all nodes
163 Setting this to a unique value will re-run any deployment tasks which
164 perform configuration on a Heat stack-update.
168 HeatAuthEncryptionKey:
169 type: OS::Heat::RandomString
172 type: OS::Heat::RandomString
177 type: OS::Heat::RandomString
182 type: OS::TripleO::ServiceNetMap
185 type: OS::TripleO::EndpointMap
188 external: {get_param: CloudName}
189 internal_api: {get_param: CloudNameInternal}
190 storage: {get_param: CloudNameStorage}
191 storage_mgmt: {get_param: CloudNameStorageManagement}
192 ctlplane: {get_param: CloudNameCtlplane}
193 NetIpMap: {get_attr: [VipMap, net_ip_map]}
194 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
196 # Jinja loop for Role in roles_data.yaml
197 {% for role in roles %}
198 # Resources generated for {{role.name}} Role
199 {{role.name}}ServiceChain:
200 type: OS::TripleO::Services
203 get_param: {{role.name}}Services
204 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
205 EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
206 DefaultPasswords: {get_attr: [DefaultPasswords, passwords]}
208 {{role.name}}AllNodesDeployment:
209 type: OS::Heat::StructuredDeployments
211 name: {{role.name}}AllNodesDeployment
212 config: {get_attr: [allNodesConfig, config_id]}
213 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
215 bootstrap_nodeid: {get_attr: [{{role.name}}, resource.0.hostname]}
216 bootstrap_nodeid_ip: {get_attr: [{{role.name}}, resource.0.ip_address]}
218 {{role.name}}AllNodesValidationDeployment:
219 type: OS::Heat::StructuredDeployments
220 depends_on: {{role.name}}AllNodesDeployment
222 name: {{role.name}}AllNodesValidationDeployment
223 config: {get_resource: AllNodesValidationConfig}
224 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
226 {{role.name}}IpListMap:
227 type: OS::TripleO::Network::Ports::NetIpListMap
229 ControlPlaneIpList: {get_attr: [{{role.name}}, ip_address]}
230 ExternalIpList: {get_attr: [{{role.name}}, external_ip_address]}
231 InternalApiIpList: {get_attr: [{{role.name}}, internal_api_ip_address]}
232 StorageIpList: {get_attr: [{{role.name}}, storage_ip_address]}
233 StorageMgmtIpList: {get_attr: [{{role.name}}, storage_mgmt_ip_address]}
234 TenantIpList: {get_attr: [{{role.name}}, tenant_ip_address]}
235 ManagementIpList: {get_attr: [{{role.name}}, management_ip_address]}
236 EnabledServices: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
237 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
238 ServiceHostnameList: {get_attr: [{{role.name}}, hostname]}
241 type: OS::Heat::ResourceGroup
244 count: {get_param: {{role.name}}Count}
245 removal_policies: {get_param: {{role.name}}RemovalPolicies}
247 type: OS::TripleO::{{role.name}}
249 CloudDomain: {get_param: CloudDomain}
250 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
251 EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
254 template: {get_param: {{role.name}}HostnameFormat}
256 '%stackname%': {get_param: 'OS::stack_name'}
258 ServiceConfigSettings:
260 - get_attr: [{{role.name}}ServiceChain, role_data, config_settings]
262 - get_attr: [{{r.name}}ServiceChain, role_data, global_config_settings]
264 # This next step combines two yaql passes:
265 # - The inner one does a deep merge on the service_config_settings for all roles
266 # - The outer one filters the map based on the services enabled for the role
267 # then merges the result into one map.
269 expression: let(root => $) -> $.data.map.items().where($[0] in $root.data.services).select($[1]).reduce($1.mergeWith($2), {})
273 expression: $.data.where($ != null).reduce($1.mergeWith($2), {})
276 - get_attr: [{{r.name}}ServiceChain, role_data, service_config_settings]
278 services: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
279 ServiceNames: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
280 MonitoringSubscriptions: {get_attr: [{{role.name}}ServiceChain, role_data, monitoring_subscriptions]}
281 LoggingSources: {get_attr: [{{role.name}}ServiceChain, role_data, logging_sources]}
282 LoggingGroups: {get_attr: [{{role.name}}ServiceChain, role_data, logging_groups]}
286 type: OS::TripleO::AllNodes::SoftwareConfig
288 cloud_name_external: {get_param: CloudName}
289 cloud_name_internal_api: {get_param: CloudNameInternal}
290 cloud_name_storage: {get_param: CloudNameStorage}
291 cloud_name_storage_mgmt: {get_param: CloudNameStorageManagement}
292 cloud_name_ctlplane: {get_param: CloudNameCtlplane}
294 {% for role in roles %}
297 - {get_attr: [{{role.name}}, hosts_entry]}
302 {% for role in roles %}
303 - {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
305 controller_ips: {get_attr: [Controller, ip_address]}
306 controller_names: {get_attr: [Controller, hostname]}
308 # Note (shardy) this somewhat complex yaql may be replaced
309 # with a map_deep_merge function in ocata. It merges the
310 # list of maps, but appends to colliding lists when a service
311 # is deployed on more than one role
313 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
316 {% for role in roles %}
317 - {get_attr: [{{role.name}}IpListMap, service_ips]}
321 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
324 {% for role in roles %}
325 - {get_attr: [{{role.name}}IpListMap, service_hostnames]}
327 # FIXME(shardy): These require further work to move into service_ips
328 memcache_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, MemcachedNetwork]}]}
329 keystone_public_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystonePublicApiNetwork]}]}
330 keystone_admin_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystoneAdminApiNetwork]}]}
331 NetVipMap: {get_attr: [VipMap, net_ip_map]}
332 RedisVirtualIP: {get_attr: [RedisVirtualIP, ip_address]}
333 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
334 DeployIdentifier: {get_param: DeployIdentifier}
335 UpdateIdentifier: {get_param: UpdateIdentifier}
338 type: OS::Heat::RandomString
343 type: OS::Heat::RandomString
346 salt: {get_param: RabbitCookieSalt}
349 type: OS::TripleO::DefaultPasswords
351 DefaultMysqlRootPassword: {get_attr: [MysqlRootPassword, value]}
352 DefaultRabbitCookie: {get_attr: [RabbitCookie, value]}
353 DefaultHeatAuthEncryptionKey: {get_attr: [HeatAuthEncryptionKey, value]}
354 DefaultPcsdPassword: {get_attr: [PcsdPassword, value]}
355 DefaultHorizonSecret: {get_attr: [HorizonSecret, value]}
357 # creates the network architecture
359 type: OS::TripleO::Network
362 type: OS::Neutron::Port
365 name: control_virtual_ip
366 network: {get_param: NeutronControlPlaneID}
367 fixed_ips: {get_param: ControlFixedIPs}
368 replacement_policy: AUTO
372 type: OS::TripleO::Network::Ports::RedisVipPort
374 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
375 ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
376 PortName: redis_virtual_ip
377 NetworkName: {get_attr: [ServiceNetMap, service_net_map, RedisNetwork]}
379 FixedIPs: {get_param: RedisVirtualFixedIPs}
381 # The public VIP is on the External net, falls back to ctlplane
384 type: OS::TripleO::Network::Ports::ExternalVipPort
386 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
387 ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
388 PortName: public_virtual_ip
389 FixedIPs: {get_param: PublicVirtualFixedIPs}
391 InternalApiVirtualIP:
393 type: OS::TripleO::Network::Ports::InternalApiVipPort
395 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
396 PortName: internal_api_virtual_ip
397 FixedIPs: {get_param: InternalApiVirtualFixedIPs}
401 type: OS::TripleO::Network::Ports::StorageVipPort
403 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
404 PortName: storage_virtual_ip
405 FixedIPs: {get_param: StorageVirtualFixedIPs}
407 StorageMgmtVirtualIP:
409 type: OS::TripleO::Network::Ports::StorageMgmtVipPort
411 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
412 PortName: storage_management_virtual_ip
413 FixedIPs: {get_param: StorageMgmtVirtualFixedIPs}
416 type: OS::TripleO::Network::Ports::NetVipMap
418 ControlPlaneIp: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
419 ExternalIp: {get_attr: [PublicVirtualIP, ip_address]}
420 ExternalIpUri: {get_attr: [PublicVirtualIP, ip_address_uri]}
421 InternalApiIp: {get_attr: [InternalApiVirtualIP, ip_address]}
422 InternalApiIpUri: {get_attr: [InternalApiVirtualIP, ip_address_uri]}
423 StorageIp: {get_attr: [StorageVirtualIP, ip_address]}
424 StorageIpUri: {get_attr: [StorageVirtualIP, ip_address_uri]}
425 StorageMgmtIp: {get_attr: [StorageMgmtVirtualIP, ip_address]}
426 StorageMgmtIpUri: {get_attr: [StorageMgmtVirtualIP, ip_address_uri]}
427 # No tenant or management VIP required
429 # All Nodes Validations
430 AllNodesValidationConfig:
431 type: OS::TripleO::AllNodes::Validation
436 - - {get_attr: [Controller, resource.0.external_ip_address]}
437 - {get_attr: [Controller, resource.0.internal_api_ip_address]}
438 - {get_attr: [Controller, resource.0.storage_ip_address]}
439 - {get_attr: [Controller, resource.0.storage_mgmt_ip_address]}
440 - {get_attr: [Controller, resource.0.tenant_ip_address]}
441 - {get_attr: [Controller, resource.0.management_ip_address]}
444 type: OS::TripleO::Tasks::UpdateWorkflow
447 {% for role in roles %}
448 {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
451 deploy_identifier: {get_param: DeployIdentifier}
452 update_identifier: {get_param: UpdateIdentifier}
454 # Optional ExtraConfig for all nodes - all roles are passed in here, but
455 # the nested template may configure each role differently (or not at all)
457 type: OS::TripleO::AllNodesExtraConfig
460 {% for role in roles %}
461 - {{role.name}}AllNodesValidationDeployment
464 {% for role in roles %}
465 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
468 # Post deployment steps for all roles
470 type: OS::TripleO::PostDeploySteps
473 {% for role in roles %}
474 {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
477 {% for role in roles %}
478 {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data]}
483 description: Asserts that the keystone endpoints have been provisioned.
486 description: URL for the Overcloud Keystone service
487 value: {get_attr: [EndpointMap, endpoint_map, KeystonePublic, uri]}
489 description: Keystone Admin VIP endpoint
490 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystoneAdminApiNetwork]}]}
492 description: Controller VIP for public API endpoints
493 value: {get_attr: [VipMap, net_ip_map, external]}
495 description: VIP for Aodh API internal endpoint
496 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, AodhApiNetwork]}]}
497 CeilometerInternalVip:
498 description: VIP for Ceilometer API internal endpoint
499 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CeilometerApiNetwork]}]}
501 description: VIP for Ceph RGW internal endpoint
502 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CephRgwNetwork]}]}
504 description: VIP for Cinder API internal endpoint
505 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CinderApiNetwork]}]}
507 description: VIP for Glance API internal endpoint
508 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, GlanceApiNetwork]}]}
510 description: VIP for Gnocchi API internal endpoint
511 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, GnocchiApiNetwork]}]}
513 description: VIP for Heat API internal endpoint
514 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, HeatApiNetwork]}]}
516 description: VIP for Ironic API internal endpoint
517 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, IronicApiNetwork]}]}
519 description: VIP for Keystone API internal endpoint
520 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystonePublicApiNetwork]}]}
522 description: VIP for Manila API internal endpoint
523 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, ManilaApiNetwork]}]}
525 description: VIP for Neutron API internal endpoint
526 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, NeutronApiNetwork]}]}
528 description: VIP for Nova API internal endpoint
529 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, NovaApiNetwork]}]}
530 OpenDaylightInternalVip:
531 description: VIP for OpenDaylight API internal endpoint
532 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, OpenDaylightApiNetwork]}]}
534 description: VIP for Sahara API internal endpoint
535 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, SaharaApiNetwork]}]}
537 description: VIP for Swift Proxy internal endpoint
538 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, SwiftProxyNetwork]}]}
541 Mapping of the resources with the needed info for their endpoints.
542 This includes the protocol used, the IP, port and also a full
543 representation of the URI.
544 value: {get_attr: [EndpointMap, endpoint_map]}
547 The content that should be appended to your /etc/hosts if you want to get
548 hostname-based access to the deployed nodes (useful for testing without
550 value: {get_attr: [allNodesConfig, hosts_entries]}
552 description: The services enabled on each role
554 {% for role in roles %}
555 {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}