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 thecontent field of the registered variable
You decode with the b64decode filter
# 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 > 1
Read 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 nginx
Error 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) | ✅ |
Use slurp when: You need file contents in a variable for processing. Use fetch when: You need the actual file on the controller. Use command/cat when: You need stdout processing or the file is too large.
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.exists
Conclusion
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
• Ansible fetch Module Guide • Ansible file Module Guide • Ansible stat Module • Ansible set_fact GuideCategory: troubleshooting