Remove double definition of config_settings key in keystone
[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     default: {{role.ServicesDefault|default([])}}
125
126   {{role.name}}Count:
127     description: Number of {{role.name}} nodes to deploy
128     type: number
129     default: {{role.CountDefault|default(0)}}
130
131   {{role.name}}HostnameFormat:
132     type: string
133     description: >
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}}"
139   {% else %}
140     default: "%stackname%-{{role.name.lower()}}-%index%"
141   {% endif %}
142
143   {{role.name}}RemovalPolicies:
144     default: []
145     type: json
146     description: >
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']}]
150 {% endfor %}
151
152   # Identifiers to trigger tasks on nodes
153   UpdateIdentifier:
154     default: ''
155     type: string
156     description: >
157       Setting to a previously unused value during stack-update will trigger
158       package update on all nodes
159   DeployIdentifier:
160     default: ''
161     type: string
162     description: >
163       Setting this to a unique value will re-run any deployment tasks which
164       perform configuration on a Heat stack-update.
165
166 resources:
167
168   HeatAuthEncryptionKey:
169     type: OS::Heat::RandomString
170
171   PcsdPassword:
172     type: OS::Heat::RandomString
173     properties:
174       length: 16
175
176   HorizonSecret:
177     type: OS::Heat::RandomString
178     properties:
179       length: 10
180
181   ServiceNetMap:
182     type: OS::TripleO::ServiceNetMap
183
184   EndpointMap:
185     type: OS::TripleO::EndpointMap
186     properties:
187       CloudEndpoints:
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]}
195
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
201     properties:
202       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]}
207
208   {{role.name}}AllNodesDeployment:
209     type: OS::Heat::StructuredDeployments
210     properties:
211       name: {{role.name}}AllNodesDeployment
212       config: {get_attr: [allNodesConfig, config_id]}
213       servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
214       input_values:
215         bootstrap_nodeid: {get_attr: [{{role.name}}, resource.0.hostname]}
216         bootstrap_nodeid_ip: {get_attr: [{{role.name}}, resource.0.ip_address]}
217
218   {{role.name}}AllNodesValidationDeployment:
219     type: OS::Heat::StructuredDeployments
220     depends_on: {{role.name}}AllNodesDeployment
221     properties:
222       name: {{role.name}}AllNodesValidationDeployment
223       config: {get_resource: AllNodesValidationConfig}
224       servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
225
226   {{role.name}}IpListMap:
227     type: OS::TripleO::Network::Ports::NetIpListMap
228     properties:
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]}
239
240   {{role.name}}:
241     type: OS::Heat::ResourceGroup
242     depends_on: Networks
243     properties:
244       count: {get_param: {{role.name}}Count}
245       removal_policies: {get_param: {{role.name}}RemovalPolicies}
246       resource_def:
247         type: OS::TripleO::{{role.name}}
248         properties:
249           CloudDomain: {get_param: CloudDomain}
250           ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
251           EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
252           Hostname:
253             str_replace:
254               template: {get_param: {{role.name}}HostnameFormat}
255               params:
256                 '%stackname%': {get_param: 'OS::stack_name'}
257           NodeIndex: '%index%'
258           ServiceConfigSettings:
259             map_merge:
260               -  get_attr: [{{role.name}}ServiceChain, role_data, config_settings]
261           {% for r in roles %}
262               - get_attr: [{{r.name}}ServiceChain, role_data, global_config_settings]
263           {% endfor %}
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.
268               - yaql:
269                   expression: let(root => $) -> $.data.map.items().where($[0] in $root.data.services).select($[1]).reduce($1.mergeWith($2), {})
270                   data:
271                     map:
272                       yaql:
273                         expression: $.data.where($ != null).reduce($1.mergeWith($2), {})
274                         data:
275                         {% for r in roles %}
276                           - get_attr: [{{r.name}}ServiceChain, role_data, service_config_settings]
277                         {% endfor %}
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]}
283 {% endfor %}
284
285   allNodesConfig:
286     type: OS::TripleO::AllNodes::SoftwareConfig
287     properties:
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}
293       hosts:
294 {% for role in roles %}
295         - list_join:
296             - '\n'
297             - {get_attr: [{{role.name}}, hosts_entry]}
298 {% endfor %}
299       enabled_services:
300         list_join:
301           - ','
302 {% for role in roles %}
303           - {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
304 {% endfor %}
305       controller_ips: {get_attr: [Controller, ip_address]}
306       controller_names: {get_attr: [Controller, hostname]}
307       service_ips:
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
312         yaql:
313           expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
314           data:
315             l:
316 {% for role in roles %}
317               - {get_attr: [{{role.name}}IpListMap, service_ips]}
318 {% endfor %}
319       service_node_names:
320         yaql:
321           expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
322           data:
323             l:
324 {% for role in roles %}
325               - {get_attr: [{{role.name}}IpListMap, service_hostnames]}
326 {% endfor %}
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}
336
337   MysqlRootPassword:
338     type: OS::Heat::RandomString
339     properties:
340       length: 10
341
342   RabbitCookie:
343     type: OS::Heat::RandomString
344     properties:
345       length: 20
346       salt: {get_param: RabbitCookieSalt}
347
348   DefaultPasswords:
349     type: OS::TripleO::DefaultPasswords
350     properties:
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]}
356
357   # creates the network architecture
358   Networks:
359     type: OS::TripleO::Network
360
361   ControlVirtualIP:
362     type: OS::Neutron::Port
363     depends_on: Networks
364     properties:
365       name: control_virtual_ip
366       network: {get_param: NeutronControlPlaneID}
367       fixed_ips: {get_param: ControlFixedIPs}
368       replacement_policy: AUTO
369
370   RedisVirtualIP:
371     depends_on: Networks
372     type: OS::TripleO::Network::Ports::RedisVipPort
373     properties:
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]}
378       ServiceName: redis
379       FixedIPs: {get_param: RedisVirtualFixedIPs}
380
381   # The public VIP is on the External net, falls back to ctlplane
382   PublicVirtualIP:
383     depends_on: Networks
384     type: OS::TripleO::Network::Ports::ExternalVipPort
385     properties:
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}
390
391   InternalApiVirtualIP:
392     depends_on: Networks
393     type: OS::TripleO::Network::Ports::InternalApiVipPort
394     properties:
395       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
396       PortName: internal_api_virtual_ip
397       FixedIPs: {get_param: InternalApiVirtualFixedIPs}
398
399   StorageVirtualIP:
400     depends_on: Networks
401     type: OS::TripleO::Network::Ports::StorageVipPort
402     properties:
403       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
404       PortName: storage_virtual_ip
405       FixedIPs: {get_param: StorageVirtualFixedIPs}
406
407   StorageMgmtVirtualIP:
408     depends_on: Networks
409     type: OS::TripleO::Network::Ports::StorageMgmtVipPort
410     properties:
411       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
412       PortName: storage_management_virtual_ip
413       FixedIPs: {get_param: StorageMgmtVirtualFixedIPs}
414
415   VipMap:
416     type: OS::TripleO::Network::Ports::NetVipMap
417     properties:
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
428
429   # All Nodes Validations
430   AllNodesValidationConfig:
431     type: OS::TripleO::AllNodes::Validation
432     properties:
433       PingTestIps:
434         list_join:
435         - ' '
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]}
442
443   UpdateWorkflow:
444     type: OS::TripleO::Tasks::UpdateWorkflow
445     properties:
446       servers:
447 {% for role in roles %}
448         {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
449 {% endfor %}
450       input_values:
451         deploy_identifier: {get_param: DeployIdentifier}
452         update_identifier: {get_param: UpdateIdentifier}
453
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)
456   AllNodesExtraConfig:
457     type: OS::TripleO::AllNodesExtraConfig
458     depends_on:
459       - UpdateWorkflow
460 {% for role in roles %}
461       - {{role.name}}AllNodesValidationDeployment
462 {% endfor %}
463     properties:
464 {% for role in roles %}
465       servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
466 {% endfor %}
467
468   # Post deployment steps for all roles
469   AllNodesDeploySteps:
470     type: OS::TripleO::PostDeploySteps
471     properties:
472       servers:
473 {% for role in roles %}
474         {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
475 {% endfor %}
476       role_data:
477 {% for role in roles %}
478         {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data]}
479 {% endfor %}
480
481 outputs:
482   ManagedEndpoints:
483     description: Asserts that the keystone endpoints have been provisioned.
484     value: true
485   KeystoneURL:
486     description: URL for the Overcloud Keystone service
487     value: {get_attr: [EndpointMap, endpoint_map, KeystonePublic, uri]}
488   KeystoneAdminVip:
489     description: Keystone Admin VIP endpoint
490     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystoneAdminApiNetwork]}]}
491   PublicVip:
492     description: Controller VIP for public API endpoints
493     value: {get_attr: [VipMap, net_ip_map, external]}
494   AodhInternalVip:
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]}]}
500   CephRgwInternalVip:
501     description: VIP for Ceph RGW internal endpoint
502     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CephRgwNetwork]}]}
503   CinderInternalVip:
504     description: VIP for Cinder API internal endpoint
505     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, CinderApiNetwork]}]}
506   GlanceInternalVip:
507     description: VIP for Glance API internal endpoint
508     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, GlanceApiNetwork]}]}
509   GnocchiInternalVip:
510     description: VIP for Gnocchi API internal endpoint
511     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, GnocchiApiNetwork]}]}
512   HeatInternalVip:
513     description: VIP for Heat API internal endpoint
514     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, HeatApiNetwork]}]}
515   IronicInternalVip:
516     description: VIP for Ironic API internal endpoint
517     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, IronicApiNetwork]}]}
518   KeystoneInternalVip:
519     description: VIP for Keystone API internal endpoint
520     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystonePublicApiNetwork]}]}
521   ManilaInternalVip:
522     description: VIP for Manila API internal endpoint
523     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, ManilaApiNetwork]}]}
524   NeutronInternalVip:
525     description: VIP for Neutron API internal endpoint
526     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, NeutronApiNetwork]}]}
527   NovaInternalVip:
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]}]}
533   SaharaInternalVip:
534     description: VIP for Sahara API internal endpoint
535     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, SaharaApiNetwork]}]}
536   SwiftInternalVip:
537     description: VIP for Swift Proxy internal endpoint
538     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, SwiftProxyNetwork]}]}
539   EndpointMap:
540     description: |
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]}
545   HostsEntry:
546     description: |
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
549       setting up a DNS).
550     value: {get_attr: [allNodesConfig, hosts_entries]}
551   EnabledServices:
552     description: The services enabled on each role
553     value:
554 {% for role in roles %}
555       {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
556 {% endfor %}