From 6194b950053c37295213323c95fc7220466367f3 Mon Sep 17 00:00:00 2001 From: Bartosz Bezak Date: Wed, 26 Nov 2025 14:36:51 +0100 Subject: [PATCH 1/7] Bifrost: Add inspector_keep_ports option Default value stays `present` to match Bifrost (overcloud ironic default remains `added`). Change-Id: Iffc8de818e80ee42f5946e2ef04b997d8a9a2f67 Signed-off-by: Bartosz Bezak --- ansible/inventory/group_vars/all/bifrost | 4 ++++ ansible/roles/kolla-bifrost/defaults/main.yml | 3 +++ .../templates/kolla/config/bifrost/bifrost.yml | 5 +++++ doc/source/configuration/reference/bifrost.rst | 3 +++ etc/kayobe/bifrost.yml | 4 ++++ releasenotes/notes/bifrost-keep-ports-5f2e583a201645b9.yaml | 6 ++++++ 6 files changed, 25 insertions(+) create mode 100644 releasenotes/notes/bifrost-keep-ports-5f2e583a201645b9.yaml diff --git a/ansible/inventory/group_vars/all/bifrost b/ansible/inventory/group_vars/all/bifrost index fc02cf5a0..f307c4118 100644 --- a/ansible/inventory/group_vars/all/bifrost +++ b/ansible/inventory/group_vars/all/bifrost @@ -96,6 +96,10 @@ kolla_bifrost_inspector_hooks: "{{ inspector_hooks }}" # 'active' or 'pxe'. kolla_bifrost_inspector_port_addition: "{{ inspector_add_ports }}" +# Which ports to keep after introspection. One of 'all', 'present', or 'added'. +# Default follows Bifrost's default of 'present'. +kolla_bifrost_inspector_keep_ports: "present" + # List of extra kernel parameters for the inspector default PXE configuration. # Default is {{ inspector_extra_kernel_options }}, defined in inspector.yml. # When customising this variable, the default extra kernel parameters should be diff --git a/ansible/roles/kolla-bifrost/defaults/main.yml b/ansible/roles/kolla-bifrost/defaults/main.yml index eff98ea8f..2ab957d03 100644 --- a/ansible/roles/kolla-bifrost/defaults/main.yml +++ b/ansible/roles/kolla-bifrost/defaults/main.yml @@ -48,6 +48,9 @@ kolla_bifrost_inspector_hooks: # 'active' or 'pxe'. kolla_bifrost_inspector_port_addition: +# Which ports to keep after introspection. One of 'all', 'present', or 'added'. +kolla_bifrost_inspector_keep_ports: + # List of extra kernel parameters for the inspector default PXE configuration. kolla_bifrost_inspector_extra_kernel_options: diff --git a/ansible/roles/kolla-bifrost/templates/kolla/config/bifrost/bifrost.yml b/ansible/roles/kolla-bifrost/templates/kolla/config/bifrost/bifrost.yml index e1e671b67..712bed6de 100644 --- a/ansible/roles/kolla-bifrost/templates/kolla/config/bifrost/bifrost.yml +++ b/ansible/roles/kolla-bifrost/templates/kolla/config/bifrost/bifrost.yml @@ -39,6 +39,11 @@ inspector_hooks: "{{ kolla_bifrost_inspector_hooks | join(',') }}" inspector_port_addition: "{{ kolla_bifrost_inspector_port_addition }}" {% endif %} +{% if kolla_bifrost_inspector_keep_ports %} +# Which ports to keep after introspection. One of 'all', 'present', or 'added'. +inspector_keep_ports: "{{ kolla_bifrost_inspector_keep_ports }}" +{% endif %} + {% if kolla_bifrost_inspector_extra_kernel_options %} # Extra kernel parameters for the inspector default PXE configuration. inspector_extra_kernel_options: "{{ kolla_bifrost_inspector_extra_kernel_options if kolla_bifrost_inspector_extra_kernel_options is string else kolla_bifrost_inspector_extra_kernel_options | join(' ') }}" diff --git a/doc/source/configuration/reference/bifrost.rst b/doc/source/configuration/reference/bifrost.rst index cbd3e738e..62ab636be 100644 --- a/doc/source/configuration/reference/bifrost.rst +++ b/doc/source/configuration/reference/bifrost.rst @@ -276,6 +276,9 @@ The following options configure the Ironic Inspector service in the Which MAC addresses to add as ports during introspection. One of ``all``, ``active`` or ``pxe``. Default is ``{{ inspector_add_ports }}``, defined in ``${KAYOBE_CONFIG_PATH}/inspector.yml``. +``kolla_bifrost_inspector_keep_ports`` + Which ports to keep after introspection. One of ``all``, ``present`` or + ``added``. Default is ``present`` to align with Bifrost's defaults. ``kolla_bifrost_inspector_extra_kernel_options`` List of extra kernel parameters for the inspector default PXE configuration. Default is ``{{ inspector_extra_kernel_options }}``, defined diff --git a/etc/kayobe/bifrost.yml b/etc/kayobe/bifrost.yml index 4150e6600..d65c9d27d 100644 --- a/etc/kayobe/bifrost.yml +++ b/etc/kayobe/bifrost.yml @@ -96,6 +96,10 @@ # 'active' or 'pxe'. #kolla_bifrost_inspector_port_addition: +# Which ports to keep after introspection. One of 'all', 'present', or 'added'. +# Default follows Bifrost's default of 'present'. +#kolla_bifrost_inspector_keep_ports: + # List of extra kernel parameters for the inspector default PXE configuration. # Default is {{ inspector_extra_kernel_options }}, defined in inspector.yml. # When customising this variable, the default extra kernel parameters should be diff --git a/releasenotes/notes/bifrost-keep-ports-5f2e583a201645b9.yaml b/releasenotes/notes/bifrost-keep-ports-5f2e583a201645b9.yaml new file mode 100644 index 000000000..9041d79a4 --- /dev/null +++ b/releasenotes/notes/bifrost-keep-ports-5f2e583a201645b9.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Allows configuring ``inspector_keep_ports`` for Bifrost via + ``kolla_bifrost_inspector_keep_ports`` (defaults to ``present`` to match + Bifrost). From ec066451766f43873081b6f1120791ddfe05ef09 Mon Sep 17 00:00:00 2001 From: Pierre Riteau Date: Fri, 5 Dec 2025 09:03:35 +0100 Subject: [PATCH 2/7] Revert "[release] Use OpenStack 2025.2 release" This reverts commit 237e8b07e046b1736f74f648e4c489644e4aad3c. Reason for revert: 2025.2 has been branched and released Change-Id: I36e92d7f4eea44b7f0b1606e9f09a2e6fd6210f3 Signed-off-by: Pierre Riteau --- ansible/inventory/group_vars/all/openstack | 6 +++--- etc/kayobe/openstack.yml | 4 ++-- requirements.yml | 2 +- tox.ini | 10 +++++----- zuul.d/jobs.yaml | 8 -------- 5 files changed, 11 insertions(+), 19 deletions(-) diff --git a/ansible/inventory/group_vars/all/openstack b/ansible/inventory/group_vars/all/openstack index a62a39a31..430293d3f 100644 --- a/ansible/inventory/group_vars/all/openstack +++ b/ansible/inventory/group_vars/all/openstack @@ -2,10 +2,10 @@ ############################################################################### # OpenStack release configuration. -# Name of the current OpenStack release. Default is "2025.2". -openstack_release: "2025.2" +# Name of the current OpenStack release. Default is "master". +openstack_release: "master" -# Name of the current OpenStack branch. Default is "stable/2025.2". +# Name of the current OpenStack branch. Default is "master". openstack_branch: >- {% if openstack_release != 'master' %}stable/{% endif %}{{ openstack_release | lower }} diff --git a/etc/kayobe/openstack.yml b/etc/kayobe/openstack.yml index d58a145fe..1acfd0756 100644 --- a/etc/kayobe/openstack.yml +++ b/etc/kayobe/openstack.yml @@ -2,10 +2,10 @@ ############################################################################### # OpenStack release configuration. -# Name of the current OpenStack release. Default is "2025.2". +# Name of the current OpenStack release. Default is "master". #openstack_release: -# Name of the current OpenStack branch. Default is "stable/2025.2". +# Name of the current OpenStack branch. Default is "master". #openstack_branch: ############################################################################### diff --git a/requirements.yml b/requirements.yml index 300f6ea5a..a52a64662 100644 --- a/requirements.yml +++ b/requirements.yml @@ -2,7 +2,7 @@ collections: - name: https://opendev.org/openstack/ansible-collection-kolla type: git - version: stable/2025.2 + version: master - name: community.docker version: 3.11.0 - name: community.network diff --git a/tox.ini b/tox.ini index c15275dcf..a8ea73ca1 100644 --- a/tox.ini +++ b/tox.ini @@ -19,7 +19,7 @@ setenv = OS_TEST_TIMEOUT=60 ANSIBLE_VERBOSITY=3 deps = - -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/2025.2} + -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt commands = stestr run {posargs} @@ -27,7 +27,7 @@ commands = stestr run {posargs} [testenv:pep8] # sphinx8 needs the sphinx package which is required via doc/requirements.txt deps = - -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/2025.2} + -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/requirements.txt -r{toxinidir}/doc/requirements.txt -r{toxinidir}/test-requirements.txt @@ -42,7 +42,7 @@ commands = [testenv:venv] deps = - -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/2025.2} + -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/test-requirements.txt -r{toxinidir}/doc/requirements.txt commands = {posargs} @@ -60,7 +60,7 @@ commands = [testenv:molecule] deps = - -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/2025.2} + -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/requirements.txt -r{toxinidir}/molecule-requirements.txt commands = @@ -131,7 +131,7 @@ commands = [testenv:docs] deps = - -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/2025.2} + -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/doc/requirements.txt commands = rm -rf doc/build/html diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml index 61b2bd44a..2af930cf3 100644 --- a/zuul.d/jobs.yaml +++ b/zuul.d/jobs.yaml @@ -71,19 +71,11 @@ required-projects: # Include kayobe to ensure other projects can use this job. - name: openstack/ansible-collection-kolla - # TODO(priteau): Remove when kayobe stable/2025.2 exists. - override-checkout: stable/2025.2 - name: openstack/kayobe - name: openstack/kayobe-config-dev - name: openstack/kolla - # TODO(priteau): Remove when kayobe stable/2025.2 exists. - override-checkout: stable/2025.2 - name: openstack/kolla-ansible - # TODO(priteau): Remove when kayobe stable/2025.2 exists. - override-checkout: stable/2025.2 - name: openstack/requirements - # TODO(priteau): Remove when kayobe stable/2025.2 exists. - override-checkout: stable/2025.2 - name: openstack/tenks irrelevant-files: - ^\..+ From 390d9663e2913587041a2118bfa3fce03a3fd3f8 Mon Sep 17 00:00:00 2001 From: Pierre Riteau Date: Sat, 6 Dec 2025 10:04:01 +0100 Subject: [PATCH 3/7] Document another change when moving to unmaintained Change-Id: Ie3743e0b54c32a8cbc7995f4b5c3e59b4f01d96b Signed-off-by: Pierre Riteau --- doc/source/contributor/releases.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/source/contributor/releases.rst b/doc/source/contributor/releases.rst index a95a93599..b54ee295a 100644 --- a/doc/source/contributor/releases.rst +++ b/doc/source/contributor/releases.rst @@ -253,6 +253,12 @@ all references to ``stable/`` need to be changed to unmaintained branch. For example, see https://review.opendev.org/c/openstack/kayobe/+/968298. +More recent releases which include upgrade jobs from the unmaintained release +should update their CI configuration to use the +``unmaintained/`` branch. For example, see +https://review.opendev.org/c/openstack/kayobe/+/969411 and +https://review.opendev.org/c/openstack/kayobe/+/970016. + Transitioning to End of Life (EOL) ================================== From 3c2cf92507ca0a493d1454b34dcc47f2673f830b Mon Sep 17 00:00:00 2001 From: Pierre Riteau Date: Tue, 9 Dec 2025 21:52:23 +0100 Subject: [PATCH 4/7] CI: Ensure firewalld is unmasked Recent nodepool images are masking the firewalld service [1], but we need it for host configure jobs. [1] https://review.opendev.org/c/opendev/zuul-providers/+/967962 Change-Id: Ic72f2e3a262d6491da8bc39de19e23c3acbedf89 Signed-off-by: Pierre Riteau --- playbooks/kayobe-overcloud-host-configure-base/pre.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/playbooks/kayobe-overcloud-host-configure-base/pre.yml b/playbooks/kayobe-overcloud-host-configure-base/pre.yml index a0bfb9252..d564c45a8 100644 --- a/playbooks/kayobe-overcloud-host-configure-base/pre.yml +++ b/playbooks/kayobe-overcloud-host-configure-base/pre.yml @@ -43,3 +43,9 @@ become: true loop: "{{ range(2, 8) | list }}" when: ansible_facts.os_family == 'Debian' + + - name: Ensure firewalld is unmasked + ansible.builtin.systemd_service: + name: firewalld + masked: false + become: true From ec5c5e6b6cdba9644c3486d4fdee5053801cf3f9 Mon Sep 17 00:00:00 2001 From: Thomas Sell Date: Sat, 8 Nov 2025 17:29:33 +0100 Subject: [PATCH 5/7] Add configuration for Ironic introspection DNS servers Closes-Bug: #2130947 Depends-On: https://review.opendev.org/c/openstack/kolla-ansible/+/966023 Change-Id: Ie5ea55953eb1c0cc04a2d387bf99bd542da396eb Signed-off-by: Thomas Sell --- ansible/kolla-ansible.yml | 1 + ansible/roles/kolla-ansible/defaults/main.yml | 3 +++ ansible/roles/kolla-ansible/templates/kolla/globals.yml | 3 +++ doc/source/configuration/reference/network.rst | 9 +++++++-- kayobe/plugins/filter/networks.py | 7 +++++++ .../notes/dns-config-ironic-dhcp-967a99a01005a6bc.yaml | 5 +++++ 6 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/dns-config-ironic-dhcp-967a99a01005a6bc.yaml diff --git a/ansible/kolla-ansible.yml b/ansible/kolla-ansible.yml index 55b79c530..34ae1ac87 100644 --- a/ansible/kolla-ansible.yml +++ b/ansible/kolla-ansible.yml @@ -99,6 +99,7 @@ kolla_inspector_dhcp_pool_end: "{{ inspection_net_name | net_inspection_allocation_pool_end }}" kolla_inspector_netmask: "{{ inspection_net_name | net_mask }}" kolla_inspector_default_gateway: "{{ inspection_net_name | net_inspection_gateway or inspection_net_name | net_gateway }}" + kolla_inspector_dns_servers: "{{ inspection_net_name | net_inspection_dns_servers }}" kolla_inspector_extra_kernel_options: "{{ inspector_extra_kernel_options }}" kolla_libvirt_tls: "{{ compute_libvirt_enable_tls | bool }}" kolla_globals_paths_static: diff --git a/ansible/roles/kolla-ansible/defaults/main.yml b/ansible/roles/kolla-ansible/defaults/main.yml index 9ea9849c0..f95225b74 100644 --- a/ansible/roles/kolla-ansible/defaults/main.yml +++ b/ansible/roles/kolla-ansible/defaults/main.yml @@ -200,6 +200,9 @@ kolla_inspector_netmask: # Default gateway to use for inspection network. kolla_inspector_default_gateway: +# DNS servers for inspection network. +kolla_inspector_dns_servers: [] + # List of extra kernel parameters for the inspector default PXE configuration. kolla_inspector_extra_kernel_options: [] diff --git a/ansible/roles/kolla-ansible/templates/kolla/globals.yml b/ansible/roles/kolla-ansible/templates/kolla/globals.yml index a1a01451d..2fbe8e40a 100644 --- a/ansible/roles/kolla-ansible/templates/kolla/globals.yml +++ b/ansible/roles/kolla-ansible/templates/kolla/globals.yml @@ -401,6 +401,9 @@ ironic_dnsmasq_dhcp_ranges: {% if kolla_inspector_default_gateway %} routers: "{{ kolla_inspector_default_gateway }}" {% endif %} +{% if kolla_inspector_dns_servers %} + dns_servers: "{{ kolla_inspector_dns_servers | join(',') }}" +{% endif %} {% endif %} {% if kolla_inspector_extra_kernel_options %} ironic_inspector_kernel_cmdline_extras: diff --git a/doc/source/configuration/reference/network.rst b/doc/source/configuration/reference/network.rst index 595d1e110..19234a67e 100644 --- a/doc/source/configuration/reference/network.rst +++ b/doc/source/configuration/reference/network.rst @@ -39,6 +39,8 @@ supported: IP address of the gateway for the hardware introspection network. ``neutron_gateway`` IP address of the gateway for a neutron subnet based on this network. +``inspection_dns_servers`` + List of DNS servers used during hardware introspection. ``vlan`` VLAN ID. ``mtu`` @@ -828,19 +830,22 @@ If using the overcloud to inspect bare metal workload (compute) hosts, it is necessary to define a DHCP allocation pool for the overcloud's ironic inspector DHCP server using the ``inspection_allocation_pool_start`` and ``inspection_allocation_pool_end`` attributes of the workload provisioning -network. +network. If ``kolla_internal_fqdn`` is set, it is mandatory to also supply one +or more DNS servers using ``inspection_dns_servers``. .. note:: This example assumes that the ``example`` network is mapped to ``provision_wl_net_name``. -To configure a network called ``example`` with an inspection allocation pool: +To configure a network called ``example`` with an inspection allocation pool +and inspection DNS servers: .. code-block:: yaml example_inspection_allocation_pool_start: 10.0.1.196 example_inspection_allocation_pool_end: 10.0.1.254 + example_inspection_dns_servers: [10.0.1.10, 10.0.1.11] .. note:: diff --git a/kayobe/plugins/filter/networks.py b/kayobe/plugins/filter/networks.py index f949d7982..adf74460b 100644 --- a/kayobe/plugins/filter/networks.py +++ b/kayobe/plugins/filter/networks.py @@ -246,6 +246,12 @@ def net_inspection_allocation_pool_end(context, name, inventory_hostname=None): net_inspection_gateway = _make_attr_filter('inspection_gateway') +@jinja2.pass_context +def net_inspection_dns_servers(context, name, inventory_hostname=None): + return net_attr(context, name, 'inspection_dns_servers', + inventory_hostname) + + @jinja2.pass_context def net_neutron_allocation_pool_start(context, name, inventory_hostname=None): return net_attr(context, name, 'neutron_allocation_pool_start', @@ -791,6 +797,7 @@ def get_filters(): 'net_inspection_allocation_pool_end': ( net_inspection_allocation_pool_end), 'net_inspection_gateway': net_inspection_gateway, + 'net_inspection_dns_servers': net_inspection_dns_servers, 'net_neutron_allocation_pool_start': net_neutron_allocation_pool_start, 'net_neutron_allocation_pool_end': net_neutron_allocation_pool_end, 'net_neutron_gateway': net_neutron_gateway, diff --git a/releasenotes/notes/dns-config-ironic-dhcp-967a99a01005a6bc.yaml b/releasenotes/notes/dns-config-ironic-dhcp-967a99a01005a6bc.yaml new file mode 100644 index 000000000..5d234371e --- /dev/null +++ b/releasenotes/notes/dns-config-ironic-dhcp-967a99a01005a6bc.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Configure inspection network DNS servers to enable Ironic inspection + when ``kolla_internal_fqdn`` is set. From f773cd04888ebd6b3d728ac418ff320cba7252aa Mon Sep 17 00:00:00 2001 From: Pierre Riteau Date: Mon, 15 Dec 2025 07:19:05 +0100 Subject: [PATCH 6/7] CI: Use centos:stream10 image for molecule Change-Id: Ie39a9975a6d9bec8e118d1d7e7a67fe2095b66a4 Signed-off-by: Pierre Riteau --- ansible/roles/kolla-openstack/molecule/default/molecule.yml | 4 ++-- .../kolla-openstack/molecule/enable-everything/molecule.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ansible/roles/kolla-openstack/molecule/default/molecule.yml b/ansible/roles/kolla-openstack/molecule/default/molecule.yml index 241f5d400..8827f3a99 100644 --- a/ansible/roles/kolla-openstack/molecule/default/molecule.yml +++ b/ansible/roles/kolla-openstack/molecule/default/molecule.yml @@ -8,8 +8,8 @@ driver: lint: | yamllint . platforms: - - name: centos-stream9 - image: quay.io/centos/centos:stream9 + - name: centos-stream10 + image: quay.io/centos/centos:stream10 network_mode: host provisioner: name: ansible diff --git a/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml b/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml index 9fcabb6b2..acf40bd1b 100644 --- a/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml +++ b/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml @@ -8,8 +8,8 @@ driver: lint: | yamllint . platforms: - - name: centos-stream9 - image: quay.io/centos/centos:stream9 + - name: centos-stream10 + image: quay.io/centos/centos:stream10 network_mode: host provisioner: name: ansible From 1444d7947b154a251167cdb7aa54ef0b253aa079 Mon Sep 17 00:00:00 2001 From: Pierre Riteau Date: Thu, 18 Dec 2025 17:04:33 +0100 Subject: [PATCH 7/7] Use opendevmirror/ubuntu:24.04 image for molecule Molecule jobs were failing on centos:stream10 when CPU did not support x86-64-v3. Change-Id: I953ab956250d6dcc6e96212057db01f438c69d78 Signed-off-by: Pierre Riteau --- ansible/roles/kolla-openstack/molecule/default/molecule.yml | 4 ++-- .../kolla-openstack/molecule/enable-everything/molecule.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ansible/roles/kolla-openstack/molecule/default/molecule.yml b/ansible/roles/kolla-openstack/molecule/default/molecule.yml index 8827f3a99..6bef4caa3 100644 --- a/ansible/roles/kolla-openstack/molecule/default/molecule.yml +++ b/ansible/roles/kolla-openstack/molecule/default/molecule.yml @@ -8,8 +8,8 @@ driver: lint: | yamllint . platforms: - - name: centos-stream10 - image: quay.io/centos/centos:stream10 + - name: ubuntu-noble + image: quay.io/opendevmirror/ubuntu:24.04 network_mode: host provisioner: name: ansible diff --git a/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml b/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml index acf40bd1b..035a4cb09 100644 --- a/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml +++ b/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml @@ -8,8 +8,8 @@ driver: lint: | yamllint . platforms: - - name: centos-stream10 - image: quay.io/centos/centos:stream10 + - name: ubuntu-noble + image: quay.io/opendevmirror/ubuntu:24.04 network_mode: host provisioner: name: ansible