kayobe/ansible/kolla-ansible.yml
Mark Goddard b12f9e35e5 Performance: Parallelise Kolla Ansible host vars generation
Kayobe generates a host_vars file for each host in the Kolla Ansible
inventory. These contain network interfaces and other host-specific
things. Currently this is done by iterating over all hosts, which does
not scale well with a large number of hosts.

This change extracts the host vars generation into a separate role, and
executes it in a play targeted at all hosts, with delegate_to:
localhost. This ensures that host variable files are generated in
parallel.

Story: 2007993
Task: 40629

Change-Id: Iae75e17024adee9c2874c14d3ed36f4c87ba48d7
2020-09-22 17:06:04 +01:00

325 lines
15 KiB
YAML

---
- name: Gather facts for localhost
hosts: localhost
gather_facts: true
tags: always
- name: Validate configuration options for kolla-ansible
hosts: localhost
tags:
- kolla-ansible
- config-validation
tasks:
- name: Validate serial console configuration
block:
- name: Check ipmitool-socat is in enabled in kolla_ironic_enabled_console_interfaces
fail:
msg: >
kolla_ironic_enabled_console_interfaces must contain ipmitool-socat if you set
ironic_serial_console_autoenable to true
when:
- kolla_ironic_enabled_console_interfaces is defined
- "'ipmitool-socat' not in kolla_ironic_enabled_console_interfaces"
when: ironic_serial_console_autoenable | bool
- name: Ensure Kolla Ansible is configured
hosts: localhost
tags:
- kolla-ansible
gather_facts: false
vars:
# We need to reference configuration for the network node.
# We pick the first host from the group for this. It is possible that at
# this point these groups have no hosts in, and we should handle that case
# gracefully.
network_host: "{{ groups['network'][0] }}"
pre_tasks:
# Configuration of extra user-provided Kolla globals.
- block:
- name: Check whether a Kolla extra globals configuration file exists
stat:
path: "{{ kayobe_config_path ~ '/kolla/globals.yml' }}"
get_checksum: False
get_md5: False
mime: False
register: globals_stat
- name: Read the Kolla extra globals configuration file
set_fact:
kolla_extra_globals: "{{ lookup('template', kayobe_config_path ~ '/kolla/globals.yml') | from_yaml }}"
when: globals_stat.stat.exists
tags:
- config
# Configuration and validation of network host networking.
- block:
- name: Set facts containing the VIP addresses and FQDNs
set_fact:
kolla_internal_vip_address: "{{ internal_net_name | net_vip_address }}"
kolla_internal_fqdn: "{{ internal_net_name | net_fqdn or internal_net_name | net_vip_address }}"
kolla_external_vip_address: "{{ public_net_name | net_vip_address }}"
kolla_external_fqdn: "{{ public_net_name | net_fqdn or public_net_name | net_vip_address }}"
when: kolla_enable_haproxy | bool
- name: Set facts containing the VIP addresses and FQDNs
set_fact:
kolla_internal_vip_address: "{{ internal_net_name | net_ip(network_host) }}"
kolla_internal_fqdn: "{{ internal_net_name | net_ip(network_host) }}"
kolla_external_vip_address: "{{ public_net_name | net_ip(network_host) }}"
kolla_external_fqdn: "{{ public_net_name | net_ip(network_host) }}"
when: not kolla_enable_haproxy | bool
- name: Validate Kolla Ansible API address configuration
fail:
msg: >
The Kolla Ansible variable {{ item.var_name }}
({{ item.description }}) is invalid. Value:
"{{ hostvars[inventory_hostname][item.var_name] | default('<undefined>') }}".
when:
- item.required | bool
- hostvars[inventory_hostname][item.var_name] is not defined or not hostvars[inventory_hostname][item.var_name]
with_items:
- var_name: "kolla_internal_vip_address"
description: "Internal API VIP address"
required: True
- var_name: "kolla_internal_fqdn"
description: "Internal API Fully Qualified Domain Name (FQDN)"
required: True
- var_name: "kolla_external_vip_address"
description: "external API VIP address"
required: True
- var_name: "kolla_external_fqdn"
description: "External API Fully Qualified Domain Name (FQDN)"
required: True
when: groups['network'] | length > 0
tags:
- config
- config-validation
- import_role:
name: kolla-ansible
vars:
kolla_ansible_install_epel: "{{ dnf_install_epel }}"
kolla_external_fqdn_cert: "{{ kolla_config_path }}/certificates/haproxy.pem"
kolla_internal_fqdn_cert: "{{ kolla_config_path }}/certificates/haproxy-internal.pem"
kolla_ansible_passwords_path: "{{ kayobe_config_path }}/kolla/passwords.yml"
kolla_overcloud_group_vars_path: "{{ kayobe_config_path }}/kolla/inventory/group_vars"
kolla_ansible_certificates_path: "{{ kayobe_config_path }}/kolla/certificates"
# NOTE: This differs from the default SELinux mode in kolla ansible,
# which is permissive. The justification for using this mode is twofold:
# 1. it avoids filling up the audit log
# 2. it avoids an issue seen when using diskimage-builder in the bifrost
# container.
# We could look at making the SELinux mode configurable in future.
kolla_selinux_state: disabled
kolla_inspector_dhcp_pool_start: "{{ inspection_net_name | net_inspection_allocation_pool_start }}"
kolla_inspector_dhcp_pool_end: "{{ inspection_net_name | net_inspection_allocation_pool_end }}"
kolla_inspector_default_gateway: "{{ inspection_net_name | net_inspection_gateway or inspection_net_name | net_gateway }}"
kolla_inspector_extra_kernel_options: "{{ inspector_extra_kernel_options }}"
kolla_enable_host_ntp: false
docker_daemon_mtu: "{{ public_net_name | net_mtu | default }}"
- name: Generate Kolla Ansible host vars for the seed host
hosts: seed
tags:
- config
- config-validation
- kolla-ansible
gather_facts: False
tasks:
- name: Set bifrost network interface
set_fact:
kolla_bifrost_network_interface: "{{ provision_oc_net_name | net_interface | replace('-', '_') }}"
when: provision_oc_net_name in network_interfaces
- name: Validate seed Kolla Ansible network configuration
fail:
msg: >
The Kolla Ansible variable {{ item.var_name }}
({{ item.description }}) is invalid. Value:
"{{ hostvars[inventory_hostname][item.var_name] | default('<undefined>') }}".
when:
- item.required | bool
- hostvars[inventory_hostname][item.var_name] is not defined or not hostvars[inventory_hostname][item.var_name]
with_items:
- var_name: "kolla_bifrost_network_interface"
description: "Bifrost network interface name"
required: True
# Strictly api_interface is not required but kolla-ansible currently
# references it in prechecks.
- name: Set API network interface
set_fact:
kolla_api_interface: "{{ kolla_bifrost_network_interface }}"
- import_role:
name: kolla-ansible-host-vars
vars:
kolla_ansible_pass_through_host_vars: "{{ kolla_seed_inventory_pass_through_host_vars }}"
kolla_ansible_pass_through_host_vars_map: "{{ kolla_seed_inventory_pass_through_host_vars_map }}"
kolla_ansible_inventory_path: "{{ kolla_config_path }}/inventory/seed"
- name: Generate Kolla Ansible host vars for overcloud hosts
hosts: overcloud
tags:
- config
- config-validation
- kolla-ansible
gather_facts: False
vars:
require_provider_networks: >-
{{ kolla_enable_neutron | bool and
(inventory_hostname in groups['network'] or
(kolla_enable_neutron_provider_networks | bool and inventory_hostname in groups['compute'])) }}
tasks:
- name: Set API network interface
set_fact:
kolla_network_interface: "{{ internal_net_name | net_interface | replace('-', '_') }}"
kolla_api_interface: "{{ internal_net_name | net_interface | replace('-', '_') }}"
when: internal_net_name in network_interfaces
- name: Set storage network interface
set_fact:
kolla_storage_interface: "{{ storage_net_name | net_interface | replace('-', '_') }}"
when: storage_net_name in network_interfaces
- name: Set cluster network interface
set_fact:
kolla_cluster_interface: "{{ storage_mgmt_net_name | net_interface | replace('-', '_') }}"
when: storage_mgmt_net_name in network_interfaces
- name: Set Swift storage network interface
set_fact:
kolla_swift_storage_interface: "{{ swift_storage_net_name | net_interface | replace('-', '_') }}"
when: swift_storage_net_name in network_interfaces
- name: Set Swift cluster network interface
set_fact:
kolla_swift_replication_interface: "{{ swift_storage_replication_net_name | net_interface | replace('-', '_') }}"
when: swift_storage_replication_net_name in network_interfaces
- name: Set provision network interface
set_fact:
kolla_provision_interface: "{{ provision_wl_net_name | net_interface | replace('-', '_') }}"
when: provision_wl_net_name in network_interfaces
- name: Set inspector dnsmasq network interface
set_fact:
kolla_inspector_dnsmasq_interface: "{{ inspection_net_name | net_interface | replace('-', '_') }}"
when: inspection_net_name in network_interfaces
- name: Set DNS network interface
set_fact:
kolla_dns_interface: "{{ public_net_name | net_interface | replace('-', '_') }}"
when: public_net_name in network_interfaces
- name: Set tunnel network interface
set_fact:
kolla_tunnel_interface: "{{ tunnel_net_name | net_interface | replace('-', '_') }}"
when: tunnel_net_name in network_interfaces
- name: Set external VIP interface
set_fact:
kolla_external_vip_interface: "{{ public_net_name | net_interface | replace('-', '_') }}"
when: public_net_name in network_interfaces
- name: Initialise facts containing the network host interfaces
set_fact:
# Initialise the following lists.
kolla_neutron_interfaces: []
kolla_neutron_bridge_names: []
kolla_neutron_external_interfaces: []
# When these networks are VLANs, we need to use the underlying tagged
# bridge interface rather than the untagged interface. We therefore
# strip the .<vlan> suffix of the interface name. We use a union here
# as a single tagged interface may be shared between these networks.
- name: Set a fact containing the interfaces to be plugged to the Neutron OVS bridges
set_fact:
kolla_neutron_interfaces: >
{{ kolla_neutron_interfaces |
union([item | net_interface | replace('.' ~ item | net_vlan | default('!nomatch!'), '')]) |
list }}
with_items: "{{ [provision_wl_net_name, cleaning_net_name] + external_net_names | unique | list }}"
when: item in network_interfaces
- name: Set facts containing the Neutron bridge and interface names
vars:
is_bridge: "{{ item in (network_interfaces | net_select_bridges | map('net_interface')) }}"
# For a bridge, use a veth pair connected to the bridge. Otherwise use
# the interface directly.
external_interface_name: "{{ (network_patch_prefix ~ item ~ network_patch_suffix_ovs) if is_bridge else item }}"
set_fact:
kolla_neutron_bridge_names: >
{{ kolla_neutron_bridge_names +
[item ~ network_bridge_suffix_ovs] }}
kolla_neutron_external_interfaces: >
{{ kolla_neutron_external_interfaces +
[external_interface_name] }}
with_items: "{{ kolla_neutron_interfaces }}"
- name: Validate overcloud host Kolla Ansible network configuration
fail:
msg: >
The Kolla Ansible variable {{ item.var_name }}
({{ item.description }}) is invalid. Value:
"{{ hostvars[inventory_hostname][item.var_name] | default('<undefined>') }}".
when:
- item.required | bool
- hostvars[inventory_hostname][item.var_name] is not defined or not hostvars[inventory_hostname][item.var_name]
with_items:
- var_name: "kolla_api_interface"
description: "API network interface name"
required: True
- var_name: "kolla_external_vip_interface"
description: "External network interface name"
required: "{{ inventory_hostname in groups['network'] }}"
- var_name: "kolla_provision_interface"
description: "Bare metal provisioning network interface name"
required: "{{ kolla_enable_ironic | bool and inventory_hostname in groups['controllers'] }}"
- var_name: "kolla_inspector_dnsmasq_interface"
description: "Bare metal introspection network interface name"
required: "{{ kolla_enable_ironic | bool and inventory_hostname in groups['controllers'] }}"
- var_name: "kolla_neutron_bridge_names"
description: "List of Neutron bridge names"
required: "{{ require_provider_networks }}"
- var_name: "kolla_neutron_external_interfaces"
description: "List of Neutron interface names"
required: "{{ require_provider_networks }}"
- name: Validate Kolla Ansible Neutron bridge and interface configuration
fail:
msg: >
The Kolla Ansible variable {{ item.0.var_name }}
({{ item.0.description }}) is invalid. Value:
"{{ item.1 | default('<undefined>') }}".
when:
- item.0.required | bool
- item.1 is not defined or not item.1
with_subelements:
- - var_name: "kolla_neutron_bridge_names"
value: "{{ kolla_neutron_bridge_names }}"
description: "List of Neutron bridge names"
required: "{{ require_provider_networks }}"
- var_name: "kolla_neutron_external_interfaces"
value: "{{ kolla_neutron_external_interfaces }}"
description: "List of Neutron interface names"
required: "{{ require_provider_networks }}"
- value
# Kolla ansible expects these variables to be comma-separated lists.
- name: Update facts containing the Neutron bridge and interface names
set_fact:
kolla_neutron_bridge_names: "{{ kolla_neutron_bridge_names | join(',') }}"
kolla_neutron_external_interfaces: "{{ kolla_neutron_external_interfaces | join(',') }}"
- import_role:
name: kolla-ansible-host-vars
vars:
kolla_ansible_pass_through_host_vars: "{{ kolla_overcloud_inventory_pass_through_host_vars }}"
kolla_ansible_pass_through_host_vars_map: "{{ kolla_overcloud_inventory_pass_through_host_vars_map }}"
kolla_ansible_inventory_path: "{{ kolla_config_path }}/inventory/overcloud"
# Kolla ansible expects these variables to be comma-separated lists.
kolla_neutron_bridge_names: "{{ kolla_neutron_bridge_names | join(',') }}"
kolla_neutron_external_interfaces: "{{ kolla_neutron_external_interfaces | join(',') }}"