Ansible Playbook to Delete OLD Log files - Windows | Devops Junction

Ansible for Windows has grown a lot from what it used to be, and the number of modules for windows is also increasing steadily.

So Ansible is the right choice going forward for Windows Server Automation tasks.  Of course, you need to use Powershell commands here and there. but collectively the task can be done with efficiency if you choose ansible.

This article and the other few articles yet to be published are going to be on the Windows and Ansible Combo. Stay connected to get updates.

Onward to the objective

In this article, we are going to share an Ansible playbook that finds the following tasks.

  • Traverse through the list of directories and find the list of old log files based on the Modified time (Age) and Regex Pattern.
  • Traverse through the collected list of files and remove them

This playbook would be helpful for sysadmins and DevOps engineers who are managing Windows Servers

ansible windows

Ansible Playbook to Find and delete old log files Windows

Here is the source code of the playbook.  We will see each task on this playbook in detail.

---
- name: House Keeping old log files
  hosts: win
  vars:
    directories: ['C:\inetpub\logs\LogFiles','C:\IBM\WebSphere\AppServer\profiles\AppSrv01\logs']
    filepattern: ['*.log']
    age: 3d
  tasks:
    - name: Find Log LogFiles
      tags: always
      win_find:
        paths: "{{directories}}"
        age: "{{age}}"
        age_stamp: mtime
        patterns: "{{filepattern}}"
        recurse: yes
      register: filestoremove

    - name: list of files to be removed
      tags: always
      vars:
        files: "{{ filestoremove.files | json_query('[].path') }}"
      debug: var=files
      when: filestoremove.matched > 0

    - name: remove the files found - this would work only when you call the – tags=delete
      tags: never,delete
      vars:
        files: "{{ filestoremove.files | json_query('[].path') }}"
      win_file:
        path: "{{item}}"
        state: absent
      with_items:
        - "{{files}}"
      when: filestoremove.matched > 0

Let us decode the key elements and tasks in our playbook

hosts we are running these tasks against a host group named win

vars we are defining necessary variables at the beginning of the playbook.

  • directories  List (or) An array of directories in Fully Qualified path within single quotes ( as Windows Paths sometimes contains Spaces)
  • filepattern  List (or) An array of patterns with Wildcard/RegEx like *.log *.out etc.
  • age A number of seconds/minutes/hours/days/weeks old files would only be considered. You can choose seconds, minutes, hours, days or weeks by specifying the first letter of an of those words (e.g., "2s", "10d", "1w").

Now we have declared the necessary variables and host group.

It is a time for putting them to the right use within our tasks. In our playbook, we have three tasks, we will see each of them in detail

Task1: Find the matching files with win_find module

In this task, we are using the Ansible windows module win_find an equivalent to the ansible linux find module

- name: Find Log LogFiles
  tags: always
  win_find: 
    paths: "{{directories}}"
    age: "{{age}}"
    age_stamp: mtime
    patterns: "{{filepattern}}"
    recurse: yes
  register: filestoremove

there is a special tag named always used in this task. It is used to tell ansible that this task can be executed all the time safely.

Like always we have one more special tag called never which helps us to run the task only when explicitly called for with --tags.  we have used both always and never in this playbook.

Read more about Ansible Special tags always and never

  • paths  List of directories as a list, we are passing the variable named directories declared earlier
  • age  Age of files to consider seconds/days/weeks. the value given earlier for the age variable would be passed here
  • patterns  One or more (PowerShell or regex) patterns to compare filenames with.
  • recurse to let windows find module to know that sub directories should be considered while looking for the files.
  • age_stamp  there are various methods to calculate the age of the files as follows
    • ctime based on the created time
    • mtime modified time
    • atime based on the last accessed time

in our case we chose mtime to find the files based on the modified time of the file. which is a default value for the age_stamp too.

we are saving the output of this task into a register variable named filestoremove

 

Task2:  Display the list of files found to purge/remove

The Second task in our playbook is a simple Debug to list the files found by the previous task.

we are simply displaying the filenames stored on the first task's register variable.

- name: list of files to be removed
  tags: always
  vars: 
    files: "{{ filestoremove.files | json_query('[].path') }}"
  debug: var=files
  when: filestoremove.matched > 0

we have a conditional element here and it would let the task be executed only when there are any matched files present on the register variable.

it is done with the help of when conditional parameter and a simple comparison statement.

You can learn more about conditional execution in ansible from this article.

when the value of filestoremove.matched is greater than 0 the task would be executed otherwise skipped.

we are using JSONQuery filter of ansible to list only the filenames from the entire output.

we have a dedicated article on Ansible JSONQuery with Examples you can refer

Task3:  A Task to remove the found or matched files - win_file module

This task is to delete the files that we have found on the first task.

As I have mentioned earlier, we have used a special tag named never which would make sure that there would not be any accident / unintended file deletion when the playbook is executed.

- name: remove the files found - this would work only when you call the – tags=delete
  tags: never,delete
  vars: 
    files: "{{ filestoremove.files | json_query('[].path') }}"
  win_file: 
    path: "{{item}}"
    state: absent
  with_items: 
    - "{{files}}"
  when: filestoremove.matched > 0

Since we have the third task as never and would only to work when explicitly invoked with --tags=delete

The Default behaviour of our playbook is to run the first two tasks only. thereby it would only find the list of files and display it NOT delete it.

So even if the playbook gets accidentally executed you are covered.

we are using the same json query we have used in the previous section to filter only the file names along with the path and save them to a variable named files

the files variables are being iterated using with_items loop and each entry in the files list would be removed using win_file module.

 

Conclusion

Hope this playbook helps you automate the Log management and keeping your windows server's disk space stable.

In this article, Besides our primary Objective, we have also covered a few interesting features of ansible you might want to read further to get a full understanding

I have summarized the list of items here

  • using special tags never and always
  • using json_query to select elements from the dictionary ( we can use selectattr function also for this with map)
  • looping through the dictionary with with_items
  • conditional execution of a task in ansible using when etc

Hope this helps.

If you are looking for any professional support long term / short term in DevOps / Cloud.

Please try Gritfy

Cheers
Sarav

Follow me on Linkedin My Profile
Follow DevopsJunction onFacebook orTwitter
For more practical videos and tutorials. Subscribe to our channel

Buy Me a Coffee at ko-fi.com

Signup for Exclusive "Subscriber-only" Content

Loading