Bootstrap FreeKB - Ansible - Read file using the slurp module
Ansible - Read file using the slurp module

Updated:   |  Ansible articles

If you are not familiar with modules, check out Ansible - Getting Started with Modules.

The slurp module can be used the read the content of a file on a managed node (e.g. target system).

However, when you want to read a file on the control node, the more common approach is to use the lookup plugin.

Before using the slurp module, you may want to use the stat module to determine if the file exists and is readable. In this example, the stats of foo.txt are stored in the 'foo' variable. This will allow you to use when statements to only slurp the file when the file is readable.

---
- hosts: all
  tasks:
  - name: store the stats of /tmp/foo.txt in the 'foo' variable
    ansible.builtin.stat:
      path: /tmp/foo.txt
    register: foo
...

 

Let's say foo.txt contains a few lines of text, like this.

Line 1
Line 2
Line 3

 

In this example, the slurp module is used to get the content of foo.txt, and the register parameter stores the content in the "out" variable. debug can be used to to print the "out" variable.

---
- hosts: all
  tasks:
  - name: read /tmp/foo.txt
    ansible.builtin.slurp:
      src: /tmp/foo.txt
    register: out
    when:
      - foo.stat.exists == true
      - foo.stat.readable == true

  - ansible.builtin.debug:
      var: out
...

 

Which will display JSON that looks something like this. Notice in this example that "content" is "bmV3IGxpbmUK" and encoding is "base64".

TASK [output the content of the 'out' variable]
ok: [server1.example.com] => {
    "msg": {
        "changed": false,
        "content": "bmV3IGxpbmUK",
        "encoding": "base64",
        "failed": false",
        "source": "/tmp/foo.txt"
    }
}

 

In this scenario, if you want to display the content of the file, the b64decode filter can be used. Refer to Ansible - Getting Started parsing JSON and Ansible - Looping through JSON array if you want to access specific values in the JSON.

- ansible.builtin.debug:
    msg: "{{ out.content | b64decode }}"

 

Which should now return the following.

TASK [debug]
ok: [server1.example.com] => {
    "msg": "Line 1\nLine 2\nLine 3"
}

 

Or, you could use the set_fact module to create a new variable that contains the content of the file.

- ansible.builtin.set_fact:
    content: "{{ out.content | b64decode }}"

 

If you want to display the content of the file, you would do something like this.

- ansible.builtin.debug:
    var: content

 

Which should now return the following.

TASK [debug]
ok: [server1.example.com] => {
    "msg": "Line 1\nLine 2\nLine 3"
}

 


Split new lines (\n)

split can be used to split the new lines.

- ansible.builtin.set_fact:
    content: "{{ out.content | b64decode }}"

- ansible.builtin.set_fact:
    lines: "{{ content.split('\n') }}"

 

The debug module can be used to print the output.

- ansible.builtin.debug:
    var: lines

 

Which should return the following.

TASK [debug]
ok: [server1.example.com] => {
    "lines": [
        "Line 1",
        "Line 2",
        "Line 3"
    ]
}

 

An index number, such as [0], can be used to only return a specific line.

- ansible.builtin.set_fact:
    content: "{{ out.content | b64decode }}"

- ansible.builtin.set_fact:
    line_one: "{{ out.split('\n')[0] }}"

 

The debug module can be used to print the output.

- ansible.builtin.debug:
    var: line_one

 

Which should now return the following.

TASK [debug]
ok: [server1.example.com] => {
    "msg": "Line 1"
}

 

with_items can be used to loop through each line.

- ansible.builtin.debug:
    msg: "{{ item }}"
  with_items: "{{ content.split('\n') }}"

 

Which should return the following.

ok: [localhost] => (item=Line 1) => {
    "msg": "Line 1"
}
ok: [localhost] => (item=Line 2) => {
    "msg": "Line 2"
}
ok: [localhost] => (item=Line 3) => {
    "msg": "Line 3"
}

 


Match lines in file

Let's say foo.txt contains the following.

Line 1
Line 2
Some Other Line

 

Here is how you could append each line in foo.txt that begins with "Line" to the list named "my_list".

---
- hosts: localhost
  gather_facts: false
  vars:
    test: []
  tasks:
  - ansible.builtin.slurp:
      src: /tmp/foo.txt
    register: out

  - ansible.builtin.set_fact:
      content: "{{ out.content | b64decode }}"

  - ansible.builtin.set_fact:
      my_list: "{{ my_list | default([]) + [item] }}"
    with_items: "{{ content.split('\n') }}"
    when: item is regex '^Line'

  - ansible.builtin.debug:
      var: my_list
...

 

Which should return the following.

ok: [localhost] => {
    "my_list": [
        "Line 1", 
        "Line 2"
    ]
}

 




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


Please enter a41462 in the box below so that we can be sure you are a human.