1
votes

Please help me in writing ansible playbook to read name servers (DNS) from /etc/resolv.conf file from multiple servers and write those name servers to a file.

I tried to get the contents into variable called contents as below:

- name: check resolv.conf exists
  stat:
    path: /etc/resolv.conf
  register: resolv_conf
- name: check nameservers list in resolv.conf
  vars:
     contents: "{{ lookup('file', '/etc/resolv.conf') }}"
  when: resolv_conf.stat.exists == True

Then not sure how to proceed further.

2

2 Answers

1
votes

You could use a regex, with the filter regex_findall in order to achieve this, especially considering that you might have more than one DNS server defined there.

Mind that this will give you a list.

Given the playbook:

- hosts: localhost
  gather_facts: no

  tasks:
    - name: check resolv.conf exists
      stat:
        path: /etc/resolv.conf
      register: resolv_conf
    - name: check nameservers list in resolv.conf
      debug:
        msg: "{{ contents }}"
      vars:
        contents: "{{ lookup('file', '/etc/resolv.conf') | regex_findall('\\s*nameserver\\s*(.*)') }}"
      when: resolv_conf.stat.exists == True

It gives, on an Alpine container, the recap:

PLAY [localhost] ***************************************************************

TASK [check resolv.conf exists] ************************************************
ok: [localhost]

TASK [check nameservers list in resolv.conf] ***********************************
ok: [localhost] => {
    "msg": [
        "192.168.65.1"
    ]
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
0
votes

I am not sure if it's exactly what you want, but you could write the contents into a file using the lineinfile than replace everything except the nameservers from there, using the replace module. Like this:

          - name: Check if resolv exists
            stat:
                    path: /etc/resolv.conf
            register: resolv_conf

          - set_fact:
                    content: "{{ lookup('file', '/etc/resolv.conf') }}"
            when: resolv_conf.stat.exists


          - name: Write them into a file
            lineinfile:
                    line: "{{ content }}"
                    create: yes
                    state: present
                    path: /tmp/resolv_conf_nameservers

          - name: Remove everything but nameservers
            replace:
                    path: /tmp/resolv_conf_nameservers
                    regexp:  "^(?!nameserver).*$"
                    replace: ""

~
Please note that you should use set_fact to load contents into a variable.

If you want the file containing the nameservers to be placed in your own machine/localhost, use delegate_to in the last two tasks:

          - name: Check if resolv exists
            stat:
                    path: /etc/resolv.conf
            register: resolv_conf

          - set_fact:
                    content: "{{ lookup('file', '/etc/resolv.conf') }}"
            when: resolv_conf.stat.exists


          - name: Write them into a file
            lineinfile:
                    line: "{{ content }}"
                    create: yes
                    state: present
                    path: /tmp/resolv_conf_nameservers
            delegate_to: localhost

          - name: Remove everything but nameservers
            replace:
                    path: /tmp/resolv_conf_nameservers
                    regexp:  "^(?!nameserver).*$"
                    replace: ""
            delegate_to: localhost