When working with Ansible's file
module, you might encounter a peculiar situation where dead symlinks aren't being removed despite playbook execution showing "ok" status. This typically happens when there's either a syntax issue in your playbook or when Ansible's path resolution behaves differently than expected.
The problem in your playbook stems from incorrect parameter formatting. In your remove task, you've included path=
as part of the string value, which Ansible interprets literally rather than as a parameter. Here's how it should be properly written:
- name: Remove symlink correctly
file:
path: /usr/local/bin/dead_symlink
state: absent
Here's a complete playbook example that checks for the symlink's existence and removes it properly:
- hosts: localhost
tasks:
- name: Check symlink status
stat:
path: /usr/local/bin/dead_symlink
register: symlink_status
- name: Debug symlink info
debug:
var: symlink_status.stat
- name: Remove dead symlink
file:
path: /usr/local/bin/dead_symlink
state: absent
when: symlink_status.stat.exists
For more robust symlink management, consider these additional scenarios:
# Force removal regardless of target existence
- name: Force symlink removal
file:
path: "{{ item }}"
state: absent
loop:
- /usr/local/bin/dead_symlink
- /another/path/broken_link
# Recursive directory cleaning
- name: Clean up all dead symlinks in directory
find:
paths: /usr/local/bin
file_type: link
follow: no
register: symlinks_to_check
- name: Remove dead symlinks found
file:
path: "{{ item.path }}"
state: absent
loop: "{{ symlinks_to_check.files }}"
when: not item.lnk_target_stat.exists
Ansible's file
module with state: absent
removes both valid and dead symlinks. The key is proper path specification without the path=
prefix in the value. The module specifically handles symbolic links differently from regular files, which explains why the original syntax failed.
When working with Ansible's file
module to manage symbolic links, you might encounter a frustrating scenario where a broken symlink refuses to disappear despite using state: absent
. Here's what's happening under the hood:
# This correctly detects the symlink exists
- stat:
path: /usr/local/bin/dead_symlink
register: dead_symlink_bin
- debug:
var: dead_symlink_bin.stat.exists
The issue lies in how Ansible handles path specifications. Your current playbook has a syntax error in the path parameter. The correct format should be:
- name: Remove symlink PROPERLY
file:
path: /usr/local/bin/dead_symlink # Remove "path=" prefix
state: absent
Here's a robust approach that handles both detection and removal:
- name: Check symlink status
stat:
path: /usr/local/bin/dead_symlink
register: symlink_status
- name: Remove broken symlink if exists
file:
path: "{{ symlink_status.stat.lnk_target if symlink_status.stat.islnk else '/usr/local/bin/dead_symlink' }}"
state: absent
when: symlink_status.stat.islnk or symlink_status.stat.exists
If the symlink still persists, try these additional steps:
- name: Force removal (be cautious!)
command: rm -f /usr/local/bin/dead_symlink
args:
removes: /usr/local/bin/dead_symlink
when: symlink_status.stat.exists
Remember that when dealing with system directories like /usr/local/bin
, you might need elevated privileges. Always include become: yes
when appropriate.