# Use Ansible facts to convert netplan from DHCP to static

**URL:** <https://forum.ansible.com/t/use-ansible-facts-to-convert-netplan-from-dhcp-to-static/1235>\
**Category:** Get Help\
**Tags:** network\
**Created:** [October 2, 2023, 12:47am UTC](https://forum.ansible.com/t/use-ansible-facts-to-convert-netplan-from-dhcp-to-static/1235 "2023-10-02T00:47:43Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![sprior](https://avatars.discourse-cdn.com/v4/letter/s/f08c70/32.png) [@sprior](https://forum.ansible.com/u/sprior)\
**Post date:** [October 2, 2023, 12:47am UTC](https://forum.ansible.com/t/use-ansible-facts-to-convert-netplan-from-dhcp-to-static/1235/1 "2023-10-02T00:47:43Z")

</div>

In my network I keep track of all static assigned IP addresses in my DHCP config. So I’ll connect a new device to my network and let DHCP give it a temp IP and arpwatch emails me its MAC address, then I decide what the perm address should be and add that to my DHCP config so the device reconnects at its new assigned IP.

But I prefer to configure servers with their static IP config so they’ll come up fine even if they come up faster than the DHCP server. So I’ll change the netplan to match the address the server already got from DHCP.

I saw solutions using a full template for the netplan config file but I decided to try the role by mrlesmithjr/ansible-netplan ([GitHub - mrlesmithjr/ansible-netplan](https://github.com/mrlesmithjr/ansible-netplan)) and I’m pretty close but can’t figure out the last bit.

I created my own task with the following:

```auto
- name: DHCP to static
  ansible.builtin.include_role:
    name: mrlesmithjr.netplan
  vars:
    netplan_enabled: true
    netplan_config_file: /etc/netplan/00-installer-config.yaml
    netplan_configuration:
      network:
        version: 2
        ethernets:
          enp3s0:
            addresses:
              - "{{ ansible_default_ipv4.address }}/24"
            routes:
              - to: default
                via: "{{ ansible_default_ipv4.gateway }}"
            nameservers:
              addresses:
                - 192.168.0.70
                - 192.168.0.72
              search:
                "{{ ansible_dns.search }}"
    netplan_remove_existing: true
    netplan_check_install: true
    netplan_apply: true

```

The last bit is that I’d like to use the ansible\_default\_ipv4.interface to fill in the interface device name, but couldn’t figure out how to build that into the above.

Can anyone suggest a way to do that?

---

<div class="post-metadata">

**Author:** ![jbericat](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jbericat/32/627_2.png) [@jbericat](https://forum.ansible.com/u/jbericat)\
**Post date:** [October 2, 2023, 7:01am UTC](https://forum.ansible.com/t/use-ansible-facts-to-convert-netplan-from-dhcp-to-static/1235/2 "2023-10-02T07:01:17Z")

</div>

Hello @sprior,

You could achieve that If you previously set a dict on a fact for your network config and then you pass the whole dict to the role, something like this:

```yaml
- name: PLAYBOOK
  gather_facts: true
  hosts: localhost
  vars:
    my_iface: "{{ ansible_default_ipv4.interface }}"
    my_iface_data:
      addresses:
        - "{{ ansible_default_ipv4.address }}/24"
      routes:
        - to: default
          via: "{{ ansible_default_ipv4.gateway }}"
      nameservers:
        addresses:
          - 192.168.0.70
          - 192.168.0.72
        search:
          "{{ ansible_dns.search | default('not_found_in_facts') }}"
  tasks:

    - name: Task 1. prepare network dict
      ansible.builtin.set_fact:
        my_network:
          version: 2
          ethernets: "{{ { my_iface:my_iface_data } }}"

    - name: Task 2. Showing the new dict
      ansible.builtin.debug:
        var: my_network

    - name: Task 3. Build the actual netplan config file
      ansible.builtin.include_role:
        name: mrlesmithjr.netplan
      vars:
        netplan_enabled: true
        netplan_config_file: /etc/netplan/00-installer-config.yaml
        netplan_configuration:
          network: "{{ my_network }}"
        netplan_remove_existing: true
        netplan_check_install: true
        netplan_apply: true

```

I haven’t tested all the tasks since I didn’t wanted to install the role on my local machine, but I believe it should work. Debugging the `my_network` fact gives something like this:

```yml
eth0:
  addresses:
    - "172.23.188.206/24"
  nameservers:
    addresses:
      - "192.168.0.70"
      - "192.168.0.72"
    search: "not_found_in_facts"
  routes:
    - to: "default"
      via: "172.23.176.1"
version: 2

```

Hope it helps!

Cheers

---

<div class="post-metadata">

**Author:** ![sprior](https://avatars.discourse-cdn.com/v4/letter/s/f08c70/32.png) [@sprior](https://forum.ansible.com/u/sprior)\
**Post date:** [October 3, 2023, 4:41am UTC](https://forum.ansible.com/t/use-ansible-facts-to-convert-netplan-from-dhcp-to-static/1235/3 "2023-10-03T04:41:33Z")

</div>

Thanks, that seems to have worked! It also gives me a technique to study and get familiar with, I really appreciate the time you put into that.

---

<div class="post-metadata">

**Author:** ![sprior](https://avatars.discourse-cdn.com/v4/letter/s/f08c70/32.png) [@sprior](https://forum.ansible.com/u/sprior)\
**Post date:** [October 3, 2023, 4:43am UTC](https://forum.ansible.com/t/use-ansible-facts-to-convert-netplan-from-dhcp-to-static/1235/4 "2023-10-03T04:43:07Z")

</div>

The form I went with is:

```auto
- name: Task 1. prepare network dict
  vars:
    my_iface: "{{ ansible_default_ipv4.interface }}"
    my_iface_data:
      addresses:
        - "{{ ansible_default_ipv4.address }}/24"
      routes:
        - to: default
          via: "{{ ansible_default_ipv4.gateway }}"
      nameservers:
        addresses:
          - 192.168.0.70
          - 192.168.0.72
        search:
          "{{ ansible_dns.search | default('not_found_in_facts') }}"
  ansible.builtin.set_fact:
    my_network:
      version: 2
      ethernets: "{{ { my_iface:my_iface_data } }}"

- name: Task 2. Showing the new dict
  ansible.builtin.debug:
    var: my_network

- name: Task 3. Build the actual netplan config file
  ansible.builtin.include_role:
    name: mrlesmithjr.netplan
  vars:
    netplan_enabled: true
    netplan_config_file: /etc/netplan/00-installer-config.yaml
    netplan_configuration:
      network: "{{ my_network }}"
    netplan_remove_existing: true
    netplan_check_install: true
    netplan_apply: true

```

---

<div class="post-metadata">

**Author:** ![jbericat](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jbericat/32/627_2.png) [@jbericat](https://forum.ansible.com/u/jbericat)\
**Post date:** [October 3, 2023, 5:40am UTC](https://forum.ansible.com/t/use-ansible-facts-to-convert-netplan-from-dhcp-to-static/1235/5 "2023-10-03T05:40:22Z")

</div>

You’re welcome Steve! Also glad that you can you use my answer to learn Ansible further, not only to get your issue sorted 😉

PS: I forgot to mention before; on this scenario we could also use the `combine()` plugin filter, It comes really handy when modifying data on existing dictionaries.

[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/combine\_filter.html](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/combine_filter.html)

See you around!

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [November 2, 2023, 5:41am UTC](https://forum.ansible.com/t/use-ansible-facts-to-convert-netplan-from-dhcp-to-static/1235/6 "2023-11-02T05:41:02Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
