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) -%}
8 {%- set primary_role_name = primary_role[0].name -%}
9 # primary role is: {{primary_role_name}}
10 heat_template_version: pike
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.
19 # TODO(shadower): we should probably use the parameter groups to put
23 # Common parameters (not specific to a role)
25 default: overcloud.localdomain
26 description: The DNS name of this cloud. E.g. ci-overcloud.tripleo.org
29 default: overcloud.internalapi.localdomain
31 The DNS name of this cloud's internal API endpoint. E.g.
32 'ci-overcloud.internalapi.tripleo.org'.
35 default: overcloud.storage.localdomain
37 The DNS name of this cloud's storage endpoint. E.g.
38 'ci-overcloud.storage.tripleo.org'.
40 CloudNameStorageManagement:
41 default: overcloud.storagemgmt.localdomain
43 The DNS name of this cloud's storage management endpoint. E.g.
44 'ci-overcloud.storagemgmt.tripleo.org'.
47 default: overcloud.ctlplane.localdomain
49 The DNS name of this cloud's provisioning network endpoint. E.g.
50 'ci-overcloud.ctlplane.tripleo.org'.
55 Control the IP allocation for the ControlVirtualIP port. E.g.
56 [{'ip_address':'1.2.3.4'}]
61 Additional hiera configuration to inject into the cluster.
63 {%- for role in roles %}
64 {{role.name}}ExtraConfig:
67 Role specific additional hiera configuration to inject into the cluster.
70 controllerExtraConfig:
73 DEPRECATED use ControllerExtraConfig instead
75 NovaComputeExtraConfig:
78 DEPRECATED use ComputeExtraConfig instead
80 InternalApiVirtualFixedIPs:
83 Control the IP allocation for the InternalApiVirtualInterface port. E.g.
84 [{'ip_address':'1.2.3.4'}]
86 NeutronControlPlaneID:
89 description: Neutron ID or name for ctlplane network.
90 NeutronPublicInterface:
92 description: Which interface to add to the NeutronPhysicalBridge.
94 PublicVirtualFixedIPs:
97 Control the IP allocation for the PublicVirtualInterface port. E.g.
98 [{'ip_address':'1.2.3.4'}]
103 description: Salt for the rabbit cookie, change this to force the randomly generated rabbit cookie to change.
104 StorageVirtualFixedIPs:
107 Control the IP allocation for the StorageVirtualInterface port. E.g.
108 [{'ip_address':'1.2.3.4'}]
110 StorageMgmtVirtualFixedIPs:
113 Control the IP allocation for the StorageMgmgVirtualInterface port. E.g.
114 [{'ip_address':'1.2.3.4'}]
116 RedisVirtualFixedIPs:
119 Control the IP allocation for the virtual IP used by Redis. E.g.
120 [{'ip_address':'1.2.3.4'}]
123 default: 'localdomain'
126 The DNS domain used for the hosts. This must match the
127 overcloud_domain_name configured on the undercloud.
131 Extra properties or metadata passed to Nova for the created nodes in
132 the overcloud. It's accessible via the Nova metadata API.
135 # Compute-specific params
136 # FIXME(shardy) handle these deprecated names as they don't match compute.yaml
137 HypervisorNeutronPhysicalBridge:
140 An OVS bridge to create on each hypervisor. This defaults to br-ex the
141 same as the control plane nodes, as we have a uniform configuration of
142 the openvswitch agent. Typically should not need to be changed.
144 HypervisorNeutronPublicInterface:
146 description: What interface to add to the HypervisorNeutronPhysicalBridge.
151 description: Maxiumum batch size for creating nodes
154 # Jinja loop for Role in role_data.yaml
155 {% for role in roles %}
156 # Parameters generated for {{role.name}} Role
157 {{role.name}}Services:
158 description: A list of service resources (configured in the Heat
159 resource_registry) which represent nested stacks
160 for each service that should get installed on the {{role.name}} role.
161 type: comma_delimited_list
164 description: Number of {{role.name}} nodes to deploy
166 default: {{role.CountDefault|default(0)}}
168 {{role.name}}HostnameFormat:
171 Format for {{role.name}} node hostnames
172 Note %index% is translated into the index of the node, e.g 0/1/2 etc
173 and %stackname% is replaced with the stack name e.g overcloud
174 {% if role.HostnameFormatDefault %}
175 default: "{{role.HostnameFormatDefault}}"
177 default: "%stackname%-{{role.name.lower()}}-%index%"
179 {{role.name}}RemovalPolicies:
183 List of resources to be removed from {{role.name}} ResourceGroup when
184 doing an update which requires removal of specific resources.
185 Example format ComputeRemovalPolicies: [{'resource_list': ['0']}]
187 {% if role.name != 'Compute' %}
188 {{role.name}}SchedulerHints:
189 description: Optional scheduler hints to pass to nova
191 NovaComputeSchedulerHints:
192 description: DEPRECATED - use ComputeSchedulerHints instead
197 {{role.name}}Parameters:
199 description: Optional Role Specific parameters to be provided to service
203 # Identifiers to trigger tasks on nodes
208 Setting to a previously unused value during stack-update will trigger
209 package update on all nodes
214 Setting this to a unique value will re-run any deployment tasks which
215 perform configuration on a Heat stack-update.
220 Set to true to append per network Vips to /etc/hosts on each node.
222 DeploymentServerBlacklist:
224 type: comma_delimited_list
226 List of server hostnames to blacklist from any triggered deployments.
229 add_vips_to_etc_hosts: {equals : [{get_param: AddVipsToEtcHosts}, True]}
234 type: OS::Heat::Value
243 IP: {get_attr: [VipMap, net_ip_map, external]}
244 HOST: {get_param: CloudName}
248 IP: {get_attr: [VipMap, net_ip_map, ctlplane]}
249 HOST: {get_param: CloudNameCtlplane}
253 IP: {get_attr: [VipMap, net_ip_map, internal_api]}
254 HOST: {get_param: CloudNameInternal}
258 IP: {get_attr: [VipMap, net_ip_map, storage]}
259 HOST: {get_param: CloudNameStorage}
263 IP: {get_attr: [VipMap, net_ip_map, storage_mgmt]}
264 HOST: {get_param: CloudNameStorageManagement}
266 HeatAuthEncryptionKey:
267 type: OS::TripleO::RandomString
270 type: OS::TripleO::RandomString
275 type: OS::TripleO::RandomString
280 type: OS::Heat::Value
286 - {get_attr: [Networks, net_cidr_map]}
287 - ctlplane: {get_attr: [ControlVirtualIP, subnets, 0, cidr]}
289 ctlplane: {get_param: NeutronControlPlaneID}
291 disabled: {get_attr: [ControlVirtualIP, subnets, 0, cidr]}
294 type: OS::TripleO::ServiceNetMap
297 type: OS::TripleO::EndpointMap
300 external: {get_param: CloudName}
301 internal_api: {get_param: CloudNameInternal}
302 storage: {get_param: CloudNameStorage}
303 storage_mgmt: {get_param: CloudNameStorageManagement}
304 ctlplane: {get_param: CloudNameCtlplane}
305 NetIpMap: {get_attr: [VipMap, net_ip_map]}
306 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
309 type: OS::Heat::Value
312 value: {get_attr: [EndpointMap, endpoint_map]}
315 type: OS::TripleO::Ssh::KnownHostsConfig
320 {% for role in roles %}
321 - {get_attr: [{{role.name}}, known_hosts_entry]}
324 # Jinja loop for Role in roles_data.yaml
325 {% for role in roles %}
326 # Resources generated for {{role.name}} Role
327 {{role.name}}ServiceChain:
328 type: OS::TripleO::Services
331 get_param: {{role.name}}Services
332 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
334 net_cidr_map: {get_attr: [NetCidrMapValue, value]}
335 EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
336 DefaultPasswords: {get_attr: [DefaultPasswords, passwords]}
337 RoleName: {{role.name}}
338 RoleParameters: {get_param: {{role.name}}Parameters}
340 # Lookup of role_data via heat outputs is slow, so workaround this by caching
341 # the value in an OS::Heat::Value resource
342 {{role.name}}ServiceChainRoleData:
343 type: OS::Heat::Value
346 value: {get_attr: [{{role.name}}ServiceChain, role_data]}
348 {{role.name}}ServiceConfigSettings:
349 type: OS::Heat::Value
354 - get_attr: [{{role.name}}ServiceChainRoleData, value, config_settings]
356 - get_attr: [{{r.name}}ServiceChainRoleData, value, global_config_settings]
358 # This next step combines two yaql passes:
359 # - The inner one does a deep merge on the service_config_settings for all roles
360 # - The outer one filters the map based on the services enabled for the role
361 # then merges the result into one map.
363 expression: let(root => $) -> $.data.map.items().where($[0] in coalesce($root.data.services, [])).select($[1]).reduce($1.mergeWith($2), {})
367 expression: $.data.where($ != null).reduce($1.mergeWith($2), {})
370 - get_attr: [{{r.name}}ServiceChainRoleData, value, service_config_settings]
372 services: {get_attr: [{{role.name}}ServiceNames, value]}
374 {{role.name}}MergedConfigSettings:
375 type: OS::Heat::Value
380 global_config_settings: {}
381 service_config_settings: {}
382 merged_config_settings:
384 - get_attr: [{{role.name}}ServiceConfigSettings, value]
385 - get_param: ExtraConfig
386 {%- if role.name == 'Controller' %}
388 - get_param: controllerExtraConfig
389 - get_param: {{role.name}}ExtraConfig
390 {%- elif role.name == 'Compute' %}
392 - get_param: NovaComputeExtraConfig
393 - get_param: {{role.name}}ExtraConfig
395 - get_param: {{role.name}}ExtraConfig
398 # Filter any null/None service_names which may be present due to mapping
399 # of services to OS::Heat::None
400 {{role.name}}ServiceNames:
401 type: OS::Heat::Value
402 depends_on: {{role.name}}ServiceChain
404 type: comma_delimited_list
407 expression: coalesce($.data, []).where($ != null)
408 data: {get_attr: [{{role.name}}ServiceChainRoleData, value, service_names]}
410 {{role.name}}HostsDeployment:
411 type: OS::Heat::StructuredDeployments
413 name: {{role.name}}HostsDeployment
414 config: {get_attr: [hostsConfig, config_id]}
415 servers: {get_attr: [{{role.name}}Servers, value]}
417 {{role.name}}SshKnownHostsDeployment:
418 type: OS::Heat::StructuredDeployments
420 name: {{role.name}}SshKnownHostsDeployment
421 config: {get_resource: SshKnownHostsConfig}
422 servers: {get_attr: [{{role.name}}Servers, value]}
424 {{role.name}}AllNodesDeployment:
425 type: OS::TripleO::AllNodesDeployment
427 {% for role_inner in roles %}
428 - {{role_inner.name}}HostsDeployment
431 name: {{role.name}}AllNodesDeployment
432 config: {get_attr: [allNodesConfig, config_id]}
433 servers: {get_attr: [{{role.name}}Servers, value]}
435 # Note we have to use yaql to look up the first hostname/ip in the
436 # list because heat path based attributes operate on the attribute
437 # inside the ResourceGroup, not the exposed list ref discussion in
438 # https://bugs.launchpad.net/heat/+bug/1640488
439 # The coalesce is needed because $.data is None during heat validation
442 expression: coalesce($.data, []).first(null)
443 data: {get_attr: [{{role.name}}, hostname]}
446 expression: coalesce($.data, []).first(null)
447 data: {get_attr: [{{role.name}}, ip_address]}
449 {{role.name}}AllNodesValidationDeployment:
450 type: OS::Heat::StructuredDeployments
451 depends_on: {{role.name}}AllNodesDeployment
453 name: {{role.name}}AllNodesValidationDeployment
454 config: {get_resource: AllNodesValidationConfig}
455 servers: {get_attr: [{{role.name}}Servers, value]}
457 {{role.name}}IpListMap:
458 type: OS::TripleO::Network::Ports::NetIpListMap
460 ControlPlaneIpList: {get_attr: [{{role.name}}, ip_address]}
461 ExternalIpList: {get_attr: [{{role.name}}, external_ip_address]}
462 InternalApiIpList: {get_attr: [{{role.name}}, internal_api_ip_address]}
463 StorageIpList: {get_attr: [{{role.name}}, storage_ip_address]}
464 StorageMgmtIpList: {get_attr: [{{role.name}}, storage_mgmt_ip_address]}
465 TenantIpList: {get_attr: [{{role.name}}, tenant_ip_address]}
466 ManagementIpList: {get_attr: [{{role.name}}, management_ip_address]}
467 EnabledServices: {get_attr: [{{role.name}}ServiceNames, value]}
468 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
469 ServiceHostnameList: {get_attr: [{{role.name}}, hostname]}
470 NetworkHostnameMap: {get_attr: [{{role.name}}NetworkHostnameMap, value]}
472 {{role.name}}NetworkHostnameMap:
473 type: OS::Heat::Value
477 # Note (shardy) this somewhat complex yaql may be replaced
478 # with a map_deep_merge function in ocata. It merges the
479 # list of maps, but appends to colliding lists so we can
480 # create a map of lists for all nodes for each network
482 expression: dict($.data.where($ != null).flatten().selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
484 - {get_attr: [{{role.name}}, hostname_map]}
487 type: OS::Heat::ResourceGroup
491 max_batch_size: {get_param: NodeCreateBatchSize}
493 count: {get_param: {{role.name}}Count}
494 removal_policies: {get_param: {{role.name}}RemovalPolicies}
496 type: OS::TripleO::{{role.name}}
498 CloudDomain: {get_param: CloudDomain}
499 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
500 EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
503 template: {get_param: {{role.name}}HostnameFormat}
505 '%stackname%': {get_param: 'OS::stack_name'}
507 {% if role.name != 'Compute' %}
508 {{role.name}}SchedulerHints: {get_param: {{role.name}}SchedulerHints}
510 NovaComputeSchedulerHints: {get_param: NovaComputeSchedulerHints}
512 ServiceConfigSettings: {get_attr: [{{role.name}}ServiceConfigSettings, value]}
513 ServiceNames: {get_attr: [{{role.name}}ServiceNames, value]}
514 MonitoringSubscriptions: {get_attr: [{{role.name}}ServiceChainRoleData, value, monitoring_subscriptions]}
515 ServiceMetadataSettings: {get_attr: [{{role.name}}ServiceChainRoleData, value, service_metadata_settings]}
516 DeploymentServerBlacklistDict: {get_attr: [DeploymentServerBlacklistDict, value]}
517 RoleParameters: {get_param: {{role.name}}Parameters}
520 {% for role in roles %}
521 {{role.name}}Servers:
522 type: OS::Heat::Value
523 depends_on: {{role.name}}
528 expression: let(servers=>switch(isDict($.data.servers) => $.data.servers, true => {})) -> $servers.deleteAll($servers.keys().where($servers[$] = null))
530 servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
533 # This is a different format to *Servers, as it creates a map of lists
534 # whereas *Servers creates a map of maps with keys of the nested resource names
536 type: OS::Heat::Value
540 {% for role in roles %}
541 {{role.name}}: {get_attr: [{{role.name}}, nova_server_resource]}
545 expression: coalesce($.data, []).first(null)
546 data: {get_attr: [{{primary_role_name}}, nova_server_resource]}
548 # This resource just creates a dict out of the DeploymentServerBlacklist,
549 # which is a list. The dict is used in the role templates to set a condition
550 # on whether to create the deployment resources. We can't use the list
551 # directly because there is no way to ask Heat if a list contains a specific
553 DeploymentServerBlacklistDict:
554 type: OS::Heat::Value
563 hostname: {get_param: DeploymentServerBlacklist}
566 type: OS::TripleO::Hosts::SoftwareConfig
572 - add_vips_to_etc_hosts
573 - {get_attr: [VipHosts, value]}
576 {% for role in roles %}
579 - {get_attr: [{{role.name}}, hosts_entry]}
583 type: OS::TripleO::AllNodes::SoftwareConfig
585 cloud_name_external: {get_param: CloudName}
586 cloud_name_internal_api: {get_param: CloudNameInternal}
587 cloud_name_storage: {get_param: CloudNameStorage}
588 cloud_name_storage_mgmt: {get_param: CloudNameStorageManagement}
589 cloud_name_ctlplane: {get_param: CloudNameCtlplane}
593 {% for role in roles %}
594 - {get_attr: [{{role.name}}ServiceNames, value]}
599 $.data.groups.flatten()
602 {% for role in roles %}
603 - {get_attr: [{{role.name}}ServiceChainRoleData, value, logging_groups]}
608 $.data.sources.flatten()
611 {% for role in roles %}
612 - {get_attr: [{{role.name}}ServiceChainRoleData, value, logging_sources]}
614 controller_ips: {get_attr: [{{primary_role_name}}, ip_address]}
615 controller_names: {get_attr: [{{primary_role_name}}, hostname]}
617 # Note (shardy) this somewhat complex yaql may be replaced
618 # with a map_deep_merge function in ocata. It merges the
619 # list of maps, but appends to colliding lists when a service
620 # is deployed on more than one role
622 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
625 {% for role in roles %}
626 - {get_attr: [{{role.name}}IpListMap, service_ips]}
630 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
633 {% for role in roles %}
634 - {get_attr: [{{role.name}}IpListMap, service_hostnames]}
636 short_service_node_names:
638 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
641 {% for role in roles %}
642 - {get_attr: [{{role.name}}IpListMap, short_service_hostnames]}
644 short_service_bootstrap_node:
646 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten().first()]))
649 {% for role in roles %}
650 - {get_attr: [{{role.name}}IpListMap, short_service_bootstrap_hostnames]}
652 NetVipMap: {get_attr: [VipMap, net_ip_map]}
653 RedisVirtualIP: {get_attr: [RedisVirtualIP, ip_address]}
654 ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
655 DeployIdentifier: {get_param: DeployIdentifier}
656 UpdateIdentifier: {get_param: UpdateIdentifier}
659 type: OS::TripleO::RandomString
664 type: OS::TripleO::RandomString
667 salt: {get_param: RabbitCookieSalt}
670 type: OS::TripleO::DefaultPasswords
672 DefaultMysqlRootPassword: {get_attr: [MysqlRootPassword, value]}
673 DefaultRabbitCookie: {get_attr: [RabbitCookie, value]}
674 DefaultHeatAuthEncryptionKey: {get_attr: [HeatAuthEncryptionKey, value]}
675 DefaultPcsdPassword: {get_attr: [PcsdPassword, value]}
676 DefaultHorizonSecret: {get_attr: [HorizonSecret, value]}
678 # creates the network architecture
680 type: OS::TripleO::Network
683 type: OS::TripleO::Network::Ports::ControlPlaneVipPort
686 name: control_virtual_ip
687 network: {get_param: NeutronControlPlaneID}
688 fixed_ips: {get_param: ControlFixedIPs}
689 replacement_policy: AUTO
693 type: OS::TripleO::Network::Ports::RedisVipPort
695 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
696 ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
697 PortName: redis_virtual_ip
698 NetworkName: {get_attr: [ServiceNetMap, service_net_map, RedisNetwork]}
700 FixedIPs: {get_param: RedisVirtualFixedIPs}
702 # The public VIP is on the External net, falls back to ctlplane
705 type: OS::TripleO::Network::Ports::ExternalVipPort
707 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
708 ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
709 PortName: public_virtual_ip
710 FixedIPs: {get_param: PublicVirtualFixedIPs}
712 InternalApiVirtualIP:
714 type: OS::TripleO::Network::Ports::InternalApiVipPort
716 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
717 PortName: internal_api_virtual_ip
718 FixedIPs: {get_param: InternalApiVirtualFixedIPs}
722 type: OS::TripleO::Network::Ports::StorageVipPort
724 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
725 PortName: storage_virtual_ip
726 FixedIPs: {get_param: StorageVirtualFixedIPs}
728 StorageMgmtVirtualIP:
730 type: OS::TripleO::Network::Ports::StorageMgmtVipPort
732 ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
733 PortName: storage_management_virtual_ip
734 FixedIPs: {get_param: StorageMgmtVirtualFixedIPs}
737 type: OS::TripleO::Network::Ports::NetVipMap
739 ControlPlaneIp: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
740 ExternalIp: {get_attr: [PublicVirtualIP, ip_address]}
741 ExternalIpUri: {get_attr: [PublicVirtualIP, ip_address_uri]}
742 InternalApiIp: {get_attr: [InternalApiVirtualIP, ip_address]}
743 InternalApiIpUri: {get_attr: [InternalApiVirtualIP, ip_address_uri]}
744 StorageIp: {get_attr: [StorageVirtualIP, ip_address]}
745 StorageIpUri: {get_attr: [StorageVirtualIP, ip_address_uri]}
746 StorageMgmtIp: {get_attr: [StorageMgmtVirtualIP, ip_address]}
747 StorageMgmtIpUri: {get_attr: [StorageMgmtVirtualIP, ip_address_uri]}
748 # No tenant or management VIP required
749 # Because of nested get_attr functions in the KeystoneAdminVip output, we
750 # can't determine which attributes of VipMap are used until after
751 # ServiceNetMap's attribute values are available.
752 depends_on: ServiceNetMap
754 # All Nodes Validations
755 AllNodesValidationConfig:
756 type: OS::TripleO::AllNodes::Validation
762 expression: coalesce($.data, []).first(null)
763 data: {get_attr: [{{primary_role_name}}, external_ip_address]}
765 expression: coalesce($.data, []).first(null)
766 data: {get_attr: [{{primary_role_name}}, internal_api_ip_address]}
768 expression: coalesce($.data, []).first(null)
769 data: {get_attr: [{{primary_role_name}}, storage_ip_address]}
771 expression: coalesce($.data, []).first(null)
772 data: {get_attr: [{{primary_role_name}}, storage_mgmt_ip_address]}
774 expression: coalesce($.data, []).first(null)
775 data: {get_attr: [{{primary_role_name}}, tenant_ip_address]}
777 expression: coalesce($.data, []).first(null)
778 data: {get_attr: [{{primary_role_name}}, management_ip_address]}
781 type: OS::TripleO::Tasks::UpdateWorkflow
783 {% for role in roles %}
784 - {{role.name}}AllNodesDeployment
788 {% for role in roles %}
789 {{role.name}}: {get_attr: [{{role.name}}Servers, value]}
792 deploy_identifier: {get_param: DeployIdentifier}
793 update_identifier: {get_param: UpdateIdentifier}
795 # Optional ExtraConfig for all nodes - all roles are passed in here, but
796 # the nested template may configure each role differently (or not at all)
798 type: OS::TripleO::AllNodesExtraConfig
801 {% for role in roles %}
802 - {{role.name}}AllNodesValidationDeployment
806 {% for role in roles %}
807 {{role.name}}: {get_attr: [{{role.name}}Servers, value]}
810 # Post deployment steps for all roles
812 type: OS::TripleO::PostDeploySteps
814 - AllNodesExtraConfig
815 {% for role in roles %}
816 - {{role.name}}AllNodesDeployment
820 {% for role in roles %}
821 {{role.name}}: {get_attr: [{{role.name}}Servers, value]}
823 stack_name: {get_param: 'OS::stack_name'}
824 EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
825 ctlplane_service_ips:
826 # Note (shardy) this somewhat complex yaql may be replaced
827 # with a map_deep_merge function in ocata. It merges the
828 # list of maps, but appends to colliding lists when a service
829 # is deployed on more than one role
831 expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
834 {% for role in roles %}
835 - {get_attr: [{{role.name}}IpListMap, ctlplane_service_ips]}
838 {% for role in roles %}
841 - {get_attr: [{{role.name}}ServiceChainRoleData, value]}
842 - {get_attr: [{{role.name}}MergedConfigSettings, value]}
845 ServerOsCollectConfigData:
846 type: OS::Heat::Value
850 {% for role in roles %}
851 {{role.name}}: {get_attr: [{{role.name}}, attributes, os_collect_config]}
854 DeployedServerEnvironment:
855 type: OS::TripleO::DeployedServerEnvironment
858 {% for role in roles %}
859 {{role.name}}DeployedServerCount: {get_param: {{role.name}}Count}
863 - {get_attr: [VipMap, net_ip_map]}
864 - redis: {get_attr: [RedisVirtualIP, ip_address]}
865 DeployedServerPortMap:
868 {% for role in roles %}
869 - {get_attr: [{{role.name}}, deployed_server_port_map]}
871 DeployedServerDeploymentSwiftDataMap:
874 {% for role in roles %}
875 - {get_attr: [{{role.name}}, deployed_server_deployment_swift_data_map]}
882 - {get_attr: [ServerOsCollectConfigData, value, {{primary_role_name}}, '0', request, metadata_url]}
888 description: Asserts that the keystone endpoints have been provisioned.
891 description: URL for the Overcloud Keystone service
892 value: {get_attr: [EndpointMapData, value, KeystonePublic, uri]}
894 description: Keystone Admin VIP endpoint
895 # Note that these nested get_attr functions require a dependency
896 # relationship between VipMap and ServiceNetMap, since we can't determine
897 # which attributes of VipMap are used until after ServiceNetMap's attribute
898 # values are available. If this is ever reworked to not use nested
899 # get_attr, that dependency can be removed.
900 value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystoneAdminApiNetwork]}]}
903 Mapping of the resources with the needed info for their endpoints.
904 This includes the protocol used, the IP, port and also a full
905 representation of the URI.
906 value: {get_attr: [EndpointMapData, value]}
909 The content that should be appended to your /etc/hosts if you want to get
910 hostname-based access to the deployed nodes (useful for testing without
915 - - {get_attr: [hostsConfig, hosts_entries]}
916 - - {get_attr: [VipHosts, value]}
918 description: The services enabled on each role
920 {% for role in roles %}
921 {{role.name}}: {get_attr: [{{role.name}}ServiceNames, value]}
924 description: The configuration data associated with each role
926 {% for role in roles %}
929 - {get_attr: [{{role.name}}ServiceChainRoleData, value]}
930 - {get_attr: [{{role.name}}MergedConfigSettings, value]}
933 description: The configuration workflows associated with each role
934 value: {get_attr: [AllNodesDeploySteps, RoleConfig]}
936 description: Mapping of each network to a list of IPs for each role
938 {% for role in roles %}
939 {{role.name}}: {get_attr: [{{role.name}}IpListMap, net_ip_map]}
942 description: Mapping of each network to a list of hostnames for each role
944 {% for role in roles %}
945 {{role.name}}: {get_attr: [{{role.name}}NetworkHostnameMap, value]}
947 ServerOsCollectConfigData:
948 description: The os-collect-config configuration associated with each server resource
949 value: {get_attr: [ServerOsCollectConfigData, value]}
951 description: Mapping of each network to VIP addresses. Also includes the Redis VIP.
954 - {get_attr: [VipMap, net_ip_map]}
955 - redis: {get_attr: [RedisVirtualIP, ip_address]}
957 description: Mapping of each role to a list of nova server IDs and the bootstrap ID
958 value: {get_attr: [ServerIdMap, value]}
959 DeployedServerEnvironment:
961 Environment data that can be used as input into the services stack when
963 value: {get_attr: [DeployedServerEnvironment, deployed_server_environment]}