Ansible - slurp module (read file)

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.

- name: store the stats of /tmp/foo.txt in the 'foo' variable
  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.

- name: read /tmp/foo.txt
  slurp:
    src: /tmp/foo.txt
  register: out
  when:
    - foo.stat.exists == true
    - foo.stat.readable == true

 

Using the debug module can be used to to print the "out" variable. Notice the double curley braces {{ ... }}. Jinja2 uses double curley braces for variables.

- name: output the content of the 'out' variable
  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.

- 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.

- set_fact:
    content: "{{ out['content'] | b64decode }}"

 

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

- 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.

- set_fact:
    content: "{{ out['content'] | b64decode }}"

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

 

The debug module can be used to print the output.

- debug:
    var: lines

 

Which should return the following.

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

 

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

- set_fact:
    content: "{{ out['content'] | b64decode }}"

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

 

The debug module can be used to print the output.

- debug:
    var: line_one

 

Which should now return the following.

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

 


Determine if file does or does not contain a certain string

The following can be used to determine if foo.txt contains the string "Hello World".

- name: read foo.txt
  slurp:
    src: foo.txt
  register: out

- set_fact:
    content: "{{ out['content'] | b64decode }}"

- name: foo.txt contains Hello World
  debug:
    msg: foo.txt contains Hello World
  when: content is search 'Hello World'

- name: foo.txt does not contain Hello World
  debug:
    msg: foo.txt does not contain Hello World
  when: content is not search 'Hello World'

 


regex_search

regex_search or regex_findall can be used to only return lines in the file that contain a certain string.

- debug:
    msg: "{{ out['content'] | b64decode | regex_findall('.*Line 2.*') }}"

 

Which should now return the following.

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


Add a Comment




We will never share your name or email with anyone. Enter your email if you would like to be notified when we respond to your comment.





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




Comments

Web design by yours truely - me, myself, and I   |   jeremy.canfield@freekb.net   |