Ansible no_log: Hide Sensitive Output in Playbook Logs (Guide)
By Luca Berton · Published 2024-01-01 · Category: installation
How to hide passwords and secrets in Ansible output with no_log. Prevent sensitive data from appearing in logs, debug output, callbacks.
The no_log: true directive prevents Ansible from displaying task output in logs and terminal. Use it to hide passwords, API tokens, database credentials, and any sensitive data that would otherwise appear in plain text.
Basic Usage
- name: Create user with password
ansible.builtin.user:
name: appuser
password: "{{ vault_user_password | password_hash('sha512') }}"
no_log: true
Without no_log:
changed: [web1] => {"changed": true, "password": "$6$rounds=656000$abc..."}
With no_log: true:
changed: [web1] => {"censored": "the output has been hidden due to the fact that 'no_log: true' was specified for this result"}
See also: Ansible Playbook Structure: Anatomy, Best Practices & Examples (2026)
Where to Use no_log
API Tokens and Keys
- name: Call API with token
ansible.builtin.uri:
url: https://api.example.com/deploy
method: POST
headers:
Authorization: "Bearer {{ vault_api_token }}"
body_format: json
body:
version: "{{ app_version }}"
no_log: true
Database Credentials
- name: Create database user
community.postgresql.postgresql_user:
name: appuser
password: "{{ vault_db_password }}"
db: myapp
priv: ALL
no_log: true
- name: Deploy database config
ansible.builtin.template:
src: database.yml.j2
dest: /opt/app/config/database.yml
mode: '0600'
no_log: true # Template contains DB password
Environment Variables with Secrets
- name: Run migration with secrets
ansible.builtin.command: /opt/app/bin/migrate
environment:
DATABASE_URL: "{{ vault_database_url }}"
SECRET_KEY: "{{ vault_secret_key }}"
API_KEY: "{{ vault_api_key }}"
no_log: true
SSH Keys and Certificates
- name: Deploy SSH private key
ansible.builtin.copy:
content: "{{ vault_ssh_private_key }}"
dest: /home/deploy/.ssh/id_ed25519
owner: deploy
mode: '0600'
no_log: true
no_log with Loops
- name: Create multiple users
ansible.builtin.user:
name: "{{ item.name }}"
password: "{{ item.password | password_hash('sha512') }}"
groups: "{{ item.groups }}"
loop: "{{ users }}"
no_log: true
# Hides ALL loop output, including usernames
# Better: Use loop_control to show names while hiding passwords
- name: Create multiple users
ansible.builtin.user:
name: "{{ item.name }}"
password: "{{ item.password | password_hash('sha512') }}"
groups: "{{ item.groups }}"
loop: "{{ users }}"
loop_control:
label: "{{ item.name }}" # Only show username in output
no_log: true
See also: Ansible Tags: Run Specific Tasks and Roles Selectively (Guide)
Conditional no_log
# Disable no_log in debug mode
- name: Create user
ansible.builtin.user:
name: appuser
password: "{{ vault_user_password | password_hash('sha512') }}"
no_log: "{{ not debug_mode | default(true) }}"
# Set debug_mode=true to see output during troubleshooting
# Normal run: output hidden
ansible-playbook site.yml
# Debug run: output visible
ansible-playbook site.yml -e debug_mode=true
Play-Level no_log
# Hide output for entire play
- hosts: databases
no_log: true
tasks:
- name: All tasks in this play are hidden
community.postgresql.postgresql_user:
name: "{{ item.name }}"
password: "{{ item.password }}"
loop: "{{ db_users }}"
See also: Ansible Variable Precedence: Complete Order of Priority (2026)
Best Practices
1. Use Vault for Secrets
# Store secrets in vault, reference with no_log
- name: Deploy secrets
ansible.builtin.template:
src: secrets.yml.j2
dest: /opt/app/secrets.yml
mode: '0600'
no_log: true
# Template references vault_* variables from encrypted group_vars
2. Use loop_control with no_log
# Don't hide everything — show useful context
- name: Deploy service configs
ansible.builtin.template:
src: "{{ item.template }}"
dest: "{{ item.dest }}"
loop: "{{ service_configs }}"
loop_control:
label: "{{ item.dest }}" # Show destination, hide template content
no_log: true
3. Separate Sensitive and Non-Sensitive Tasks
# Non-sensitive — full output
- name: Install packages
ansible.builtin.package:
name: "{{ packages }}"
state: present
# Sensitive — hidden output
- name: Configure credentials
ansible.builtin.template:
src: credentials.j2
dest: /etc/app/credentials.yml
mode: '0600'
no_log: true
# Non-sensitive — full output
- name: Start service
ansible.builtin.systemd:
name: myapp
state: started
4. Avoid no_log on debug Tasks
# BAD — can't see debug output
- name: Show status
ansible.builtin.debug:
var: service_status
no_log: true # Defeats the purpose!
# GOOD — only hide sensitive debug
- name: Show config (redacted)
ansible.builtin.debug:
msg: "DB host: {{ db_host }}, DB name: {{ db_name }}"
# Don't show password, so no need for no_log
Troubleshooting with no_log
When a no_log: true task fails, the error message is also hidden:
fatal: [web1]: FAILED! => {"censored": "the output has been hidden..."}
To debug:
# Method 1: Temporarily disable
ansible-playbook site.yml -e debug_mode=true
# Method 2: Use ANSIBLE_NO_LOG=false (overrides all no_log)
ANSIBLE_NO_LOG=false ansible-playbook site.yml
# Method 3: Add -vvvv (does NOT override no_log, but shows more context)
ansible-playbook site.yml -vvvv
ansible-lint Warning
ansible-lint flags tasks with passwords that lack no_log:
WARNING no-log-password: Tasks that set passwords should have no_log set.
Fix by adding no_log: true to any task that handles passwords.
FAQ
What does no_log do in Ansible?
no_log: true prevents Ansible from displaying task input and output in the terminal and log files. The task still runs normally, but its results are shown as "censored" instead of the actual data.
When should I use no_log?
Use it on any task that handles sensitive data: passwords, API tokens, SSH keys, database credentials, certificates, or any secrets. Also use it when templates or copy content contain embedded secrets.
Does no_log hide errors too?
Yes — when a no_log: true task fails, the error message is also hidden. Use ANSIBLE_NO_LOG=false or a conditional no_log: "{{ not debug_mode }}" to temporarily disable it for troubleshooting.
Can I disable no_log globally for debugging?
Yes — set the environment variable ANSIBLE_NO_LOG=false before running the playbook. This overrides all no_log: true directives. Only use this in secure environments.
Does no_log affect Ansible Tower/AWX logs?
Yes — no_log: true hides output in Tower/AWX job output as well. The data never reaches the Tower database, making it safe for audit-sensitive environments.
Conclusion
•no_log: true — Hide sensitive task output
• Use on: passwords, tokens, keys, credentials, secret templates
• loop_control: label — Show useful context while hiding secrets
• Conditional: no_log: "{{ not debug_mode }}" for troubleshooting
• ANSIBLE_NO_LOG=false — Emergency override for debugging
• Always combine with Ansible Vault for complete secret management
Related Articles
• Ansible Vault: Encrypt Secrets • Ansible debug Module: Print Variables • Ansible Playbook Structure & Best PracticesCategory: installation