heat_template_version: pike description: 'All Nodes Config for Puppet' parameters: {%- for network in networks if network.vip|default(false) %} cloud_name_{{network.name_lower}}: type: string {%- endfor %} cloud_name_ctlplane: type: string enabled_services: type: comma_delimited_list controller_ips: type: comma_delimited_list service_ips: type: json service_node_names: type: json short_service_node_names: type: json short_service_bootstrap_node: type: json controller_names: 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 default: '' 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. Note StackUpdateType is set to UPGRADE when a major-version upgrade is in progress. constraints: - allowed_values: ['CREATE', 'UPDATE'] StackUpdateType: type: string description: > Type of update, to differentiate between UPGRADE and UPDATE cases when StackAction is UPDATE (both are the same stack action). constraints: - allowed_values: ['', 'UPGRADE'] default: '' # NOTE(jaosorior): This is being set as IPA as it's the first # CA we'll actually be testing out. But we can change this if # people request it. CertmongerCA: type: string default: 'IPA' EnableInternalTLS: type: boolean default: false {%- for network in networks %} {{network.name}}NetName: default: {{network.name_lower}} description: The name of the {{network.name_lower}} network. type: string {%- endfor %} resources: allNodesConfigImpl: type: OS::Heat::StructuredConfig properties: group: hiera config: datafiles: bootstrap_node: bootstrap_nodeid: {get_input: bootstrap_nodeid} bootstrap_nodeid_ip: {get_input: bootstrap_nodeid_ip} all_nodes: map_merge: - enabled_services: yaql: expression: $.data.distinct() data: {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: {get_param: enabled_services} # Dynamically generate per-service network data # This works as follows (outer->inner functions) # yaql - filters services where no mapping exists in ServiceNetMap # 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_merge: repeat: template: SERVICE_network: SERVICE_network for_each: SERVICE: {get_param: enabled_services} - values: {get_param: ServiceNetMap} # Keystone doesn't provide separate entries for the public # and admin endpoints, so we need to add them here manually # like we do in the vip-config below - keystone_admin_api_network: {get_param: [ServiceNetMap, keystone_admin_api_network]} keystone_public_api_network: {get_param: [ServiceNetMap, keystone_public_api_network]} # provides a mapping of service_name_ips to a list of IPs - {get_param: service_ips} - {get_param: service_node_names} - {get_param: short_service_node_names} - {get_param: short_service_bootstrap_node} - controller_node_ips: list_join: - ',' - {get_param: controller_ips} controller_node_names: list_join: - ',' - {get_param: controller_names} deploy_identifier: {get_param: DeployIdentifier} update_identifier: {get_param: UpdateIdentifier} stack_action: {get_param: StackAction} stack_update_type: {get_param: StackUpdateType} vip_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: {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, {get_param: ExternalNetName}]} controller_virtual_ip: {get_param: [NetVipMap, ctlplane]} internal_api_virtual_ip: {get_param: [NetVipMap, {get_param: InternalApiNetName}]} storage_virtual_ip: {get_param: [NetVipMap, {get_param: StorageNetName}]} storage_mgmt_virtual_ip: {get_param: [NetVipMap, {get_param: StorageMgmtNetName}]} 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, {get_param: ExternalNetName}]} tripleo::haproxy::controller_virtual_ip: {get_param: [NetVipMap, ctlplane]} tripleo::keepalived::public_virtual_ip: {get_param: [NetVipMap, {get_param: ExternalNetName}]} tripleo::keepalived::controller_virtual_ip: {get_param: [NetVipMap, ctlplane]} tripleo::keepalived::internal_api_virtual_ip: {get_param: [NetVipMap, {get_param: InternalApiNetName}]} tripleo::keepalived::storage_virtual_ip: {get_param: [NetVipMap, {get_param: StorageNetName}]} tripleo::keepalived::storage_mgmt_virtual_ip: {get_param: [NetVipMap, {get_param: StorageMgmtNetName}]} 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_ctlplane: {get_param: cloud_name_ctlplane} # TLS parameters certmonger_ca: {get_param: CertmongerCA} enable_internal_tls: {get_param: EnableInternalTLS} outputs: config_id: description: The ID of the allNodesConfigImpl resource. value: {get_resource: allNodesConfigImpl}