heat_template_version: 2016-10-14 description: 'All Nodes Config for Puppet' parameters: cloud_name_external: type: string cloud_name_internal_api: type: string cloud_name_storage: type: string cloud_name_storage_mgmt: type: string cloud_name_management: type: string hosts: type: comma_delimited_list # FIXME(shardy) this can be comma_delimited_list when # https://bugs.launchpad.net/heat/+bug/1617019 is fixed enabled_services: type: string controller_ips: type: comma_delimited_list service_ips: type: json service_node_names: type: json controller_names: type: comma_delimited_list memcache_node_ips: type: comma_delimited_list keystone_public_api_node_ips: type: comma_delimited_list keystone_admin_api_node_ips: type: comma_delimited_list NetVipMap: type: json RedisVirtualIP: type: string default: '' ServiceNetMap: type: json DeployIdentifier: type: string default: '' description: > Setting this to a unique value will re-run any deployment tasks which perform configuration on a Heat stack-update. UpdateIdentifier: type: string description: > Setting to a previously unused value during stack-update will trigger package update on all nodes StackAction: type: string description: > Heat action on performed top-level stack. constraints: - allowed_values: ['CREATE', 'UPDATE'] resources: allNodesConfigImpl: type: OS::Heat::StructuredConfig properties: group: os-apply-config config: hosts: list_join: - "\n" - {get_param: hosts} hiera: datafiles: bootstrap_node: mapped_data: bootstrap_nodeid: {get_input: bootstrap_nodeid} bootstrap_nodeid_ip: {get_input: bootstrap_nodeid_ip} all_nodes: mapped_data: map_merge: - enabled_services: {get_param: enabled_services} # This writes out a mapping of service_name_enabled: 'true' # For any services not enabled, hiera foo_enabled will # return nil, as it's undefined - map_merge: repeat: template: # Note this must be string 'true' due to # https://bugs.launchpad.net/heat/+bug/1617203 SERVICE_enabled: 'true' for_each: SERVICE: str_split: [',', {get_param: enabled_services}] # provides a mapping of service_name_ips to a list of IPs - {get_param: service_ips} - {get_param: service_node_names} - controller_node_ips: list_join: - ',' - {get_param: controller_ips} controller_node_names: list_join: - ',' - {get_param: controller_names} memcached_node_ips_v6: str_replace: template: "['inet6:[SERVERS_LIST]']" params: SERVERS_LIST: list_join: - "]','inet6:[" - {get_param: memcache_node_ips} keystone_public_api_node_ips: str_replace: template: "['SERVERS_LIST']" params: SERVERS_LIST: list_join: - "','" - {get_param: keystone_public_api_node_ips} keystone_admin_api_node_ips: str_replace: template: "['SERVERS_LIST']" params: SERVERS_LIST: list_join: - "','" - {get_param: keystone_admin_api_node_ips} deploy_identifier: {get_param: DeployIdentifier} update_identifier: {get_param: UpdateIdentifier} stack_action: {get_param: StackAction} vip_data: mapped_data: map_merge: # Dynamically generate per-service VIP data based on enabled_services # This works as follows (outer->inner functions) # yaql - filters services where no mapping exists in ServiceNetMap # map_replace: substitute e.g internal_api with the IP from NetVipMap # map_replace: substitute e.g heat_api_network with network name from ServiceNetMap # map_merge/repeat: generate a per-service mapping - yaql: # This filters any entries where the value hasn't been substituted for # a list, e.g it's still $service_network. This happens when there is # no network defined for the service in the ServiceNetMap, which is OK # as not all services have to be bound to a network, so we filter them expression: dict($.data.map.items().where(isString($[1]) and not $[1].endsWith("_network"))) data: map: map_replace: - map_replace: - map_merge: repeat: template: SERVICE_vip: SERVICE_network for_each: SERVICE: str_split: [',', {get_param: enabled_services}] - values: {get_param: ServiceNetMap} - values: {get_param: NetVipMap} - keystone_admin_api_vip: get_param: [NetVipMap, {get_param: [ServiceNetMap, keystone_admin_api_network]}] keystone_public_api_vip: get_param: [NetVipMap, {get_param: [ServiceNetMap, keystone_public_api_network]}] public_virtual_ip: {get_param: [NetVipMap, external]} controller_virtual_ip: {get_param: [NetVipMap, ctlplane]} internal_api_virtual_ip: {get_param: [NetVipMap, internal_api]} storage_virtual_ip: {get_param: [NetVipMap, storage]} storage_mgmt_virtual_ip: {get_param: [NetVipMap, storage_mgmt]} redis_vip: {get_param: RedisVirtualIP} # public_virtual_ip and controller_virtual_ip are needed in # both HAproxy & keepalived. tripleo::haproxy::public_virtual_ip: {get_param: [NetVipMap, external]} tripleo::haproxy::controller_virtual_ip: {get_param: [NetVipMap, ctlplane]} tripleo::keepalived::public_virtual_ip: {get_param: [NetVipMap, external]} tripleo::keepalived::controller_virtual_ip: {get_param: [NetVipMap, ctlplane]} tripleo::keepalived::internal_api_virtual_ip: {get_param: [NetVipMap, internal_api]} tripleo::keepalived::storage_virtual_ip: {get_param: [NetVipMap, storage]} tripleo::keepalived::storage_mgmt_virtual_ip: {get_param: [NetVipMap, storage_mgmt]} tripleo::keepalived::redis_virtual_ip: {get_param: RedisVirtualIP} tripleo::redis_notification::haproxy_monitor_ip: {get_param: [NetVipMap, ctlplane]} cloud_name_external: {get_param: cloud_name_external} cloud_name_internal_api: {get_param: cloud_name_internal_api} cloud_name_storage: {get_param: cloud_name_storage} cloud_name_storage_mgmt: {get_param: cloud_name_storage_mgmt} cloud_name_management: {get_param: cloud_name_management} outputs: config_id: description: The ID of the allNodesConfigImpl resource. value: {get_resource: allNodesConfigImpl} hosts_entries: description: | The content that should be appended to your /etc/hosts if you want to get hostname-based access to the deployed nodes (useful for testing without setting up a DNS). value: {get_attr: [allNodesConfigImpl, config, hosts]}