Merge "Enable internal network TLS for etcd"
[apex-tripleo-heat-templates.git] / overcloud.j2.yaml
1 {%- set primary_role = [roles[0]] -%}
2 {%- for role in roles -%}
3   {%- if 'primary' in role.tags and 'controller' in role.tags -%}
4     {%- set _ = primary_role.pop() -%}
5     {%- set _ = primary_role.append(role) -%}
6   {%- endif -%}
7 {%- endfor -%}
8 {%- set primary_role_name = primary_role[0].name -%}
9 # primary role is: {{primary_role_name}}
10 heat_template_version: ocata
11
12 description: >
13   Deploy an OpenStack environment, consisting of several node types (roles),
14   Controller, Compute, BlockStorage, SwiftStorage and CephStorage. The Storage
15   roles enable independent scaling of the storage components, but the minimal
16   deployment is one Controller and one Compute node.
17
18
19 # TODO(shadower): we should probably use the parameter groups to put
20 # some order in here.
21 parameters:
22
23   # Common parameters (not specific to a role)
24   CloudName:
25     default: overcloud.localdomain
26     description: The DNS name of this cloud. E.g. ci-overcloud.tripleo.org
27     type: string
28   CloudNameInternal:
29     default: overcloud.internalapi.localdomain
30     description: >
31       The DNS name of this cloud's internal API endpoint. E.g.
32       'ci-overcloud.internalapi.tripleo.org'.
33     type: string
34   CloudNameStorage:
35     default: overcloud.storage.localdomain
36     description: >
37       The DNS name of this cloud's storage endpoint. E.g.
38       'ci-overcloud.storage.tripleo.org'.
39     type: string
40   CloudNameStorageManagement:
41     default: overcloud.storagemgmt.localdomain
42     description: >
43       The DNS name of this cloud's storage management endpoint. E.g.
44       'ci-overcloud.storagemgmt.tripleo.org'.
45     type: string
46   CloudNameCtlplane:
47     default: overcloud.ctlplane.localdomain
48     description: >
49       The DNS name of this cloud's storage management endpoint. E.g.
50       'ci-overcloud.management.tripleo.org'.
51     type: string
52   ControlFixedIPs:
53     default: []
54     description: >
55         Control the IP allocation for the ControlVirtualIP port. E.g.
56         [{'ip_address':'1.2.3.4'}]
57     type: json
58   InternalApiVirtualFixedIPs:
59     default: []
60     description: >
61         Control the IP allocation for the InternalApiVirtualInterface port. E.g.
62         [{'ip_address':'1.2.3.4'}]
63     type: json
64   NeutronControlPlaneID:
65     default: 'ctlplane'
66     type: string
67     description: Neutron ID or name for ctlplane network.
68   NeutronPublicInterface:
69     default: nic1
70     description: What interface to bridge onto br-ex for network nodes.
71     type: string
72   PublicVirtualFixedIPs:
73     default: []
74     description: >
75         Control the IP allocation for the PublicVirtualInterface port. E.g.
76         [{'ip_address':'1.2.3.4'}]
77     type: json
78   RabbitCookieSalt:
79     type: string
80     default: unset
81     description: Salt for the rabbit cookie, change this to force the randomly generated rabbit cookie to change.
82   StorageVirtualFixedIPs:
83     default: []
84     description: >
85         Control the IP allocation for the StorageVirtualInterface port. E.g.
86         [{'ip_address':'1.2.3.4'}]
87     type: json
88   StorageMgmtVirtualFixedIPs:
89     default: []
90     description: >
91         Control the IP allocation for the StorageMgmgVirtualInterface port. E.g.
92         [{'ip_address':'1.2.3.4'}]
93     type: json
94   RedisVirtualFixedIPs:
95     default: []
96     description: >
97         Control the IP allocation for the virtual IP used by Redis. E.g.
98         [{'ip_address':'1.2.3.4'}]
99     type: json
100   CloudDomain:
101     default: 'localdomain'
102     type: string
103     description: >
104       The DNS domain used for the hosts. This should match the dhcp_domain
105       configured in the Undercloud neutron. Defaults to localdomain.
106   ServerMetadata:
107     default: {}
108     description: >
109       Extra properties or metadata passed to Nova for the created nodes in
110       the overcloud. It's accessible via the Nova metadata API.
111     type: json
112
113 # Compute-specific params
114 # FIXME(shardy) handle these deprecated names as they don't match compute.yaml
115   HypervisorNeutronPhysicalBridge:
116     default: 'br-ex'
117     description: >
118       An OVS bridge to create on each hypervisor. This defaults to br-ex the
119       same as the control plane nodes, as we have a uniform configuration of
120       the openvswitch agent. Typically should not need to be changed.
121     type: string
122   HypervisorNeutronPublicInterface:
123     default: nic1
124     description: What interface to add to the HypervisorNeutronPhysicalBridge.
125     type: string
126
127   NodeCreateBatchSize:
128     default: 30
129     description: Maxiumum batch size for creating nodes
130     type: number
131
132   # Jinja loop for Role in role_data.yaml
133 {% for role in roles %}
134   # Parameters generated for {{role.name}} Role
135   {{role.name}}Services:
136     description: A list of service resources (configured in the Heat
137                  resource_registry) which represent nested stacks
138                  for each service that should get installed on the {{role.name}} role.
139     type: comma_delimited_list
140
141   {{role.name}}Count:
142     description: Number of {{role.name}} nodes to deploy
143     type: number
144     default: {{role.CountDefault|default(0)}}
145
146   {{role.name}}HostnameFormat:
147     type: string
148     description: >
149       Format for {{role.name}} node hostnames
150       Note %index% is translated into the index of the node, e.g 0/1/2 etc
151       and %stackname% is replaced with the stack name e.g overcloud
152   {% if role.HostnameFormatDefault %}
153     default: "{{role.HostnameFormatDefault}}"
154   {% else %}
155     default: "%stackname%-{{role.name.lower()}}-%index%"
156   {% endif %}
157
158   {{role.name}}RemovalPolicies:
159     default: []
160     type: json
161     description: >
162       List of resources to be removed from {{role.name}} ResourceGroup when
163       doing an update which requires removal of specific resources.
164       Example format ComputeRemovalPolicies: [{'resource_list': ['0']}]
165
166 {% if role.name != 'Compute' %}
167   {{role.name}}SchedulerHints:
168 {% else %}
169   NovaComputeSchedulerHints:
170 {% endif %}
171     type: json
172     description: Optional scheduler hints to pass to nova
173     default: {}
174 {% endfor %}
175
176   # Identifiers to trigger tasks on nodes
177   UpdateIdentifier:
178     default: ''
179     type: string
180     description: >
181       Setting to a previously unused value during stack-update will trigger
182       package update on all nodes
183   DeployIdentifier:
184     default: ''
185     type: string
186     description: >
187       Setting this to a unique value will re-run any deployment tasks which
188       perform configuration on a Heat stack-update.
189   AddVipsToEtcHosts:
190     default: True
191     type: boolean
192     description: >
193       Set to true to append per network Vips to /etc/hosts on each node.
194
195 conditions:
196   add_vips_to_etc_hosts: {equals : [{get_param: AddVipsToEtcHosts}, True]}
197
198 resources:
199
200   VipHosts:
201     type: OS::Heat::Value
202     properties:
203       type: string
204       value:
205         list_join:
206         - "\n"
207         - - str_replace:
208               template: IP  HOST
209               params:
210                 IP: {get_attr: [VipMap, net_ip_map, external]}
211                 HOST: {get_param: CloudName}
212           - str_replace:
213               template: IP  HOST
214               params:
215                 IP: {get_attr: [VipMap, net_ip_map, ctlplane]}
216                 HOST: {get_param: CloudNameCtlplane}
217           - str_replace:
218               template: IP  HOST
219               params:
220                 IP: {get_attr: [VipMap, net_ip_map, internal_api]}
221                 HOST: {get_param: CloudNameInternal}
222           - str_replace:
223               template: IP  HOST
224               params:
225                 IP: {get_attr: [VipMap, net_ip_map, storage]}
226                 HOST: {get_param: CloudNameStorage}
227           - str_replace:
228               template: IP  HOST
229               params:
230                 IP: {get_attr: [VipMap, net_ip_map, storage_mgmt]}
231                 HOST: {get_param: CloudNameStorageManagement}
232
233   HeatAuthEncryptionKey:
234     type: OS::Heat::RandomString
235
236   PcsdPassword:
237     type: OS::Heat::RandomString
238     properties:
239       length: 16
240
241   HorizonSecret:
242     type: OS::Heat::RandomString
243     properties:
244       length: 10
245
246   ServiceNetMap:
247     type: OS::TripleO::ServiceNetMap
248
249   EndpointMap:
250     type: OS::TripleO::EndpointMap
251     properties:
252       CloudEndpoints:
253         external: {get_param: CloudName}
254         internal_api: {get_param: CloudNameInternal}
255         storage: {get_param: CloudNameStorage}
256         storage_mgmt: {get_param: CloudNameStorageManagement}
257         ctlplane: {get_param: CloudNameCtlplane}
258       NetIpMap: {get_attr: [VipMap, net_ip_map]}
259       ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
260
261   EndpointMapData:
262     type: OS::Heat::Value
263     properties:
264       type: json
265       value: {get_attr: [EndpointMap, endpoint_map]}
266
267   SshKnownHostsConfig:
268     type: OS::TripleO::Ssh::KnownHostsConfig
269     properties:
270       known_hosts:
271         list_join:
272           - ''
273           {% for role in roles %}
274           - {get_attr: [{{role.name}}, known_hosts_entry]}
275           {% endfor %}
276
277   # Jinja loop for Role in roles_data.yaml
278 {% for role in roles %}
279   # Resources generated for {{role.name}} Role
280   {{role.name}}ServiceChain:
281     type: OS::TripleO::Services
282     properties:
283       Services:
284         get_param: {{role.name}}Services
285       ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
286       EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
287       DefaultPasswords: {get_attr: [DefaultPasswords, passwords]}
288
289   # Filter any null/None service_names which may be present due to mapping
290   # of services to OS::Heat::None
291   {{role.name}}ServiceNames:
292     type: OS::Heat::Value
293     depends_on: {{role.name}}ServiceChain
294     properties:
295       type: comma_delimited_list
296       value:
297         yaql:
298           expression: coalesce($.data, []).where($ != null)
299           data: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
300
301   {{role.name}}HostsDeployment:
302     type: OS::Heat::StructuredDeployments
303     properties:
304       name: {{role.name}}HostsDeployment
305       config: {get_attr: [hostsConfig, config_id]}
306       servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
307
308   {{role.name}}SshKnownHostsDeployment:
309     type: OS::Heat::StructuredDeployments
310     properties:
311       name: {{role.name}}SshKnownHostsDeployment
312       config: {get_resource: SshKnownHostsConfig}
313       servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
314
315   {{role.name}}AllNodesDeployment:
316     type: OS::Heat::StructuredDeployments
317     depends_on:
318 {% for role_inner in roles %}
319       - {{role_inner.name}}HostsDeployment
320 {% endfor %}
321     properties:
322       name: {{role.name}}AllNodesDeployment
323       config: {get_attr: [allNodesConfig, config_id]}
324       servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
325       input_values:
326         # Note we have to use yaql to look up the first hostname/ip in the
327         # list because heat path based attributes operate on the attribute
328         # inside the ResourceGroup, not the exposed list ref discussion in
329         # https://bugs.launchpad.net/heat/+bug/1640488
330         # The coalesce is needed because $.data is None during heat validation
331         bootstrap_nodeid:
332           yaql:
333             expression: coalesce($.data, []).first(null)
334             data: {get_attr: [{{role.name}}, hostname]}
335         bootstrap_nodeid_ip:
336           yaql:
337             expression: coalesce($.data, []).first(null)
338             data: {get_attr: [{{role.name}}, ip_address]}
339
340   {{role.name}}AllNodesValidationDeployment:
341     type: OS::Heat::StructuredDeployments
342     depends_on: {{role.name}}AllNodesDeployment
343     properties:
344       name: {{role.name}}AllNodesValidationDeployment
345       config: {get_resource: AllNodesValidationConfig}
346       servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
347
348   {{role.name}}IpListMap:
349     type: OS::TripleO::Network::Ports::NetIpListMap
350     properties:
351       ControlPlaneIpList: {get_attr: [{{role.name}}, ip_address]}
352       ExternalIpList: {get_attr: [{{role.name}}, external_ip_address]}
353       InternalApiIpList: {get_attr: [{{role.name}}, internal_api_ip_address]}
354       StorageIpList: {get_attr: [{{role.name}}, storage_ip_address]}
355       StorageMgmtIpList: {get_attr: [{{role.name}}, storage_mgmt_ip_address]}
356       TenantIpList: {get_attr: [{{role.name}}, tenant_ip_address]}
357       ManagementIpList: {get_attr: [{{role.name}}, management_ip_address]}
358       EnabledServices: {get_attr: [{{role.name}}ServiceNames, value]}
359       ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
360       ServiceHostnameList: {get_attr: [{{role.name}}, hostname]}
361       NetworkHostnameMap:
362         # Note (shardy) this somewhat complex yaql may be replaced
363         # with a map_deep_merge function in ocata.  It merges the
364         # list of maps, but appends to colliding lists so we can
365         # create a map of lists for all nodes for each network
366         yaql:
367           expression: dict($.data.where($ != null).flatten().selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
368           data:
369             - {get_attr: [{{role.name}}, hostname_map]}
370
371   {{role.name}}:
372     type: OS::Heat::ResourceGroup
373     depends_on: Networks
374     update_policy:
375       batch_create:
376         max_batch_size: {get_param: NodeCreateBatchSize}
377     properties:
378       count: {get_param: {{role.name}}Count}
379       removal_policies: {get_param: {{role.name}}RemovalPolicies}
380       resource_def:
381         type: OS::TripleO::{{role.name}}
382         properties:
383           CloudDomain: {get_param: CloudDomain}
384           ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
385           EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
386           Hostname:
387             str_replace:
388               template: {get_param: {{role.name}}HostnameFormat}
389               params:
390                 '%stackname%': {get_param: 'OS::stack_name'}
391           NodeIndex: '%index%'
392   {% if role.name != 'Compute' %}
393           {{role.name}}SchedulerHints: {get_param: {{role.name}}SchedulerHints}
394   {% else %}
395           NovaComputeSchedulerHints: {get_param: NovaComputeSchedulerHints}
396   {% endif %}
397           ServiceConfigSettings:
398             map_merge:
399               -  get_attr: [{{role.name}}ServiceChain, role_data, config_settings]
400           {% for r in roles %}
401               - get_attr: [{{r.name}}ServiceChain, role_data, global_config_settings]
402           {% endfor %}
403               # This next step combines two yaql passes:
404               # - The inner one does a deep merge on the service_config_settings for all roles
405               # - The outer one filters the map based on the services enabled for the role
406               #   then merges the result into one map.
407               - yaql:
408                   expression: let(root => $) -> $.data.map.items().where($[0] in coalesce($root.data.services, [])).select($[1]).reduce($1.mergeWith($2), {})
409                   data:
410                     map:
411                       yaql:
412                         expression: $.data.where($ != null).reduce($1.mergeWith($2), {})
413                         data:
414                         {% for r in roles %}
415                           - get_attr: [{{r.name}}ServiceChain, role_data, service_config_settings]
416                         {% endfor %}
417                     services: {get_attr: [{{role.name}}ServiceNames, value]}
418           ServiceNames: {get_attr: [{{role.name}}ServiceNames, value]}
419           MonitoringSubscriptions: {get_attr: [{{role.name}}ServiceChain, role_data, monitoring_subscriptions]}
420           ServiceMetadataSettings: {get_attr: [{{role.name}}ServiceChain, role_data, service_metadata_settings]}
421 {% endfor %}
422
423   hostsConfig:
424     type: OS::TripleO::Hosts::SoftwareConfig
425     properties:
426       hosts:
427         list_join:
428         - "\n"
429         - - if:
430             - add_vips_to_etc_hosts
431             - {get_attr: [VipHosts, value]}
432             - ''
433         -
434 {% for role in roles %}
435           - list_join:
436             - ""
437             - {get_attr: [{{role.name}}, hosts_entry]}
438 {% endfor %}
439
440   allNodesConfig:
441     type: OS::TripleO::AllNodes::SoftwareConfig
442     properties:
443       cloud_name_external: {get_param: CloudName}
444       cloud_name_internal_api: {get_param: CloudNameInternal}
445       cloud_name_storage: {get_param: CloudNameStorage}
446       cloud_name_storage_mgmt: {get_param: CloudNameStorageManagement}
447       cloud_name_ctlplane: {get_param: CloudNameCtlplane}
448       enabled_services:
449         list_join:
450           - ','
451 {% for role in roles %}
452           - {get_attr: [{{role.name}}ServiceNames, value]}
453 {% endfor %}
454       logging_groups:
455         yaql:
456           expression: >
457             $.data.groups.flatten()
458           data:
459             groups:
460 {% for role in roles %}
461               - {get_attr: [{{role.name}}ServiceChain, role_data, logging_groups]}
462 {% endfor %}
463       logging_sources:
464         yaql:
465           expression: >
466             $.data.sources.flatten()
467           data:
468             sources:
469 {% for role in roles %}
470               - {get_attr: [{{role.name}}ServiceChain, role_data, logging_sources]}
471 {% endfor %}
472       controller_ips: {get_attr: [{{primary_role_name}}, ip_address]}
473       controller_names: {get_attr: [{{primary_role_name}}, hostname]}
474       service_ips:
475         # Note (shardy) this somewhat complex yaql may be replaced
476         # with a map_deep_merge function in ocata.  It merges the
477         # list of maps, but appends to colliding lists when a service
478         # is deployed on more than one role
479         yaql:
480           expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
481           data:
482             l:
483 {% for role in roles %}
484               - {get_attr: [{{role.name}}IpListMap, service_ips]}
485 {% endfor %}
486       service_node_names:
487         yaql:
488           expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
489           data:
490             l:
491 {% for role in roles %}
492               - {get_attr: [{{role.name}}IpListMap, service_hostnames]}
493 {% endfor %}
494       short_service_node_names:
495         yaql:
496           expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
497           data:
498             l:
499 {% for role in roles %}
500               - {get_attr: [{{role.name}}IpListMap, short_service_hostnames]}
501 {% endfor %}
502       short_service_bootstrap_node:
503         yaql:
504           expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten().first()]))
505           data:
506             l:
507 {% for role in roles %}
508               - {get_attr: [{{role.name}}IpListMap, short_service_bootstrap_hostnames]}
509 {% endfor %}
510       # FIXME(shardy): These require further work to move into service_ips
511       memcache_node_ips: {get_attr: [{{primary_role_name}}IpListMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, MemcachedNetwork]}]}
512       NetVipMap: {get_attr: [VipMap, net_ip_map]}
513       RedisVirtualIP: {get_attr: [RedisVirtualIP, ip_address]}
514       ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
515       DeployIdentifier: {get_param: DeployIdentifier}
516       UpdateIdentifier: {get_param: UpdateIdentifier}
517
518   MysqlRootPassword:
519     type: OS::Heat::RandomString
520     properties:
521       length: 10
522
523   RabbitCookie:
524     type: OS::Heat::RandomString
525     properties:
526       length: 20
527       salt: {get_param: RabbitCookieSalt}
528
529   DefaultPasswords:
530     type: OS::TripleO::DefaultPasswords
531     properties:
532       DefaultMysqlRootPassword: {get_attr: [MysqlRootPassword, value]}
533       DefaultRabbitCookie: {get_attr: [RabbitCookie, value]}
534       DefaultHeatAuthEncryptionKey: {get_attr: [HeatAuthEncryptionKey, value]}
535       DefaultPcsdPassword: {get_attr: [PcsdPassword, value]}
536       DefaultHorizonSecret: {get_attr: [HorizonSecret, value]}
537
538   # creates the network architecture
539   Networks:
540     type: OS::TripleO::Network
541
542   ControlVirtualIP:
543     type: OS::TripleO::Network::Ports::ControlPlaneVipPort
544     depends_on: Networks
545     properties:
546       name: control_virtual_ip
547       network: {get_param: NeutronControlPlaneID}
548       fixed_ips: {get_param: ControlFixedIPs}
549       replacement_policy: AUTO
550
551   RedisVirtualIP:
552     depends_on: Networks
553     type: OS::TripleO::Network::Ports::RedisVipPort
554     properties:
555       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
556       ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
557       PortName: redis_virtual_ip
558       NetworkName: {get_attr: [ServiceNetMap, service_net_map, RedisNetwork]}
559       ServiceName: redis
560       FixedIPs: {get_param: RedisVirtualFixedIPs}
561
562   # The public VIP is on the External net, falls back to ctlplane
563   PublicVirtualIP:
564     depends_on: Networks
565     type: OS::TripleO::Network::Ports::ExternalVipPort
566     properties:
567       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
568       ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
569       PortName: public_virtual_ip
570       FixedIPs: {get_param: PublicVirtualFixedIPs}
571
572   InternalApiVirtualIP:
573     depends_on: Networks
574     type: OS::TripleO::Network::Ports::InternalApiVipPort
575     properties:
576       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
577       PortName: internal_api_virtual_ip
578       FixedIPs: {get_param: InternalApiVirtualFixedIPs}
579
580   StorageVirtualIP:
581     depends_on: Networks
582     type: OS::TripleO::Network::Ports::StorageVipPort
583     properties:
584       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
585       PortName: storage_virtual_ip
586       FixedIPs: {get_param: StorageVirtualFixedIPs}
587
588   StorageMgmtVirtualIP:
589     depends_on: Networks
590     type: OS::TripleO::Network::Ports::StorageMgmtVipPort
591     properties:
592       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
593       PortName: storage_management_virtual_ip
594       FixedIPs: {get_param: StorageMgmtVirtualFixedIPs}
595
596   VipMap:
597     type: OS::TripleO::Network::Ports::NetVipMap
598     properties:
599       ControlPlaneIp: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
600       ExternalIp: {get_attr: [PublicVirtualIP, ip_address]}
601       ExternalIpUri: {get_attr: [PublicVirtualIP, ip_address_uri]}
602       InternalApiIp: {get_attr: [InternalApiVirtualIP, ip_address]}
603       InternalApiIpUri: {get_attr: [InternalApiVirtualIP, ip_address_uri]}
604       StorageIp: {get_attr: [StorageVirtualIP, ip_address]}
605       StorageIpUri: {get_attr: [StorageVirtualIP, ip_address_uri]}
606       StorageMgmtIp: {get_attr: [StorageMgmtVirtualIP, ip_address]}
607       StorageMgmtIpUri: {get_attr: [StorageMgmtVirtualIP, ip_address_uri]}
608       # No tenant or management VIP required
609
610   # All Nodes Validations
611   AllNodesValidationConfig:
612     type: OS::TripleO::AllNodes::Validation
613     properties:
614       PingTestIps:
615         list_join:
616         - ' '
617         - - yaql:
618               expression: coalesce($.data, []).first(null)
619               data: {get_attr: [{{primary_role_name}}, external_ip_address]}
620           - yaql:
621               expression: coalesce($.data, []).first(null)
622               data: {get_attr: [{{primary_role_name}}, internal_api_ip_address]}
623           - yaql:
624               expression: coalesce($.data, []).first(null)
625               data: {get_attr: [{{primary_role_name}}, storage_ip_address]}
626           - yaql:
627               expression: coalesce($.data, []).first(null)
628               data: {get_attr: [{{primary_role_name}}, storage_mgmt_ip_address]}
629           - yaql:
630               expression: coalesce($.data, []).first(null)
631               data: {get_attr: [{{primary_role_name}}, tenant_ip_address]}
632           - yaql:
633               expression: coalesce($.data, []).first(null)
634               data: {get_attr: [{{primary_role_name}}, management_ip_address]}
635
636   UpdateWorkflow:
637     type: OS::TripleO::Tasks::UpdateWorkflow
638     depends_on:
639 {% for role in roles %}
640       - {{role.name}}AllNodesDeployment
641 {% endfor %}
642     properties:
643       servers:
644 {% for role in roles %}
645         {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
646 {% endfor %}
647       input_values:
648         deploy_identifier: {get_param: DeployIdentifier}
649         update_identifier: {get_param: UpdateIdentifier}
650
651   # Optional ExtraConfig for all nodes - all roles are passed in here, but
652   # the nested template may configure each role differently (or not at all)
653   AllNodesExtraConfig:
654     type: OS::TripleO::AllNodesExtraConfig
655     depends_on:
656       - UpdateWorkflow
657 {% for role in roles %}
658       - {{role.name}}AllNodesValidationDeployment
659 {% endfor %}
660     properties:
661       servers:
662 {% for role in roles %}
663         {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
664 {% endfor %}
665
666   # Post deployment steps for all roles
667   AllNodesDeploySteps:
668     type: OS::TripleO::PostDeploySteps
669     depends_on:
670 {% for role in roles %}
671       - {{role.name}}AllNodesDeployment
672 {% endfor %}
673     properties:
674       servers:
675 {% for role in roles %}
676         {{role.name}}: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
677 {% endfor %}
678       EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
679       role_data:
680 {% for role in roles %}
681         {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data]}
682 {% endfor %}
683
684 outputs:
685   ManagedEndpoints:
686     description: Asserts that the keystone endpoints have been provisioned.
687     value: true
688   KeystoneURL:
689     description: URL for the Overcloud Keystone service
690     value: {get_attr: [EndpointMapData, value, KeystonePublic, uri]}
691   KeystoneAdminVip:
692     description: Keystone Admin VIP endpoint
693     value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystoneAdminApiNetwork]}]}
694   EndpointMap:
695     description: |
696       Mapping of the resources with the needed info for their endpoints.
697       This includes the protocol used, the IP, port and also a full
698       representation of the URI.
699     value: {get_attr: [EndpointMapData, value]}
700   HostsEntry:
701     description: |
702       The content that should be appended to your /etc/hosts if you want to get
703       hostname-based access to the deployed nodes (useful for testing without
704       setting up a DNS).
705     value:
706       list_join:
707       - "\n"
708       - - {get_attr: [hostsConfig, hosts_entries]}
709       - - {get_attr: [VipHosts, value]}
710   EnabledServices:
711     description: The services enabled on each role
712     value:
713 {% for role in roles %}
714       {{role.name}}: {get_attr: [{{role.name}}ServiceNames, value]}
715 {% endfor %}
716   RoleData:
717     description: The configuration data associated with each role
718     value:
719 {% for role in roles %}
720       {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data]}
721 {% endfor %}
722   RoleNetIpMap:
723     description: Mapping of each network to a list of IPs for each role
724     value:
725 {% for role in roles %}
726       {{role.name}}: {get_attr: [{{role.name}}IpListMap, net_ip_map]}
727 {% endfor %}