3

I'm currently developping a network configuration role used by Ansible to customize our fresh new virtual machine that came from our Debian 11 template.

The following role changes from DHCP to static interface configuration and then restart the networking service.For testing purpose i set IP/netmask/gateway as extra vars (and it's dynamically changed depends on the server i have to use my role)

  - name: ens3 reconfiguration 
    ansible.builtin.template:
      src: interfaces.j2
      dest: /etc/network/interfaces
 
  - name: Restart  networking.service
    ansible.builtin.service:
      name: networking
      state: restarted

Here's the content of interfaces.j2 for understanding.

# The primary network interface
auto ens3
iface ens3 inet static
  address {{ ens3_ip }}/{{ ens3_netmask }}
  gateway {{ ens3_gateway }}
  dns-nameservers X.X.X.X
  dns-search my_domain.net

The problem here is, as the network interface is dhcp configured, it has for example 10.0.0.1, i reconfigure it with 10.0.0.50, then Ansible move to the restart networking.service task, and gets hang forever...

**From an Ansible perspective, is it possible to dynamically reconnect to the host with the new IP ? or maybe, bypass the execution result of the restart networking.service ? **

motorbass
  • 303
  • 2
  • 12
  • This is really a duplicate for https://stackoverflow.com/questions/60181867/ansible-is-there-a-way-to-change-a-windows-server-ip-address-using-ansible/ – Peter Zhabin Feb 20 '23 at 16:29

1 Answers1

1

While very close to the question listed by https://serverfault.com/users/378597/peter-zhabin uses win_shell, which is not applicable to Linux.

Off the top of my head it seems like this would be the solution under Linux, changing win_shell for shell, although I slightly modified the suggestion so it aligns more closely to bash shell in Linux.

  1. Use async and poll for the network restart task.
  2. Then set_fact to update the nodes IP.
  3. Next wait until the ssh port responds on the new IP.
  4. Finally continue on with any remaining tasks.
  - name: Async restart of networking.service 
    shell: "sleep 1; systemctl restart networking.service &"
    args:
      executable: /bin/bash
    async: 100
    poll: 0
    
  - name: set_fact for the nodes new IP
    set_fact:
      ansible_host: "10.0.0.50"

  - name: wait_for ssh port access
    local_action:
      module: wait_for
      host: "{{ ansible_host }}"
      port: 22
      delay: 60
      state: started
    register: network_responding

Then add another task to the playbook after registering the wait_result and that task can have a conditional when clause like:

when: network_responding|bool == true

I converted the restart to shell with bash, backgrounding the restart operation. This may not be needed but YMMV trying to use the same logic with ansible.builtin.service, testing should be pretty simple to compare if doing this without shell is also viable.

  • Hi Trevor, sorry for the delay, went in hospital for many days... This works great ! thanks a lot :) now i just have to handle the SSH host identification & keys but it won't be tough. – motorbass Mar 07 '23 at 10:10