Ansible slurp Module: Read Remote Files as Base64 (Complete Guide)
By Luca Berton · Published 2024-01-01 · Category: troubleshooting
Complete guide to Ansible slurp module (ansible.builtin.slurp). Read remote file contents as base64, decode with b64decode filter, parse JSON/YAML configs.
The ansible.builtin.slurp module reads a file from a remote host and returns its contents as base64-encoded data. Unlike fetch, it doesn't write to the local filesystem — the content stays in a variable for processing within your playbook. Perfect for reading configs, certificates, keys, and small files.
Basic Usage
- name: Read remote file
ansible.builtin.slurp:
src: /etc/hostname
register: hostname_file
- name: Show file contents
ansible.builtin.debug:
msg: "{{ hostname_file.content | b64decode }}"Output:
TASK [Show file contents] ****
ok: [web01] => {
"msg": "web01.example.com\n"
}See also: Ansible slurp Module: Read File Content from Remote Hosts (ansible.builtin.slurp)
How slurp Works
- Reads the file on the remote host
- Encodes contents as base64
- Returns data in the
contentfield of the registered variable - You decode with the
b64decodefilter
# The registered variable structure
hostname_file:
content: "d2ViMDEuZXhhbXBsZS5jb20K" # base64 encoded
encoding: "base64"
source: "/etc/hostname"Read and Parse Configuration Files
Parse JSON Config
- name: Read JSON config
ansible.builtin.slurp:
src: /etc/myapp/config.json
register: app_config_raw
- name: Parse JSON
ansible.builtin.set_fact:
app_config: "{{ app_config_raw.content | b64decode | from_json }}"
- name: Use config values
ansible.builtin.debug:
msg: "Database host: {{ app_config.database.host }}"Parse YAML Config
- name: Read YAML config
ansible.builtin.slurp:
src: /etc/myapp/settings.yml
register: settings_raw
- name: Parse YAML
ansible.builtin.set_fact:
settings: "{{ settings_raw.content | b64decode | from_yaml }}"
- name: Show setting
ansible.builtin.debug:
msg: "Log level: {{ settings.logging.level }}"Read INI/Properties Files
- name: Read properties file
ansible.builtin.slurp:
src: /opt/app/application.properties
register: props_raw
- name: Extract specific property
ansible.builtin.set_fact:
db_url: "{{ (props_raw.content | b64decode).split('\n')
| select('match', '^database.url=')
| first
| regex_replace('^database.url=', '') }}"See also: Ansible slurp Module: Read Remote File Content into Variable (Guide)
Read Certificates and Keys
- name: Read SSL certificate
ansible.builtin.slurp:
src: /etc/ssl/certs/myapp.crt
register: ssl_cert
- name: Check certificate expiry
community.crypto.x509_certificate_info:
content: "{{ ssl_cert.content | b64decode }}"
register: cert_info
- name: Warn if certificate expires soon
ansible.builtin.debug:
msg: "⚠️ Certificate expires {{ cert_info.not_after }}!"
when: cert_info.not_after < (ansible_date_time.iso8601 | to_datetime('%Y-%m-%dT%H:%M:%SZ')).strftime('%Y%m%d%H%M%SZ')Compare Files Across Hosts
- name: Read config from all hosts
ansible.builtin.slurp:
src: /etc/myapp/config.conf
register: configs
- name: Check config consistency
ansible.builtin.assert:
that:
- configs.content == hostvars[groups['webservers'][0]].configs.content
fail_msg: "Config on {{ inventory_hostname }} differs from primary!"
success_msg: "Config matches primary"See also: Ansible Set File Permissions 755: chmod with file Module Guide
Read /etc/passwd for User Audit
- name: Audit local users
ansible.builtin.slurp:
src: /etc/passwd
register: passwd_file
- name: Find users with UID 0 (root-level)
ansible.builtin.set_fact:
root_users: "{{ (passwd_file.content | b64decode).split('\n')
| select('match', '.*:.*:0:')
| list }}"
- name: Alert on extra root users
ansible.builtin.debug:
msg: "⚠️ Multiple UID 0 users: {{ root_users }}"
when: root_users | length > 1Read and Template
- name: Read current config
ansible.builtin.slurp:
src: /etc/nginx/nginx.conf
register: current_nginx
- name: Render new config
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
when: (current_nginx.content | b64decode) != lookup('template', 'nginx.conf.j2')
notify: reload nginxError Handling
- name: Read file (may not exist)
ansible.builtin.slurp:
src: /etc/myapp/optional.conf
register: optional_config
ignore_errors: true
- name: Use default if file missing
ansible.builtin.set_fact:
config_value: "{{ (optional_config.content | b64decode) if optional_config is success else 'default_value' }}"slurp vs fetch vs command
| Feature | slurp | fetch | command (cat) |
|---|---|---|---|
| Data stays in memory | ✅ | ❌ (writes to disk) | ✅ |
| Binary-safe | ✅ (base64) | ✅ | ❌ |
| Idempotent | ✅ | ✅ | ❌ (always changed) |
| Large files | ❌ (memory limit) | ✅ | ❌ |
| Parse in playbook | ✅ | ❌ (need extra task) | ✅ |
FAQ
What is the maximum file size for slurp?
There's no hard limit, but slurp loads the entire file into memory (base64 encoded, which is ~33% larger). For files over a few MB, use fetch instead. Practical limit is around 10-20 MB depending on available memory.
Can slurp read binary files?
Yes. Since slurp encodes everything as base64, it handles binary files correctly. Use b64decode carefully — if you need the raw bytes, write them to a file with copy module using content: "{{ data.content | b64decode }}".
Why does slurp return base64 instead of plain text?
Base64 encoding ensures safe transport of any file content (including binary data, special characters, and null bytes) through Ansible's JSON-based communication layer.
How do I read a file only if it exists?
Use stat first to check existence, then conditionally slurp:
- name: Check if file exists
ansible.builtin.stat:
path: /etc/myapp/config.conf
register: config_stat
- name: Read if exists
ansible.builtin.slurp:
src: /etc/myapp/config.conf
register: config_data
when: config_stat.stat.existsConclusion
The slurp module is essential for reading remote file contents into playbook variables. Pair it with b64decode, from_json, and from_yaml filters to parse configuration files, audit system files, compare configs across hosts, and make decisions based on remote file contents — all without writing temporary files.
Related Articles
Category: troubleshooting