Search code examples
ansibleansible-template

Create interface configuration files using Ansible


I have an Excel spreadsheet that I've saved as a CSV file (comma deliminated) containing the IP addresses of multiple interfaces for a list of servers. There's been an interface configured on these servers (initially) so I have connectivity. I'd like to go through this file row-by-row and grab the necessary values to build the ifcfg file locally, copy to the server and then restart the network.

This is not the actual file; rather, a sample outlining the idea that there's a location with multiple IP addresses provided.

New Orleans, 192.168.10.42, 13, 192.168.3.10
Atlanta, 192.168.31.100, 18, 192.168.10.10
Detroit, 172.16.31.8, 43, 172.16.10.27

The goal is to parse this file and create the network interface files as follows

ifcfg-eth0

TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none
NM_CONTROLLED=no
IPADDR=192.168.10

ifcfg-ens3

TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none
NM_CONTROLLED=no
IPADDR=192.168.3.10

This looks to get me partway there

- debug:
  loop: "{{ lookup('file', './file.one').splitlines() }}"
  register: val

And returns

ok: [localhost] => (item=New Orleans, 192.168.10.42, 13, 192.168.3.10) => {
    "msg": "Hello world!"
}
ok: [localhost] => (item=Atlanta, 192.168.31.100, 18, 192.168.10.10) => {
    "msg": "Hello world!"
}
ok: [localhost] => (item=Detroit, 172.16.31.8, 43, 172.16.10.27) => {
    "msg": "Hello world!"
}

I did find a snippet on StackOverflow using the_dict I used but everything is returned as a list and not a scalar :(

  tasks:
  - debug: var=the_dict
    vars:
      the_dict: >-
        {%- set row = lookup("file", "~/Documents/Book1.csv").split("\n") | list -%}
        {%- for i in row -%}
        {%- set v  = i.split(",") -%}
        {%- set A_Location = v.0 -%}
        {%- set B_Interface = v.1 -%}
        ...
        ...
        ...

Solution

  • to read csv with ansible, read module CSV

    an example to use template the template file conf.j2 (to put in templates directory)

    {% for record in  records.list %}
    ifcfg-eth0
    
    TYPE=Ethernet
    PROXY_METHOD=none
    BROWSER_ONLY=no
    BOOTPROTO=none
    NM_CONTROLLED=no
    IPADDR={{ record.ip1 }}
    
    ifcfg-ens3
    
    TYPE=Ethernet
    PROXY_METHOD=none
    BROWSER_ONLY=no
    BOOTPROTO=none
    NM_CONTROLLED=no
    IPADDR=1{{ record.ip2 }}
    
    {% endfor %} 
    
    
    
    
    - name: playbook2.0
      hosts: localhost
      gather_facts: False
      tasks:
        - name: Read CSV file and return a list
          community.general.read_csv:
            path: file.csv
            fieldnames: location,ip1,data,ip2
            delimiter: ','
          register: records
          delegate_to: localhost
    
        - name: generate fileconf.txt from conf.j2
          template:
            src: conf.j2
            dest: fileconf.txt 
    

    you have the new file conf generated in the file fileconf.txt

    you could adapt the file.j2 as you want with jinja2 syntax