Heat templates for deploying OpenStack
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1216 lines
44KB

  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: rocky
  11. description: >
  12. Deploy an OpenStack environment, consisting of several node types (roles),
  13. Controller, Compute, BlockStorage, SwiftStorage and CephStorage. The Storage
  14. roles enable independent scaling of the storage components, but the minimal
  15. deployment is one Controller and one Compute node.
  16. # TODO(shadower): we should probably use the parameter groups to put
  17. # some order in here.
  18. parameters:
  19. # Common parameters (not specific to
  20. {%- for network in networks if network.vip|default(false) and network.enabled|default(true) %}
  21. {%- if network.name == 'External' %}
  22. # Special case the External hostname param, which is CloudName
  23. CloudName:
  24. default: overcloud.localdomain
  25. description: The DNS name of this cloud. E.g. ci-overcloud.tripleo.org
  26. type: string
  27. # TODO (dsneddon) Legacy name, eventually refactor to match network name
  28. PublicVirtualFixedIPs:
  29. default: []
  30. description: >
  31. Control the IP allocation for the PublicVirtualInterface port. E.g.
  32. [{'ip_address':'1.2.3.4'}]
  33. type: json
  34. {%- elif network.name == 'InternalApi' %}
  35. # Special case the Internal API hostname param, which is CloudNameInternal
  36. CloudNameInternal:
  37. default: overcloud.{{network.name.lower()}}.localdomain
  38. description: >
  39. The DNS name of this cloud's {{network.name_lower}} endpoint. E.g.
  40. 'ci-overcloud.{{network.name.lower()}}.tripleo.org'.
  41. type: string
  42. {%- elif network.name == 'StorageMgmt' %}
  43. # Special case StorageMgmt hostname param, which is CloudNameStorageManagement
  44. CloudNameStorageManagement:
  45. default: overcloud.{{network.name.lower()}}.localdomain
  46. description: >
  47. The DNS name of this cloud's {{network.name_lower}} endpoint. E.g.
  48. 'ci-overcloud.{{network.name.lower()}}.tripleo.org'.
  49. type: string
  50. {%- else %}
  51. CloudName{{network.name}}:
  52. default: overcloud.{{network.name.lower()}}.localdomain
  53. description: >
  54. The DNS name of this cloud's {{network.name_lower}} endpoint. E.g.
  55. 'ci-overcloud.{{network.name.lower()}}.tripleo.org'.
  56. type: string
  57. {%- endif %}
  58. {{network.name}}VirtualFixedIPs:
  59. default: []
  60. description: >
  61. Control the IP allocation for the {{network.name}}VirtualInterface port. E.g.
  62. [{'ip_address':'1.2.3.4'}]
  63. type: json
  64. {%- endfor %}
  65. CloudNameCtlplane:
  66. default: overcloud.ctlplane.localdomain
  67. description: >
  68. The DNS name of this cloud's provisioning network endpoint. E.g.
  69. 'ci-overcloud.ctlplane.tripleo.org'.
  70. type: string
  71. ExtraHostFileEntries:
  72. default: []
  73. description: List of extra hosts entries to be appended to /etc/hosts
  74. type: comma_delimited_list
  75. EndpointMapOverride:
  76. default: {}
  77. description: Can be used to override the calcluated EndpointMap
  78. type: json
  79. ExtraConfig:
  80. default: {}
  81. description: |
  82. Additional hiera configuration to inject into the cluster.
  83. type: json
  84. NeutronControlPlaneID:
  85. default: 'ctlplane'
  86. type: string
  87. description: Neutron ID or name for ctlplane network.
  88. NeutronPhysicalBridge:
  89. default: 'br-ex'
  90. description: An OVS bridge to create for accessing external networks.
  91. type: string
  92. NeutronPublicInterface:
  93. default: nic1
  94. description: Which interface to add to the NeutronPhysicalBridge.
  95. type: string
  96. ControlPlaneSubnet:
  97. description: The name of the undercloud Neutron control plane subnet
  98. default: ctlplane-subnet
  99. type: string
  100. ControlPlaneSubnetCidr:
  101. default: ''
  102. description: >
  103. The subnet CIDR of the control plane network. (The parameter is
  104. automatically resolved from the ctlplane subnet's cidr attribute.)
  105. type: string
  106. ControlFixedIPs:
  107. default: []
  108. description: >
  109. Control the IP allocation for the ControlVirtualIP port. E.g.
  110. [{'ip_address':'1.2.3.4'}]
  111. type: json
  112. RabbitCookieSalt:
  113. type: string
  114. default: unset
  115. description: Salt for the rabbit cookie, change this to force the randomly generated rabbit cookie to change.
  116. RedisVirtualFixedIPs:
  117. default: []
  118. description: >
  119. Control the IP allocation for the virtual IP used by Redis. E.g.
  120. [{'ip_address':'1.2.3.4'}]
  121. type: json
  122. CloudDomain:
  123. default: 'localdomain'
  124. type: string
  125. description: >
  126. The DNS domain used for the hosts. This must match the
  127. overcloud_domain_name configured on the undercloud.
  128. ServerMetadata:
  129. default: {}
  130. description: >
  131. Extra properties or metadata passed to Nova for the created nodes in
  132. the overcloud. It's accessible via the Nova metadata API.
  133. type: json
  134. NetworkDeploymentActions:
  135. type: comma_delimited_list
  136. description: >
  137. Heat action when to apply network configuration changes
  138. default: ['CREATE']
  139. # Compute-specific params
  140. # FIXME(shardy) handle these deprecated names as they don't match compute.yaml
  141. HypervisorNeutronPhysicalBridge:
  142. default: 'br-ex'
  143. description: >
  144. An OVS bridge to create on each hypervisor. This defaults to br-ex the
  145. same as the control plane nodes, as we have a uniform configuration of
  146. the openvswitch agent. Typically should not need to be changed.
  147. type: string
  148. HypervisorNeutronPublicInterface:
  149. default: nic1
  150. description: What interface to add to the HypervisorNeutronPhysicalBridge.
  151. type: string
  152. NodeCreateBatchSize:
  153. default: 30
  154. description: Maxiumum batch size for creating nodes
  155. type: number
  156. NovaAdditionalCell:
  157. default: false
  158. description: Whether this is an cell additional to the default cell.
  159. type: boolean
  160. NovaLocalMetadataPerCell:
  161. default: false
  162. description: >
  163. Indicates that the nova-metadata API service has been deployed
  164. per-cell, so that we can have better performance and data isolation in a
  165. multi-cell deployment. Users should consider the use of this configuration
  166. depending on how neutron is setup. If networks span cells, you might need
  167. to run nova-metadata API service globally. If your networks are segmented
  168. along cell boundaries, then you can run nova-metadata API service per cell.
  169. When running nova-metadata API service per cell, you should also configure
  170. each Neutron metadata-agent to point to the corresponding nova-metadata API
  171. service.
  172. type: boolean
  173. # Jinja loop for Role in role_data.yaml
  174. {% for role in roles %}
  175. {{role.name}}ExtraConfig:
  176. default: {}
  177. description: |
  178. Role specific additional hiera configuration to inject into the cluster.
  179. type: json
  180. {%- if role.deprecated_param_extraconfig is defined %}
  181. {{role.deprecated_param_extraconfig}}:
  182. default: {}
  183. description: |
  184. DEPRECATED use {{role.name}}ExtraConfig instead
  185. type: json
  186. {%- endif %}
  187. # Parameters generated for {{role.name}} Role
  188. {{role.name}}Services:
  189. description: A list of service resources (configured in the Heat
  190. resource_registry) which represent nested stacks
  191. for each service that should get installed on the {{role.name}} role.
  192. type: comma_delimited_list
  193. {{role.name}}NetworkDeploymentActions:
  194. type: comma_delimited_list
  195. description: >
  196. Heat action when to apply network configuration changes
  197. default: []
  198. {{role.name}}AnyErrorsFatal:
  199. default: yes
  200. type: string
  201. {#- We generally won't want any failures on HA Controller roles, 15% will cause any 1 node to fail the deploy, #}
  202. {#- for a 3 or 5 node Role, making it a fairly safe default. #}
  203. {{role.name}}MaxFailPercentage:
  204. default: 15
  205. type: number
  206. {{role.name}}Count:
  207. description: Number of {{role.name}} nodes to deploy
  208. type: number
  209. default: {{role.CountDefault|default(0)}}
  210. {{role.name}}HostnameFormat:
  211. type: string
  212. description: >
  213. Format for {{role.name}} node hostnames
  214. Note %index% is translated into the index of the node, e.g 0/1/2 etc
  215. and %stackname% is replaced with the stack name e.g overcloud
  216. {% if role.HostnameFormatDefault %}
  217. default: "{{role.HostnameFormatDefault}}"
  218. {% else %}
  219. default: "%stackname%-{{role.name.lower()}}-%index%"
  220. {% endif %}
  221. {{role.name}}RemovalPolicies:
  222. default: []
  223. type: json
  224. description: >
  225. List of resources to be removed from {{role.name}} ResourceGroup when
  226. doing an update which requires removal of specific resources.
  227. Example format ComputeRemovalPolicies: [{'resource_list': ['0']}]
  228. {{role.name}}RemovalPoliciesMode:
  229. default: append
  230. type: string
  231. description: >
  232. How to handle change to RemovalPolicies for {{role.name}}
  233. ResourceGroup when doing an update. Default mode 'append' will
  234. append to the existing blacklist and 'update' would replace
  235. the blacklist.
  236. {{role.name}}SchedulerHints:
  237. type: json
  238. description: Optional scheduler hints to pass to nova
  239. default: {}
  240. {%- if role.deprecated_param_scheduler_hints is defined %}
  241. {{role.deprecated_param_scheduler_hints}}:
  242. type: json
  243. description: DEPRECATED - use {{role.name}}SchedulerHints instead
  244. default: {}
  245. {%- endif %}
  246. {{role.name}}Parameters:
  247. type: json
  248. description: Optional Role Specific parameters to be provided to service
  249. default: {}
  250. {% endfor %}
  251. # Identifiers to trigger tasks on nodes
  252. UpdateIdentifier:
  253. default: ''
  254. type: string
  255. description: >
  256. Setting to a previously unused value during stack-update will trigger
  257. package update on all nodes
  258. DeployIdentifier:
  259. default: ''
  260. type: string
  261. description: >
  262. Setting this to a unique value will re-run any deployment tasks which
  263. perform configuration on a Heat stack-update.
  264. AddVipsToEtcHosts:
  265. default: True
  266. type: boolean
  267. description: >
  268. Set to true to append per network Vips to /etc/hosts on each node.
  269. DeploymentServerBlacklist:
  270. default: []
  271. type: comma_delimited_list
  272. description: >
  273. List of server hostnames to blacklist from any triggered deployments.
  274. GlobalConfigExtraMapData:
  275. type: json
  276. default: {}
  277. description: Map of extra global_config_settings data to set on each node.
  278. {% for role in roles %}
  279. {%- if role.deprecated_param_scheduler_hints is defined or role.deprecated_param_extraconfig is defined %}
  280. {%- if not parameter_groups_defined|default(false) %}
  281. parameter_groups:
  282. - label: deprecated
  283. description: Do not use deprecated params, they will be removed.
  284. parameters:
  285. {%- set parameter_groups_defined = true %}
  286. {%- endif %}
  287. {%- endif %}
  288. {%- if role.deprecated_param_scheduler_hints is defined %}
  289. - {{role.deprecated_param_scheduler_hints}}
  290. {%- endif %}
  291. {%- if role.deprecated_param_extraconfig is defined %}
  292. - {{role.deprecated_param_extraconfig}}
  293. {%- endif %}
  294. {%- endfor %}
  295. conditions:
  296. add_vips_to_etc_hosts: {equals : [{get_param: AddVipsToEtcHosts}, True]}
  297. control_fixed_ip_not_set: {equals : [{get_param: ControlFixedIPs}, []]}
  298. ctlplane_subnet_cidr_set:
  299. not:
  300. equals: [{get_param: ControlPlaneSubnetCidr}, '']
  301. {%- for network in networks if network.name != 'External' %}
  302. {{network.name_lower}}_virtual_fixed_ip_set:
  303. not:
  304. equals:
  305. - get_param: {{network.name}}VirtualFixedIPs
  306. - []
  307. {%- endfor %}
  308. public_virtual_fixed_ip_set:
  309. not:
  310. equals:
  311. - get_param: PublicVirtualFixedIPs
  312. - []
  313. redis_virtual_fixed_ip_set:
  314. not:
  315. equals:
  316. - get_param: RedisVirtualFixedIPs
  317. - []
  318. set_default_mysql_cell_internal:
  319. or:
  320. - equals:
  321. - get_param: NovaAdditionalCell
  322. - true
  323. - and:
  324. - equals:
  325. - get_param: NovaAdditionalCell
  326. - false
  327. - equals:
  328. - get_param: [EndpointMapOverride, MysqlCellInternal]
  329. - ''
  330. {%- for role in roles %}
  331. {{role.name}}_network_deployment_actions_exists:
  332. not:
  333. equals:
  334. - {get_param: {{role.name}}NetworkDeploymentActions}
  335. - []
  336. {%- endfor %}
  337. set_default_nova_vnc_proxy_cell_public:
  338. or:
  339. - equals:
  340. - get_param: NovaAdditionalCell
  341. - true
  342. - and:
  343. - equals:
  344. - get_param: NovaAdditionalCell
  345. - false
  346. - equals:
  347. - get_param: [EndpointMapOverride, NovaVNCProxyCellPublic]
  348. - ''
  349. set_default_nova_metadata_cell_internal:
  350. or:
  351. - equals:
  352. - get_param: NovaLocalMetadataPerCell
  353. - true
  354. - and:
  355. - equals:
  356. - get_param: NovaLocalMetadataPerCell
  357. - false
  358. - equals:
  359. - get_param: [EndpointMapOverride, NovaMetadataCellInternal]
  360. - ''
  361. resources:
  362. VipHosts:
  363. type: OS::Heat::Value
  364. properties:
  365. type: string
  366. value:
  367. list_join:
  368. - "\n"
  369. - - str_replace:
  370. template: IP HOST
  371. params:
  372. IP: {get_attr: [VipMap, net_ip_map, ctlplane]}
  373. HOST: {get_param: CloudNameCtlplane}
  374. {%- for network in networks if network.vip|default(false) and network.enabled|default(true) %}
  375. {%- if network.name == 'External' %}
  376. # Special case the External hostname param, which is CloudName
  377. - str_replace:
  378. template: IP HOST
  379. params:
  380. IP: {get_attr: [VipMap, net_ip_map, {{network.name_lower}}]}
  381. HOST: {get_param: CloudName}
  382. {%- elif network.name == 'InternalApi' %}
  383. # Special case the Internal API hostname param, which is CloudNameInternal
  384. - str_replace:
  385. template: IP HOST
  386. params:
  387. IP: {get_attr: [VipMap, net_ip_map, {{network.name_lower}}]}
  388. HOST: {get_param: CloudNameInternal}
  389. {%- elif network.name == 'StorageMgmt' %}
  390. # Special case StorageMgmt hostname param, which is CloudNameStorageManagement
  391. - str_replace:
  392. template: IP HOST
  393. params:
  394. IP: {get_attr: [VipMap, net_ip_map, {{network.name_lower}}]}
  395. HOST: {get_param: CloudNameStorageManagement}
  396. {%- else %}
  397. - str_replace:
  398. template: IP HOST
  399. params:
  400. IP: {get_attr: [VipMap, net_ip_map, {{network.name_lower}}]}
  401. HOST: {get_param: CloudName{{network.name}}}
  402. {%- endif %}
  403. {%- endfor %}
  404. HeatAuthEncryptionKey:
  405. type: OS::TripleO::RandomString
  406. PcsdPassword:
  407. type: OS::TripleO::RandomString
  408. properties:
  409. length: 16
  410. HorizonSecret:
  411. type: OS::TripleO::RandomString
  412. properties:
  413. length: 64
  414. NetCidrMapValue:
  415. type: OS::Heat::Value
  416. properties:
  417. type: json
  418. value:
  419. map_replace:
  420. - map_merge:
  421. - {get_attr: [Networks, net_cidr_map]}
  422. # NOTE(hjensas): When ctlplane network and subnets are created by the
  423. # undercloud installer, the subnet cidrs are added as tags.
  424. - ctlplane: {get_attr: [ControlVirtualIP, network, tags]}
  425. - keys:
  426. ctlplane: {get_param: NeutronControlPlaneID}
  427. ServiceNetMap:
  428. type: OS::TripleO::ServiceNetMap
  429. EndpointMap:
  430. type: OS::TripleO::EndpointMap
  431. properties:
  432. CloudEndpoints:
  433. ctlplane: {get_param: CloudNameCtlplane}
  434. {%- for network in networks if network.vip|default(false) and network.enabled|default(true) %}
  435. {%- if network.name == 'External' %}
  436. # Special case the External hostname param, which is CloudName
  437. {{network.name_lower}}: {get_param: CloudName}
  438. {%- elif network.name == 'InternalApi' %}
  439. # Special case the Internal API hostname param, which is CloudNameInternal
  440. {{network.name_lower}}: {get_param: CloudNameInternal}
  441. {%- elif network.name == 'StorageMgmt' %}
  442. # Special case StorageMgmt hostname param, which is CloudNameStorageManagement
  443. {{network.name_lower}}: {get_param: CloudNameStorageManagement}
  444. {%- else %}
  445. {{network.name_lower}}: {get_param: CloudName{{network.name}}}
  446. {%- endif %}
  447. {%- endfor %}
  448. NetIpMap: {get_attr: [VipMap, net_ip_map]}
  449. ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
  450. EndpointMapData:
  451. type: OS::Heat::Value
  452. properties:
  453. type: json
  454. value:
  455. map_merge:
  456. - {get_attr: [EndpointMap, endpoint_map]}
  457. - {get_param: EndpointMapOverride}
  458. # For parent stack we must set these to the local endpoints
  459. # For split-controlplane stacks that are nova cells we must set
  460. # these to the local endpoints
  461. # For split-controlplane stacks that are not nova cells we should
  462. # take these from EndpointMapOverride (i.e the parent stack)
  463. - if:
  464. - set_default_mysql_cell_internal
  465. - MysqlCellInternal: {get_attr: [EndpointMap, endpoint_map, MysqlInternal]}
  466. - {}
  467. - if:
  468. - set_default_nova_vnc_proxy_cell_public
  469. - NovaVNCProxyCellPublic: {get_attr: [EndpointMap, endpoint_map, NovaVNCProxyPublic]}
  470. - {}
  471. - if:
  472. - set_default_nova_metadata_cell_internal
  473. - NovaMetadataCellInternal: {get_attr: [EndpointMap, endpoint_map, NovaMetadataInternal]}
  474. - {}
  475. # Creates the "heat-admin" user if configured via the environment
  476. # Should return a OS::Heat::MultipartMime reference via OS::stack_id
  477. NodeAdminUserData:
  478. type: OS::TripleO::NodeAdminUserData
  479. # Bootstraps an ntp configuration and includes a hardware clock sync to
  480. # for containers.
  481. # Should return a OS::Heat::MultipartMime reference via OS::stack_id
  482. NodeTimesyncUserData:
  483. type: OS::TripleO::NodeTimesyncUserData
  484. # For optional operator additional userdata
  485. # Should return a OS::Heat::MultipartMime reference via OS::stack_id
  486. NodeUserData:
  487. type: OS::TripleO::NodeUserData
  488. # Jinja loop for Role in roles_data.yaml
  489. {% for role in roles %}
  490. # Resources generated for {{role.name}} Role
  491. {{role.name}}ServiceChain:
  492. type: OS::TripleO::{{role.name}}Services
  493. properties:
  494. Services:
  495. get_param: {{role.name}}Services
  496. ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
  497. ServiceData:
  498. net_cidr_map: {get_attr: [NetCidrMapValue, value]}
  499. EndpointMap: {get_attr: [EndpointMapData, value]}
  500. DefaultPasswords: {get_attr: [DefaultPasswords, passwords]}
  501. RoleName: {{role.name}}
  502. RoleParameters:
  503. map_merge:
  504. - {{role.RoleParametersDefault|default({})}}
  505. - get_param: {{role.name}}Parameters
  506. # Lookup of role_data via heat outputs is slow, so workaround this by caching
  507. # the value in an OS::Heat::Value resource
  508. {{role.name}}ServiceChainRoleData:
  509. type: OS::Heat::Value
  510. properties:
  511. type: json
  512. value: {get_attr: [{{role.name}}ServiceChain, role_data]}
  513. {{role.name}}NetworkDeploymentActionsValue:
  514. type: OS::Heat::Value
  515. properties:
  516. value:
  517. - if:
  518. - {{role.name}}_network_deployment_actions_exists
  519. - {get_param: {{role.name}}NetworkDeploymentActions}
  520. - {get_param: NetworkDeploymentActions}
  521. {{role.name}}ConfigData:
  522. type: OS::Heat::Value
  523. properties:
  524. type: json
  525. value:
  526. service_configs: {get_attr: [{{role.name}}ServiceConfigSettings, value]}
  527. role_extraconfig:
  528. map_merge:
  529. - sensu::subscriptions: {get_attr: [{{role.name}}ServiceChainRoleData, value, monitoring_subscriptions]}
  530. {%- if role.deprecated_param_extraconfig is defined %}
  531. - {get_param: {{role.deprecated_param_extraconfig}}}
  532. {%- endif %}
  533. - {get_param: {{role.name}}ExtraConfig}
  534. extraconfig: {get_param: ExtraConfig}
  535. hieradata_files:
  536. - '"%{::uuid}"'
  537. - fqdn
  538. - docker_puppet # Optionally provided by container-puppet.py
  539. - heat_config_%{::deploy_config_name}
  540. - config_step
  541. - role_extraconfig
  542. - extraconfig
  543. - service_configs
  544. - cloud_domain
  545. - bootstrap_node # provided by tripleo-hieradata
  546. - all_nodes # provided by tripleo-hieradata
  547. - vip_data # provided by tripleo-hieradata
  548. - net_ip_map
  549. - '"%{::osfamily}"'
  550. # The following are required for compatibility with the Controller role
  551. # where some vendor integrations added hieradata via ExtraConfigPre
  552. - neutron_bigswitch_data # Optionally provided by Controller/ComputeExtraConfigPre
  553. # Special variable for upgrade
  554. - upgrade
  555. {{role.name}}ServiceConfigSettings:
  556. type: OS::Heat::Value
  557. properties:
  558. type: json
  559. value:
  560. map_merge:
  561. - get_param: GlobalConfigExtraMapData
  562. - get_attr: [{{role.name}}ServiceChainRoleData, value, config_settings]
  563. {% for r in roles %}
  564. - get_attr: [{{r.name}}ServiceChainRoleData, value, global_config_settings]
  565. {% endfor %}
  566. # This next step combines two yaql passes:
  567. # - The inner one does a deep merge on the service_config_settings for all roles
  568. # - The outer one filters the map based on the services enabled for the role
  569. # then merges the result into one map.
  570. - yaql:
  571. expression: let(root => $) -> $.data.map.items().where($[0] in coalesce($root.data.services, [])).select($[1]).reduce($1.mergeWith($2), {})
  572. data:
  573. map:
  574. yaql:
  575. expression: $.data.where($ != null).reduce($1.mergeWith($2), {})
  576. data:
  577. {% for r in roles %}
  578. - get_attr: [{{r.name}}ServiceChainRoleData, value, service_config_settings]
  579. {% endfor %}
  580. services: {get_attr: [{{role.name}}ServiceNames, value]}
  581. # Filter any null/None service_names which may be present due to mapping
  582. # of services to OS::Heat::None
  583. {{role.name}}ServiceNames:
  584. type: OS::Heat::Value
  585. depends_on: {{role.name}}ServiceChain
  586. properties:
  587. type: comma_delimited_list
  588. value:
  589. yaql:
  590. expression: let(root => $) -> $.data.extra_services.items().where($[0] in coalesce($root.data.enabled_services, [])).select($[1]).flatten() + coalesce($root.data.enabled_services, [])
  591. data:
  592. enabled_services: {get_attr: [{{role.name}}ServiceChainRoleData, value, service_names]}
  593. extra_services:
  594. # If anything other than keystone needs this
  595. # then we should add an extra_networks interface
  596. # to the service templates role_data but for
  597. # now we hard-code the keystone special case
  598. keystone:
  599. - keystone_admin_api
  600. - keystone_public_api
  601. {{role.name}}IpListMap:
  602. type: OS::TripleO::Network::Ports::NetIpListMap
  603. properties:
  604. ControlPlaneIpList: {get_attr: [{{role.name}}, ip_address]}
  605. {%- for network in networks %}
  606. {%- if network.enabled|default(true) and network.name in role.networks|default([]) %}
  607. {{network.name}}IpList: {get_attr: [{{role.name}}, {{network.name_lower}}_ip_address]}
  608. {%- else %}
  609. {{network.name}}IpList: {get_attr: [{{role.name}}, ip_address]}
  610. {%- endif %}
  611. {%- endfor %}
  612. EnabledServices: {get_attr: [{{role.name}}ServiceNames, value]}
  613. ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
  614. ServiceHostnameList: {get_attr: [{{role.name}}, hostname]}
  615. NetworkHostnameMap: {get_attr: [{{role.name}}NetworkHostnameMap, value]}
  616. {{role.name}}NetworkHostnameMap:
  617. type: OS::Heat::Value
  618. properties:
  619. type: json
  620. value:
  621. # Note (shardy) this somewhat complex yaql may be replaced
  622. # with a map_deep_merge function in ocata. It merges the
  623. # list of maps, but appends to colliding lists so we can
  624. # create a map of lists for all nodes for each network
  625. yaql:
  626. expression: dict($.data.where($ != null).flatten().selectMany($.items()).groupBy($[0], $[1]).select([$[0], $[1].flatten()]))
  627. data:
  628. - {get_attr: [{{role.name}}, hostname_map]}
  629. # Combine the NodeAdminUserData and NodeUserData mime archives
  630. {{role.name}}UserData:
  631. type: OS::Heat::MultipartMime
  632. properties:
  633. parts:
  634. - config: {get_resource: NodeAdminUserData}
  635. type: multipart
  636. - config: {get_resource: NodeTimesyncUserData}
  637. type: multipart
  638. - config: {get_resource: NodeUserData}
  639. type: multipart
  640. - config: {get_resource: {{role.name}}RoleUserData}
  641. type: multipart
  642. # For optional operator role-specific userdata
  643. # Should return a OS::Heat::MultipartMime reference via OS::stack_id
  644. {{role.name}}RoleUserData:
  645. type: OS::TripleO::{{role.name}}::NodeUserData
  646. {{role.name}}:
  647. type: OS::Heat::ResourceGroup
  648. depends_on: Networks
  649. update_policy:
  650. batch_create:
  651. max_batch_size: {get_param: NodeCreateBatchSize}
  652. properties:
  653. count: {get_param: {{role.name}}Count}
  654. removal_policies: {get_param: {{role.name}}RemovalPolicies}
  655. removal_policies_mode: {get_param: {{role.name}}RemovalPoliciesMode}
  656. resource_def:
  657. type: OS::TripleO::{{role.name}}
  658. properties:
  659. CloudDomain: {get_param: CloudDomain}
  660. ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]}
  661. EndpointMap: {get_attr: [EndpointMapData, value]}
  662. Hostname:
  663. str_replace:
  664. template: {get_param: {{role.name}}HostnameFormat}
  665. params:
  666. '%stackname%': {get_param: 'OS::stack_name'}
  667. NodeIndex: '%index%'
  668. # Note, SchedulerHints must be defined here, not only in the
  669. # nested template, as it can contain %index%
  670. {{role.name}}SchedulerHints:
  671. map_merge:
  672. {%- if role.deprecated_param_scheduler_hints is defined %}
  673. - {get_param: {{role.deprecated_param_scheduler_hints}}}
  674. {%- endif %}
  675. - {get_param: {{role.name}}SchedulerHints}
  676. ServiceNames: {get_attr: [{{role.name}}ServiceNames, value]}
  677. ServiceMetadataSettings: {get_attr: [{{role.name}}ServiceChainRoleData, value, service_metadata_settings]}
  678. DeploymentServerBlacklistDict: {get_attr: [DeploymentServerBlacklistDict, value]}
  679. RoleParameters:
  680. map_merge:
  681. - {{role.RoleParametersDefault|default({})}}
  682. - get_param: {{role.name}}Parameters
  683. UserData: {get_resource: {{role.name}}UserData}
  684. {%- endfor %}
  685. {%- for role in roles %}
  686. {{role.name}}Servers:
  687. type: OS::Heat::Value
  688. depends_on: {{role.name}}
  689. properties:
  690. type: json
  691. value:
  692. yaql:
  693. expression: let(servers=>switch(isDict($.data.servers) => $.data.servers, true => {})) -> $servers.deleteAll($servers.keys().where($servers[$] = null))
  694. data:
  695. servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]}
  696. {%- endfor %}
  697. # This is a different format to *Servers, as it creates a map of lists
  698. # whereas *Servers creates a map of maps with keys of the nested resource names
  699. ServerIdMap:
  700. type: OS::Heat::Value
  701. properties:
  702. value:
  703. server_ids:
  704. {%- for role in roles %}
  705. {{role.name}}: {get_attr: [{{role.name}}, nova_server_resource]}
  706. {%- endfor %}
  707. bootstrap_server_id:
  708. yaql:
  709. expression: coalesce($.data, []).first(null)
  710. data: {get_attr: [{{primary_role_name}}, nova_server_resource]}
  711. # This resource just creates a dict out of the DeploymentServerBlacklist,
  712. # which is a list. The dict is used in the role templates to set a condition
  713. # on whether to create the deployment resources. We can't use the list
  714. # directly because there is no way to ask Heat if a list contains a specific
  715. # value.
  716. DeploymentServerBlacklistDict:
  717. type: OS::Heat::Value
  718. properties:
  719. type: json
  720. value:
  721. map_merge:
  722. repeat:
  723. template:
  724. hostname: 1
  725. for_each:
  726. hostname: {get_param: DeploymentServerBlacklist}
  727. HostsValue:
  728. type: OS::Heat::Value
  729. properties:
  730. value:
  731. list_join:
  732. - "\n"
  733. - - if:
  734. - add_vips_to_etc_hosts
  735. - {get_attr: [VipHosts, value]}
  736. - ''
  737. -
  738. {%- for role in roles %}
  739. - list_join:
  740. - ""
  741. - {get_attr: [{{role.name}}, hosts_entry]}
  742. {%- endfor %}
  743. - {get_param: ExtraHostFileEntries}
  744. HostsEntryValue:
  745. type: OS::Heat::Value
  746. properties:
  747. value:
  748. list_join:
  749. - ' '
  750. - str_split:
  751. - '\n'
  752. - {get_attr: [HostsValue, value]}
  753. CloudNames:
  754. type: OS::Heat::Value
  755. properties:
  756. value:
  757. {%- for network in networks if network.vip|default(false) and network.enabled|default(true) %}
  758. {%- if network.name == 'External' %}
  759. # Special case the External hostname param, which is CloudName
  760. cloud_name_{{network.name_lower}}: {get_param: CloudName}
  761. {%- elif network.name == 'InternalApi' %}
  762. # Special case the Internal API hostname param, which is CloudNameInternal
  763. cloud_name_{{network.name_lower}}: {get_param: CloudNameInternal}
  764. {%- elif network.name == 'StorageMgmt' %}
  765. # Special case StorageMgmt hostname param, which is CloudNameStorageManagement
  766. cloud_name_{{network.name_lower}}: {get_param: CloudNameStorageManagement}
  767. {%- else %}
  768. cloud_name_{{network.name_lower}}: {get_param: CloudName{{network.name}}}
  769. {%- endif %}
  770. {%- endfor %}
  771. cloud_name_ctlplane: {get_param: CloudNameCtlplane}
  772. GlobalConfig:
  773. type: OS::Heat::Value
  774. properties:
  775. type: json
  776. value:
  777. map_merge:
  778. {% for role in roles %}
  779. - get_attr: [{{role.name}}ServiceChainRoleData, value, global_config_settings]
  780. {% endfor %}
  781. MysqlRootPassword:
  782. type: OS::TripleO::RandomString
  783. properties:
  784. length: 10
  785. RabbitCookie:
  786. type: OS::TripleO::RandomString
  787. properties:
  788. length: 20
  789. salt: {get_param: RabbitCookieSalt}
  790. DefaultPasswords:
  791. type: OS::TripleO::DefaultPasswords
  792. properties:
  793. DefaultMysqlRootPassword: {get_attr: [MysqlRootPassword, value]}
  794. DefaultRabbitCookie: {get_attr: [RabbitCookie, value]}
  795. DefaultHeatAuthEncryptionKey: {get_attr: [HeatAuthEncryptionKey, value]}
  796. DefaultPcsdPassword: {get_attr: [PcsdPassword, value]}
  797. DefaultHorizonSecret: {get_attr: [HorizonSecret, value]}
  798. # creates the network architecture
  799. Networks:
  800. type: OS::TripleO::Network
  801. properties:
  802. CtlplaneNetworkCidrs: {get_attr: [ControlVirtualIP, network, tags]}
  803. {%- for role in roles %}
  804. {{role.name}}GroupVars:
  805. type: OS::Heat::Value
  806. properties:
  807. value:
  808. bootstrap_nodeid:
  809. yaql:
  810. expression: coalesce($.data, []).where(not isEmpty($)).first()
  811. data: {get_attr: [{{role.name}}, hostname]}
  812. ctlplane_subnet_cidr:
  813. yaql:
  814. expression: coalesce($.data, []).where(not isEmpty($)).first().split('/')[-1]
  815. data:
  816. if:
  817. - ctlplane_subnet_cidr_set
  818. - [{get_param: ControlPlaneSubnetCidr}]
  819. - {get_attr: [ControlVirtualIP, network, tags]}
  820. network_cidrs:
  821. {%- for network in networks %}
  822. {%- if network.enabled|default(true) and network.name in role.networks|default([]) %}
  823. {{network.name}}_cidr:
  824. yaql:
  825. expression: coalesce($.data, []).where(not isEmpty($)).first().split('/')[-1]
  826. data: {get_attr: [Networks, net_cidr_map, {{network.name_lower}}]}
  827. {%- endif %}
  828. {%- endfor %}
  829. role_networks:
  830. {%- for network in networks %}
  831. {%- if network.enabled|default(true) and network.name in role.networks|default([]) %}
  832. - {{network.name}}
  833. {% endif %}
  834. {% endfor %}
  835. {%- for network in networks %}
  836. {%- if network.enabled|default(true) and network.name in role.networks|default([]) %}
  837. {{network.name_lower}}_cidr:
  838. yaql:
  839. expression: coalesce($.data, []).where(not isEmpty($)).first().split('/')[-1]
  840. data: {get_attr: [Networks, net_cidr_map, {{network.name_lower}}]}
  841. {% endif %}
  842. {% endfor %}
  843. {% endfor %}
  844. ControlVirtualIP:
  845. depends_on: ServiceNetMap
  846. type: OS::TripleO::Network::Ports::ControlPlaneVipPort
  847. properties:
  848. name: control_virtual_ip
  849. network: {get_param: NeutronControlPlaneID}
  850. fixed_ips:
  851. if:
  852. - control_fixed_ip_not_set
  853. - [{subnet: {get_attr: [ServiceNetMap, vip_subnet_map, ctlplane]}}]
  854. - get_param: ControlFixedIPs
  855. replacement_policy: AUTO
  856. RedisVirtualIP:
  857. depends_on: [Networks, ServiceNetMap]
  858. type: OS::TripleO::Network::Ports::RedisVipPort
  859. properties:
  860. ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
  861. ControlPlaneSubnetCidr:
  862. if:
  863. - ctlplane_subnet_cidr_set
  864. - {get_param: ControlPlaneSubnetCidr}
  865. - {str_split: ['/', {get_attr: [ControlVirtualIP, subnets, 0, cidr]}, 1]}
  866. ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
  867. PortName: redis_virtual_ip
  868. NetworkName: {get_attr: [ServiceNetMap, service_net_map, RedisNetwork]}
  869. ServiceName: redis
  870. FixedIPs:
  871. if:
  872. - redis_virtual_fixed_ip_set
  873. - {get_param: RedisVirtualFixedIPs}
  874. - [{subnet: {get_attr: [ServiceNetMap, vip_subnet_map, redis]}}]
  875. {%- for network in networks if network.vip|default(false) and network.enabled|default(true) %}
  876. {%- if network.name == 'External' %}
  877. # The public VIP is on the External net, falls back to ctlplane
  878. PublicVirtualIP:
  879. depends_on: [Networks, ServiceNetMap]
  880. type: OS::TripleO::Network::Ports::ExternalVipPort
  881. properties:
  882. ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
  883. ControlPlaneSubnetCidr:
  884. if:
  885. - ctlplane_subnet_cidr_set
  886. - {get_param: ControlPlaneSubnetCidr}
  887. - {str_split: ['/', {get_attr: [ControlVirtualIP, subnets, 0, cidr]}, 1]}
  888. ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
  889. PortName: public_virtual_ip
  890. FixedIPs:
  891. if:
  892. - public_virtual_fixed_ip_set
  893. - {get_param: PublicVirtualFixedIPs}
  894. - [{subnet: {get_attr: [ServiceNetMap, vip_subnet_map, {{network.name}}]}}]
  895. {%- else %}
  896. {{network.name}}VirtualIP:
  897. depends_on: [Networks, ServiceNetMap]
  898. type: OS::TripleO::Network::Ports::{{network.name}}VipPort
  899. properties:
  900. ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
  901. ControlPlaneSubnetCidr:
  902. if:
  903. - ctlplane_subnet_cidr_set
  904. - {get_param: ControlPlaneSubnetCidr}
  905. - {str_split: ['/', {get_attr: [ControlVirtualIP, subnets, 0, cidr]}, 1]}
  906. PortName: {{network.name_lower}}_virtual_ip
  907. FixedIPs:
  908. if:
  909. - {{network.name_lower}}_virtual_fixed_ip_set
  910. - {get_param: {{network.name}}VirtualFixedIPs}
  911. - [{subnet: {get_attr: [ServiceNetMap, vip_subnet_map, {{network.name}}]}}]
  912. {% endif %}
  913. {%- endfor %}
  914. VipMap:
  915. type: OS::TripleO::Network::Ports::NetVipMap
  916. properties:
  917. ControlPlaneIp: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
  918. ControlPlaneSubnetCidr:
  919. if:
  920. - ctlplane_subnet_cidr_set
  921. - {get_param: ControlPlaneSubnetCidr}
  922. - {str_split: ['/', {get_attr: [ControlVirtualIP, subnets, 0, cidr]}, 1]}
  923. {%- for network in networks if network.vip|default(false) and network.enabled|default(true) %}
  924. {%- if network.name == 'External' %}
  925. ExternalIp: {get_attr: [PublicVirtualIP, ip_address]}
  926. ExternalIpUri: {get_attr: [PublicVirtualIP, ip_address_uri]}
  927. {%- else %}
  928. {{network.name}}Ip: {get_attr: [{{network.name}}VirtualIP, ip_address]}
  929. {{network.name}}IpUri: {get_attr: [{{network.name}}VirtualIP, ip_address_uri]}
  930. {%- endif %}
  931. {%- endfor %}
  932. # No tenant or management VIP required
  933. # Because of nested get_attr functions in the KeystoneAdminVip output, we
  934. # can't determine which attributes of VipMap are used until after
  935. # ServiceNetMap's attribute values are available.
  936. depends_on: ServiceNetMap
  937. # Optional ExtraConfig for all nodes - all roles are passed in here, but
  938. # the nested template may configure each role differently (or not at all)
  939. AllNodesExtraConfig:
  940. type: OS::TripleO::AllNodesExtraConfig
  941. properties:
  942. servers:
  943. {%- for role in roles %}
  944. {{role.name}}: {get_attr: [{{role.name}}Servers, value]}
  945. {%- endfor %}
  946. BlacklistedIpAddresses:
  947. type: OS::Heat::Value
  948. properties:
  949. value:
  950. list_concat:
  951. {%- for role in roles %}
  952. - {get_attr: [{{role.name}}, blacklist_ip_address]}
  953. {%- endfor %}
  954. AnsibleHostVars:
  955. type: OS::Heat::Value
  956. properties:
  957. type: json
  958. value:
  959. {%- for role in roles %}
  960. {{role.name}}:
  961. map_merge:
  962. list_concat:
  963. - {get_attr: [{{role.name}}, ansible_host_vars_map]}
  964. {%- endfor %}
  965. BlacklistedHostnames:
  966. type: OS::Heat::Value
  967. properties:
  968. value:
  969. list_concat:
  970. {%- for role in roles %}
  971. - {get_attr: [{{role.name}}, blacklist_hostname]}
  972. {%- endfor %}
  973. # Post deployment steps for all roles
  974. AllNodesDeploySteps:
  975. type: OS::TripleO::PostDeploySteps
  976. depends_on:
  977. - AllNodesExtraConfig
  978. properties:
  979. servers:
  980. {%- for role in roles %}
  981. {{role.name}}: {get_attr: [{{role.name}}Servers, value]}
  982. {%- endfor %}
  983. EndpointMap: {get_attr: [EndpointMapData, value]}
  984. role_data:
  985. {%- for role in roles %}
  986. {{role.name}}: {get_attr: [{{role.name}}ServiceChainRoleData, value]}
  987. {%- endfor %}
  988. {%- for role in roles %}
  989. {{role.name}}Count: {get_param: {{role.name}}Count}
  990. {%- endfor %}
  991. ServiceNetMapLower: {get_attr: [ServiceNetMap, service_net_map_lower]}
  992. PingTestIpsMap:
  993. {%- for role in roles %}
  994. {{role.name}}:
  995. list_join:
  996. - ' '
  997. - - yaql:
  998. expression: coalesce($.data, []).first(null)
  999. data: {get_attr: [{{role.name}}, ip_address]}
  1000. {%- for network in networks %}
  1001. {%- if network.enabled|default(true) and network.name in role.networks|default([]) %}
  1002. - yaql:
  1003. expression: coalesce($.data, []).first(null)
  1004. data: {get_attr: [{{role.name}}, {{network.name_lower}}_ip_address]}
  1005. {%- endif %}
  1006. {%- endfor %}
  1007. {%- endfor %}
  1008. HostsEntry: {get_attr: [HostsEntryValue, value]}
  1009. EnabledServices:
  1010. list_concat:
  1011. {%- for role in roles %}
  1012. - {get_attr: [{{role.name}}ServiceNames, value]}
  1013. {%- endfor %}
  1014. ControlVirtualIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
  1015. EnabledNetworks:
  1016. {%- for network in networks if network.enabled|default(true) %}
  1017. - {{ network.name }}
  1018. {%- endfor %}
  1019. NetVipMap:
  1020. map_merge:
  1021. - {get_attr: [VipMap, net_ip_map]}
  1022. - redis: {get_attr: [RedisVirtualIP, ip_address]}
  1023. CloudNames: {get_attr: [CloudNames, value]}
  1024. DeployedServerEnvironment:
  1025. type: OS::TripleO::DeployedServerEnvironment
  1026. properties:
  1027. RoleCounts:
  1028. {%- for role in roles %}
  1029. {{role.name}}DeployedServerCount: {get_param: {{role.name}}Count}
  1030. {%- endfor %}
  1031. VipMap:
  1032. map_merge:
  1033. - {get_attr: [VipMap, net_ip_map]}
  1034. - redis: {get_attr: [RedisVirtualIP, ip_address]}
  1035. DeployedServerPortMap:
  1036. map_merge:
  1037. list_concat:
  1038. {%- for role in roles %}
  1039. - {get_attr: [{{role.name}}, deployed_server_port_map]}
  1040. {%- endfor %}
  1041. outputs:
  1042. ManagedEndpoints:
  1043. description: Asserts that the keystone endpoints have been provisioned.
  1044. value: true
  1045. KeystoneURL:
  1046. description: URL for the Overcloud Keystone service
  1047. value: {get_attr: [EndpointMapData, value, KeystonePublic, uri_no_suffix]}
  1048. KeystoneAdminVip:
  1049. description: Keystone Admin VIP endpoint
  1050. # Note that these nested get_attr functions require a dependency
  1051. # relationship between VipMap and ServiceNetMap, since we can't determine
  1052. # which attributes of VipMap are used until after ServiceNetMap's attribute
  1053. # values are available. If this is ever reworked to not use nested
  1054. # get_attr, that dependency can be removed.
  1055. value: {get_attr: [VipMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystoneAdminApiNetwork]}]}
  1056. EndpointMap:
  1057. description: |
  1058. Mapping of the resources with the needed info for their endpoints.
  1059. This includes the protocol used, the IP, port and also a full
  1060. representation of the URI.
  1061. value: {get_attr: [EndpointMapData, value]}
  1062. HostsEntry:
  1063. description: |
  1064. The content that should be appended to your /etc/hosts if you want to get
  1065. hostname-based access to the deployed nodes (useful for testing without
  1066. setting up a DNS).
  1067. value:
  1068. list_join:
  1069. - "\n"
  1070. - - {get_attr: [HostsEntryValue, value]}
  1071. - - {get_attr: [VipHosts, value]}
  1072. EnabledServices:
  1073. description: The services enabled on each role
  1074. value:
  1075. {%- for role in roles %}
  1076. {{role.name}}: {get_attr: [{{role.name}}ServiceNames, value]}
  1077. {%- endfor %}
  1078. RoleData:
  1079. description: The configuration data associated with each role
  1080. value:
  1081. {%- for role in roles %}
  1082. {{role.name}}: {get_attr: [{{role.name}}ServiceChainRoleData, value]}
  1083. {%- endfor %}
  1084. RoleConfig:
  1085. description: The configuration workflows associated with each role
  1086. value: {get_attr: [AllNodesDeploySteps, RoleConfig]}
  1087. RoleNetIpMap:
  1088. description: Mapping of each network to a list of IPs for each role
  1089. value:
  1090. {%- for role in roles %}
  1091. {{role.name}}: {get_attr: [{{role.name}}IpListMap, net_ip_map]}
  1092. {%- endfor %}
  1093. RoleGroupVars:
  1094. description: Mapping of roles to ansible group_vars to be applied config in those roles
  1095. value:
  1096. {%- for role in roles %}
  1097. {{role.name}}:
  1098. map_merge:
  1099. - {get_attr: [{{role.name}}GroupVars, value]}
  1100. - {get_attr: [{{role.name}}ConfigData, value]}
  1101. - any_errors_fatal: {get_param: {{role.name}}AnyErrorsFatal}
  1102. max_fail_percentage: {get_param: {{role.name}}MaxFailPercentage}
  1103. neutron_physical_bridge_name: {get_param: NeutronPhysicalBridge}
  1104. neutron_public_interface_name: {get_param: NeutronPublicInterface}
  1105. network_deployment_actions: {get_attr: [{{role.name}}NetworkDeploymentActionsValue, value]}
  1106. {%- endfor %}
  1107. RoleNetHostnameMap:
  1108. description: Mapping of each network to a list of hostnames for each role
  1109. value:
  1110. {%- for role in roles %}
  1111. {{role.name}}: {get_attr: [{{role.name}}NetworkHostnameMap, value]}
  1112. {%- endfor %}
  1113. RoleTags:
  1114. description: Tags for each role, as defined in roles_data.yaml
  1115. value:
  1116. {%- for role in roles %}
  1117. {{role.name}}: {{role.tags|default([])}}
  1118. {%- endfor %}
  1119. VipMap:
  1120. description: Mapping of each network to VIP addresses. Also includes the Redis VIP.
  1121. value:
  1122. map_merge:
  1123. - {get_attr: [VipMap, net_ip_map]}
  1124. - redis: {get_attr: [RedisVirtualIP, ip_address]}
  1125. ServerIdData:
  1126. description: Mapping of each role to a list of nova server IDs and the bootstrap ID
  1127. value: {get_attr: [ServerIdMap, value]}
  1128. DeployedServerEnvironment:
  1129. description:
  1130. Environment data that can be used as input into the services stack when
  1131. using split-stack.
  1132. value: {get_attr: [DeployedServerEnvironment, deployed_server_environment]}
  1133. BlacklistedHostnames:
  1134. description: List of blacklisted hostnames
  1135. value: {get_attr: [BlacklistedHostnames, value]}
  1136. BlacklistedIpAddresses:
  1137. description: List of blacklisted ctlplane IP addresses
  1138. value: {get_attr: [BlacklistedIpAddresses, value]}
  1139. GlobalConfig:
  1140. description: The global_config (hieradata).
  1141. value: {get_attr: [GlobalConfig, value]}
  1142. HostnameNetworkConfigMap:
  1143. description: Mapping of hostname to NetworkConfig resource
  1144. value:
  1145. map_merge:
  1146. list_concat:
  1147. {%- for role in roles %}
  1148. - {get_attr: [{{role.name}}, hostname_network_config_map]}
  1149. {%- endfor %}
  1150. AnsibleHostVarsMap:
  1151. description: Map of Ansible Host variables per role
  1152. value: {get_attr: [AnsibleHostVars, value]}