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 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.
- directoriesList (or) An array of directories in Fully Qualified path within single quotes ( as Windows Paths sometimes contains Spaces)
- filepatternList (or) An array of patterns with Wildcard/RegEx like- *.log *.outetc.
- ageA 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
- pathsList of directories as a list, we are passing the variable named directories declared earlier
- ageAge of files to consider seconds/days/weeks. the value given earlier for the age variable would be passed here
- patternsOne or more (PowerShell or regex) patterns to compare filenames with.
- recurseto let windows find module to know that sub directories should be considered while looking for the files.
- age_stampthere are various methods to calculate the age of the files as follows- ctimebased on the created time
- mtimemodified time
- atimebased 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 neverandalways
- using json_queryto select elements from the dictionary ( we can useselectattrfunction also for this with map)
- looping through the dictionary with with_items
- conditional execution of a task in ansible using whenetc
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
 
Signup for Exclusive "Subscriber-only" Content






