ec4db843dc756c457d7019a79b55403c1abf0ffc
[apex-tripleo-heat-templates.git] / overcloud.j2.yaml
1 heat_template_version: 2016-10-14
2
3 description: >
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.
8
9
10 # TODO(shadower): we should probably use the parameter groups to put
11 # some order in here.
12 parameters:
13
14   # Common parameters (not specific to a role)
15   CloudName:
16     default: overcloud.localdomain
17     description: The DNS name of this cloud. E.g. ci-overcloud.tripleo.org
18     type: string
19   CloudNameInternal:
20     default: overcloud.internalapi.localdomain
21     description: >
22       The DNS name of this cloud's internal API endpoint. E.g.
23       'ci-overcloud.internalapi.tripleo.org'.
24     type: string
25   CloudNameStorage:
26     default: overcloud.storage.localdomain
27     description: >
28       The DNS name of this cloud's storage endpoint. E.g.
29       'ci-overcloud.storage.tripleo.org'.
30     type: string
31   CloudNameStorageManagement:
32     default: overcloud.storagemgmt.localdomain
33     description: >
34       The DNS name of this cloud's storage management endpoint. E.g.
35       'ci-overcloud.storagemgmt.tripleo.org'.
36     type: string
37   CloudNameCtlplane:
38     default: overcloud.ctlplane.localdomain
39     description: >
40       The DNS name of this cloud's storage management endpoint. E.g.
41       'ci-overcloud.management.tripleo.org'.
42     type: string
43   ControlFixedIPs:
44     default: []
45     description: Should be used for arbitrary ips.
46     type: json
47   InternalApiVirtualFixedIPs:
48     default: []
49     description: >
50         Control the IP allocation for the InternalApiVirtualInterface port. E.g.
51         [{'ip_address':'1.2.3.4'}]
52     type: json
53   NeutronControlPlaneID:
54     default: 'ctlplane'
55     type: string
56     description: Neutron ID or name for ctlplane network.
57   NeutronPublicInterface:
58     default: nic1
59     description: What interface to bridge onto br-ex for network nodes.
60     type: string
61   PublicVirtualFixedIPs:
62     default: []
63     description: >
64         Control the IP allocation for the PublicVirtualInterface port. E.g.
65         [{'ip_address':'1.2.3.4'}]
66     type: json
67   RabbitCookieSalt:
68     type: string
69     default: unset
70     description: Salt for the rabbit cookie, change this to force the randomly generated rabbit cookie to change.
71   StorageVirtualFixedIPs:
72     default: []
73     description: >
74         Control the IP allocation for the StorageVirtualInterface port. E.g.
75         [{'ip_address':'1.2.3.4'}]
76     type: json
77   StorageMgmtVirtualFixedIPs:
78     default: []
79     description: >
80         Control the IP allocation for the StorageMgmgVirtualInterface port. E.g.
81         [{'ip_address':'1.2.3.4'}]
82     type: json
83   RedisVirtualFixedIPs:
84     default: []
85     description: >
86         Control the IP allocation for the virtual IP used by Redis. E.g.
87         [{'ip_address':'1.2.3.4'}]
88     type: json
89   CloudDomain:
90     default: 'localdomain'
91     type: string
92     description: >
93       The DNS domain used for the hosts. This should match the dhcp_domain
94       configured in the Undercloud neutron. Defaults to localdomain.
95   ServerMetadata:
96     default: {}
97     description: >
98       Extra properties or metadata passed to Nova for the created nodes in
99       the overcloud. It's accessible via the Nova metadata API.
100     type: json
101
102 # Compute-specific params
103 # FIXME(shardy) handle these deprecated names as they don't match compute.yaml
104   HypervisorNeutronPhysicalBridge:
105     default: 'br-ex'
106     description: >
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.
110     type: string
111   HypervisorNeutronPublicInterface:
112     default: nic1
113     description: What interface to add to the HypervisorNeutronPhysicalBridge.
114     type: string
115
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   {% if role.ServicesDefault %}
125     default: {{role.ServicesDefault}}
126   {% endif %}
127
128   {{role.name}}Count:
129     description: Number of {{role.name}} nodes to deploy
130     type: number
131   {% if role.CountDefault %}
132     default: {{role.CountDefault}}
133   {% endif %}
134
135   {{role.name}}HostnameFormat:
136     type: string
137     description: >
138       Format for {{role.name}} node hostnames
139       Note %index% is translated into the index of the node, e.g 0/1/2 etc
140       and %stackname% is replaced with the stack name e.g overcloud
141   {% if role.HostnameFormatDefault %}
142     default: "{{role.HostnameFormatDefault}}"
143   {% endif %}
144
145   {{role.name}}RemovalPolicies:
146     default: []
147     type: json
148     description: >
149       List of resources to be removed from {{role.name}} ResourceGroup when
150       doing an update which requires removal of specific resources.
151       Example format ComputeRemovalPolicies: [{'resource_list': ['0']}]
152 {% endfor %}
153
154   # Identifiers to trigger tasks on nodes
155   UpdateIdentifier:
156     default: ''
157     type: string
158     description: >
159       Setting to a previously unused value during stack-update will trigger
160       package update on all nodes
161   DeployIdentifier:
162     default: ''
163     type: string
164     description: >
165       Setting this to a unique value will re-run any deployment tasks which
166       perform configuration on a Heat stack-update.
167
168 resources:
169
170   HeatAuthEncryptionKey:
171     type: OS::Heat::RandomString
172
173   PcsdPassword:
174     type: OS::Heat::RandomString
175     properties:
176       length: 16
177
178   HorizonSecret:
179     type: OS::Heat::RandomString
180     properties:
181       length: 10
182
183   ServiceNetMap:
184     type: OS::TripleO::ServiceNetMap
185
186   EndpointMap:
187     type: OS::TripleO::EndpointMap
188     properties:
189       CloudEndpoints:
190         external: {get_param: CloudName}
191         internal_api: {get_param: CloudNameInternal}
192         storage: {get_param: CloudNameStorage}
193         storage_mgmt: {get_param: CloudNameStorageManagement}
194         ctlplane: {get_param: CloudNameCtlplane}
195       NetIpMap: {get_attr: [VipMap, net_ip_map]}
196       ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
197
198   # Jinja loop for Role in roles_data.yaml
199 {% for role in roles %}
200   # Resources generated for {{role.name}} Role
201   {{role.name}}ServiceChain:
202     type: OS::TripleO::Services
203     properties:
204       Services:
205         get_param: {{role.name}}Services
206       ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
207       EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
208       DefaultPasswords: {get_attr: [DefaultPasswords, passwords]}
209
210   {{role.name}}AllNodesDeployment:
211     type: OS::Heat::StructuredDeployments
212     properties:
213       name: {{role.name}}AllNodesDeployment
214       config: {get_attr: [allNodesConfig, config_id]}
215       servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
216       input_values:
217         bootstrap_nodeid: {get_attr: [{{role.name}}, resource.0.hostname]}
218         bootstrap_nodeid_ip: {get_attr: [{{role.name}}, resource.0.ip_address]}
219
220   {{role.name}}AllNodesValidationDeployment:
221     type: OS::Heat::StructuredDeployments
222     depends_on: {{role.name}}AllNodesDeployment
223     properties:
224       name: {{role.name}}AllNodesValidationDeployment
225       config: {get_resource: AllNodesValidationConfig}
226       servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
227
228   {{role.name}}IpListMap:
229     type: OS::TripleO::Network::Ports::NetIpListMap
230     properties:
231       ControlPlaneIpList: {get_attr: [{{role.name}}, ip_address]}
232       ExternalIpList: {get_attr: [{{role.name}}, external_ip_address]}
233       InternalApiIpList: {get_attr: [{{role.name}}, internal_api_ip_address]}
234       StorageIpList: {get_attr: [{{role.name}}, storage_ip_address]}
235       StorageMgmtIpList: {get_attr: [{{role.name}}, storage_mgmt_ip_address]}
236       TenantIpList: {get_attr: [{{role.name}}, tenant_ip_address]}
237       ManagementIpList: {get_attr: [{{role.name}}, management_ip_address]}
238       EnabledServices: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
239       ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
240       ServiceHostnameList: {get_attr: [{{role.name}}, hostname]}
241
242   {{role.name}}:
243     type: OS::Heat::ResourceGroup
244     depends_on: Networks
245     properties:
246       count: {get_param: {{role.name}}Count}
247       removal_policies: {get_param: {{role.name}}RemovalPolicies}
248       resource_def:
249         type: OS::TripleO::{{role.name}}
250         properties:
251           CloudDomain: {get_param: CloudDomain}
252           ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
253           EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
254           Hostname:
255             str_replace:
256               template: {get_param: {{role.name}}HostnameFormat}
257               params:
258                 '%stackname%': {get_param: 'OS::stack_name'}
259           NodeIndex: '%index%'
260           ServiceConfigSettings:
261             map_merge:
262               -  get_attr: [{{role.name}}ServiceChain, role_data, config_settings]
263           {% for r in roles %}
264               - get_attr: [{{r.name}}ServiceChain, role_data, global_config_settings]
265           {% endfor %}
266           ServiceNames: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
267           MonitoringSubscriptions: {get_attr: [{{role.name}}ServiceChain, role_data, monitoring_subscriptions]}
268 {% endfor %}
269
270   allNodesConfig:
271     type: OS::TripleO::AllNodes::SoftwareConfig
272     properties:
273       cloud_name_external: {get_param: CloudName}
274       cloud_name_internal_api: {get_param: CloudNameInternal}
275       cloud_name_storage: {get_param: CloudNameStorage}
276       cloud_name_storage_mgmt: {get_param: CloudNameStorageManagement}
277       cloud_name_ctlplane: {get_param: CloudNameCtlplane}
278       hosts:
279 {% for role in roles %}
280         - list_join:
281             - '\n'
282             - {get_attr: [{{role.name}}, hosts_entry]}
283 {% endfor %}
284       enabled_services:
285         list_join:
286           - ','
287 {% for role in roles %}
288           - {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
289 {% endfor %}
290       controller_ips: {get_attr: [Controller, ip_address]}
291       controller_names: {get_attr: [Controller, hostname]}
292       service_ips:
293         # Note (shardy) this somewhat complex yaql may be replaced
294         # with a map_deep_merge function in ocata.  It merges the
295         # list of maps, but appends to colliding lists when a service
296         # is deployed on more than one role
297         yaql:
298           expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
299           data:
300             l:
301 {% for role in roles %}
302               - {get_attr: [{{role.name}}IpListMap, service_ips]}
303 {% endfor %}
304       service_node_names:
305         yaql:
306           expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
307           data:
308             l:
309 {% for role in roles %}
310               - {get_attr: [{{role.name}}IpListMap, service_hostnames]}
311 {% endfor %}
312       # FIXME(shardy): These require further work to move into service_ips
313       memcache_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, MemcachedNetwork]}]}
314       keystone_public_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystonePublicApiNetwork]}]}
315       keystone_admin_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystoneAdminApiNetwork]}]}
316       NetVipMap: {get_attr: [VipMap, net_ip_map]}
317       RedisVirtualIP: {get_attr: [RedisVirtualIP, ip_address]}
318       ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
319       DeployIdentifier: {get_param: DeployIdentifier}
320       UpdateIdentifier: {get_param: UpdateIdentifier}
321
322   MysqlRootPassword:
323     type: OS::Heat::RandomString
324     properties:
325       length: 10
326
327   RabbitCookie:
328     type: OS::Heat::RandomString
329     properties:
330       length: 20
331       salt: {get_param: RabbitCookieSalt}
332
333   DefaultPasswords:
334     type: OS::TripleO::DefaultPasswords
335     properties:
336       DefaultMysqlRootPassword: {get_attr: [MysqlRootPassword, value]}
337       DefaultRabbitCookie: {get_attr: [RabbitCookie, value]}
338       DefaultHeatAuthEncryptionKey: {get_attr: [HeatAuthEncryptionKey, value]}
339       DefaultPcsdPassword: {get_attr: [PcsdPassword, value]}
340       DefaultHorizonSecret: {get_attr: [HorizonSecret, value]}
341
342   # creates the network architecture
343   Networks:
344     type: OS::TripleO::Network
345
346   ControlVirtualIP:
347     type: OS::Neutron::Port
348     depends_on: Networks
349     properties:
350       name: control_virtual_ip
351       network: {get_param: NeutronControlPlaneID}
352       fixed_ips: {get_param: ControlFixedIPs}
353       replacement_policy: AUTO
354
355   RedisVirtualIP:
356     depends_on: Networks
357     type: OS::TripleO::Network::Ports::RedisVipPort
358     properties:
359       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
360       ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
361       PortName: redis_virtual_ip
362       NetworkName: {get_attr: [ServiceNetMap, service_net_map, RedisNetwork]}
363       ServiceName: redis
364       FixedIPs: {get_param: RedisVirtualFixedIPs}
365
366   # The public VIP is on the External net, falls back to ctlplane
367   PublicVirtualIP:
368     depends_on: Networks
369     type: OS::TripleO::Network::Ports::ExternalVipPort
370     properties:
371       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
372       ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
373       PortName: public_virtual_ip
374       FixedIPs: {get_param: PublicVirtualFixedIPs}
375
376   InternalApiVirtualIP:
377     depends_on: Networks
378     type: OS::TripleO::Network::Ports::InternalApiVipPort
379     properties:
380       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
381       PortName: internal_api_virtual_ip
382       FixedIPs: {get_param: InternalApiVirtualFixedIPs}
383
384   StorageVirtualIP:
385     depends_on: Networks
386     type: OS::TripleO::Network::Ports::StorageVipPort
387     properties:
388       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
389       PortName: storage_virtual_ip
390       FixedIPs: {get_param: StorageVirtualFixedIPs}
391
392   StorageMgmtVirtualIP:
393     depends_on: Networks
394     type: OS::TripleO::Network::Ports::StorageMgmtVipPort
395     properties:
396       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
397       PortName: storage_management_virtual_ip
398       FixedIPs: {get_param: StorageMgmtVirtualFixedIPs}
399
400   VipMap:
401     type: OS::TripleO::Network::Ports::NetVipMap
402     properties:
403       ControlPlaneIp: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
404       ExternalIp: {get_attr: [PublicVirtualIP, ip_address]}
405       ExternalIpUri: {get_attr: [PublicVirtualIP, ip_address_uri]}
406       InternalApiIp: {get_attr: [InternalApiVirtualIP, ip_address]}
407       InternalApiIpUri: {get_attr: [InternalApiVirtualIP, ip_address_uri]}
408       StorageIp: {get_attr: [StorageVirtualIP, ip_address]}
409       StorageIpUri: {get_attr: [StorageVirtualIP, ip_address_uri]}
410       StorageMgmtIp: {get_attr: [StorageMgmtVirtualIP, ip_address]}
411       StorageMgmtIpUri: {get_attr: [StorageMgmtVirtualIP, ip_address_uri]}
412       # No tenant or management VIP required
413
414   # All Nodes Validations
415   AllNodesValidationConfig:
416     type: OS::TripleO::AllNodes::Validation
417     properties:
418       PingTestIps:
419         list_join:
420         - ' '
421         - - {get_attr: [Controller, resource.0.external_ip_address]}
422           - {get_attr: [Controller, resource.0.internal_api_ip_address]}
423           - {get_attr: [Controller, resource.0.storage_ip_address]}
424           - {get_attr: [Controller, resource.0.storage_mgmt_ip_address]}
425           - {get_attr: [Controller, resource.0.tenant_ip_address]}
426           - {get_attr: [Controller, resource.0.management_ip_address]}
427
428   UpdateWorkflow:
429     type: OS::TripleO::Tasks::UpdateWorkflow
430     properties:
431       controller_servers: {get_attr: [Controller, attributes, nova_server_resource]}
432       compute_servers: {get_attr: [Compute, attributes, nova_server_resource]}
433       blockstorage_servers: {get_attr: [BlockStorage, attributes, nova_server_resource]}
434       objectstorage_servers: {get_attr: [ObjectStorage, attributes, nova_server_resource]}
435       cephstorage_servers: {get_attr: [CephStorage, attributes, nova_server_resource]}
436       input_values:
437         deploy_identifier: {get_param: DeployIdentifier}
438         update_identifier: {get_param: UpdateIdentifier}
439
440   # Optional ExtraConfig for all nodes - all roles are passed in here, but
441   # the nested template may configure each role differently (or not at all)
442   AllNodesExtraConfig:
443     type: OS::TripleO::AllNodesExtraConfig
444     depends_on:
445       - UpdateWorkflow
446       - ComputeAllNodesValidationDeployment
447       - BlockStorageAllNodesValidationDeployment
448       - ObjectStorageAllNodesValidationDeployment
449       - CephStorageAllNodesValidationDeployment
450       - ControllerAllNodesValidationDeployment
451     properties:
452       controller_servers: {get_attr: [Controller, attributes, nova_server_resource]}
453       compute_servers: {get_attr: [Compute, attributes, nova_server_resource]}
454       blockstorage_servers: {get_attr: [BlockStorage, attributes, nova_server_resource]}
455       objectstorage_servers: {get_attr: [ObjectStorage, attributes, nova_server_resource]}
456       cephstorage_servers: {get_attr: [CephStorage, attributes, nova_server_resource]}
457
458   # Post deployment steps for all roles
459   AllNodesDeploySteps:
460     type: OS::TripleO::PostDeploySteps
461     properties:
462       servers:
463 {% for role in roles %}
464         {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
465 {% endfor %}
466       role_data:
467 {% for role in roles %}
468         {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data]}
469 {% endfor %}
470
471 outputs:
472   ManagedEndpoints:
473     description: Asserts that the keystone endpoints have been provisioned.
474     value: true
475   KeystoneURL:
476     description: URL for the Overcloud Keystone service
477     value: {get_attr: [EndpointMap, endpoint_map, KeystonePublic, uri]}
478   KeystoneAdminVip:
479     description: Keystone Admin VIP endpoint
480     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystoneAdminApiNetwork]}]}
481   PublicVip:
482     description: Controller VIP for public API endpoints
483     value: {get_attr: [VipMap, net_ip_map, external]}
484   AodhInternalVip:
485     description: VIP for Aodh API internal endpoint
486     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, AodhApiNetwork]}]}
487   CeilometerInternalVip:
488     description: VIP for Ceilometer API internal endpoint
489     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CeilometerApiNetwork]}]}
490   CephRgwInternalVip:
491     description: VIP for Ceph RGW internal endpoint
492     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CephRgwNetwork]}]}
493   CinderInternalVip:
494     description: VIP for Cinder API internal endpoint
495     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CinderApiNetwork]}]}
496   GlanceInternalVip:
497     description: VIP for Glance API internal endpoint
498     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, GlanceApiNetwork]}]}
499   GnocchiInternalVip:
500     description: VIP for Gnocchi API internal endpoint
501     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, GnocchiApiNetwork]}]}
502   HeatInternalVip:
503     description: VIP for Heat API internal endpoint
504     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, HeatApiNetwork]}]}
505   IronicInternalVip:
506     description: VIP for Ironic API internal endpoint
507     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, IronicApiNetwork]}]}
508   KeystoneInternalVip:
509     description: VIP for Keystone API internal endpoint
510     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystonePublicApiNetwork]}]}
511   ManilaInternalVip:
512     description: VIP for Manila API internal endpoint
513     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, ManilaApiNetwork]}]}
514   NeutronInternalVip:
515     description: VIP for Neutron API internal endpoint
516     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, NeutronApiNetwork]}]}
517   NovaInternalVip:
518     description: VIP for Nova API internal endpoint
519     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, NovaApiNetwork]}]}
520   OpenDaylightInternalVip:
521     description: VIP for OpenDaylight API internal endpoint
522     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, OpenDaylightApiNetwork]}]}
523   SaharaInternalVip:
524     description: VIP for Sahara API internal endpoint
525     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, SaharaApiNetwork]}]}
526   SwiftInternalVip:
527     description: VIP for Swift Proxy internal endpoint
528     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, SwiftProxyNetwork]}]}
529   EndpointMap:
530     description: |
531       Mapping of the resources with the needed info for their endpoints.
532       This includes the protocol used, the IP, port and also a full
533       representation of the URI.
534     value: {get_attr: [EndpointMap, endpoint_map]}
535   HostsEntry:
536     description: |
537       The content that should be appended to your /etc/hosts if you want to get
538       hostname-based access to the deployed nodes (useful for testing without
539       setting up a DNS).
540     value: {get_attr: [allNodesConfig, hosts_entries]}
541   EnabledServices:
542     description: The services enabled on each role
543     value:
544       Controller: {get_attr: [ControllerServiceChain, role_data, service_names]}
545       Compute: {get_attr: [ComputeServiceChain, role_data, service_names]}
546       BlockStorage: {get_attr: [BlockStorageServiceChain, role_data, service_names]}
547       ObjectStorage: {get_attr: [ObjectStorageServiceChain, role_data, service_names]}
548       CephStorage: {get_attr: [CephStorageServiceChain, role_data, service_names]}