Kunal Jha
Kunal Jha

Reputation: 136

How to read CSV file data in ansible-playbook using with_lines?

I have situation where in one csv file i have 2 columns like below

cat report.csv
Field1,Field2,Field3
name3,3,5
name4,5,6

now i want to use the lines which are in bold.

Each column will be an input to one of the ansible role.

it should go like

   roles:
     - { role: arti_master, mod_name: "{{ item.name}}" , version: "{{ item.version}}"
  with_lines:
    - "cat report.csv|cut -d, -f2"

Upvotes: 3

Views: 20999

Answers (4)

Rohit Salecha
Rohit Salecha

Reputation: 1033

Sharing my ansible code as well this is what worked for me https://stackoverflow.com/a/56910479/1679541

playbook.yaml

---
- name: Read Users
  gather_facts: True
  hosts: localhost

  tasks:
  - read_csv:
      path: users.csv
    register: userlist

  - debug: 
      msg: "{{ user.username }} and password is {{ user.password }}"
    loop: "{{ userlist.list }}"
    loop_control:
      loop_var: user

users.csv

username,password
user0,test123
user1,test123

Ansible Output

PLAY [Read Users] *************************************************

TASK [Gathering Facts] *********************************************************
ok: [127.0.0.1]

TASK [read_csv] ****************************************************************
ok: [127.0.0.1]

TASK [debug] *******************************************************************
ok: [127.0.0.1] => (item={u'username': u'user0', u'password': u'test123'}) => {
    "msg": "user0 and password is test123"
}
ok: [127.0.0.1] => (item={u'username': u'user1', u'password': u'test123'}) => {
    "msg": "user1 and password is test123"
}

PLAY RECAP *********************************************************************
127.0.0.1                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Upvotes: 0

Joel Zamboni
Joel Zamboni

Reputation: 345

Here is an example:

- name: "Sending email"
  hosts: localhost
  gather_facts: no
  tasks:
  - name: "Reading user information"
    read_csv:
      path: users.csv
    register: users
  - name: "Sending an e-mail using Gmail SMTP servers"
    mail:
      host: smtp.gmail.com
      port: 587
      username: <email>
      password: <pass>
      to: "{{ user.email }}"
      subject: Email Subjet
      body: |
        Hi {{ user.first_name }},

        How are you? 
    loop: "{{ users.list }}"
    loop_control:
      loop_var: user 

And the CSV:

first_name,last_name,email
Joel,Zamboni,[email protected]

The read_csv returns the data in two formats, as a dict or as a list and in this case I am 'looping' over the list to send emails.

Best,

Joel

Upvotes: 4

Aakarsh
Aakarsh

Reputation: 11

read_csv module was recently added to ansible, and is now available from ansible 2.8. After upgrading ansible, you can read line by line as follows:

  - name: read the csv file
    read_csv:
      path: "{{ report.csv }}"
      delimiter: ','
    register: report_csv

You can then access it as list by using report_csv.list and it'll hold values as a list of dictionaries:

[{'Field1': 'name3', 'Field2': 3, 'Field3': 5}, {'Field1': 'name4', 'Field2': 5, 'Field3': 6}]

Upvotes: 1

mdaniel
mdaniel

Reputation: 33203

I believe you have two (and a half) ways that I can think of:

  1. Do as you said and run the file through cut or python -c "import csv;..." or other "manual" processing, then capture the output in a variable

    Anything that looks like JSON when fed into a vars: or set_fact: will become a list or dict, so you'd just want the text to go into a tool looking like CSV and come out of the tool looking like JSON

  2. Use the lookup("csvfile") to actually read the file using an "approved" mechanism
    1. (this is the "half" part:) if the csv is on the remote machine, then use fetch: to pull it to your controlling machine, then run lookup("csvfile") on it

Upvotes: 2

Related Questions