--- - name: Формируем отсортированный список физических интерфейсов ansible.builtin.set_fact: # Сортировка гарантирует порядок: первый в списке станет eth0 physical_interfaces: "{{ ansible_interfaces | json_query('[? !contains(`' + (ignored_interfaces | join(' ')) + '`, @)]') | sort }}" - name: Сохраняем сетевые настройки первого интерфейса (будущего eth0) ansible.builtin.set_fact: first_iface: "{{ physical_interfaces[0] }}" current_ip: "{{ hostvars[inventory_hostname]['ansible_' + physical_interfaces[0].replace('-', '_')]['ipv4']['address'] }}" current_mask: "{{ hostvars[inventory_hostname]['ansible_' + physical_interfaces[0].replace('-', '_')]['ipv4']['netmask'] }}" current_gw: "{{ ansible_default_ipv4.gateway | default(omit) }}" - name: Настройка eth0 с сохранением текущего IP community.general.nmcli: conn_name: eth0 ifname: eth0 type: ethernet mac: "{{ ansible_facts[first_iface]['macaddress'] }}" ip4: "{{ current_ip }}/{{ current_mask }}" gw4: "{{ current_gw }}" state: present autoconnect: true - name: Настройка остальных интерфейсов (eth1, eth2...) community.general.nmcli: conn_name: eth{{ item.0 + 1 }} ifname: eth{{ item.0 + 1 }} type: ethernet mac: "{{ ansible_facts[item.1]['macaddress'] }}" state: present autoconnect: true # Пропускаем первый (индекс 0), так как настроили его выше loop: "{{ physical_interfaces[1:] | enumerate }}" - name: Применение настроек (поднятие eth0) ansible.builtin.shell: nmcli device connect eth0 # noqa: command-instead-of-shell ignore-errors async: 20 poll: 0 ignore_errors: true # noqa: ignore-errors changed_when: true - name: Применение настроек для остальных интерфейсов ansible.builtin.shell: nmcli device connect eth{{ item.0 + 1 }} # noqa: command-instead-of-shell ignore-errors loop: "{{ physical_interfaces[1:] | enumerate }}" ignore_errors: true # noqa: ignore-errors changed_when: false - name: Перезапуск NetworkManager для чистоты ansible.builtin.systemd: name: NetworkManager state: restarted async: 30 poll: 0