A Practical Guide to Automating Daily Linux Tasks with Ansible
You know that feeling when you spend the first half of your day manually updating a dozen servers, only to realize you could have been sipping coffee instead? In 2024 the pressure to keep services up, secure, and fast is higher than ever, and the only realistic way to stay sane is to let the computer do the boring work. That’s why I’m pulling out my favorite tool – Ansible – and showing you how to turn everyday chores into a few lines of YAML.
Why Automation Matters Today
Most sysadmins wear many hats: you’re a troubleshooter, a security guard, a capacity planner, and sometimes even a coffee maker. When you add “manual patching” to that list, you’re setting yourself up for errors and burnout. Automation gives you three big wins:
- Consistency – The same command runs the same way on every host.
- Speed – What used to take an hour can be done in minutes.
- Traceability – Every change is recorded in a playbook, so you can audit it later.
Ansible fits right into that picture because it works over SSH, needs no extra agents, and reads like plain English. If you’ve never written a playbook, don’t worry – I’ll walk you through three common daily tasks and give you ready‑to‑run examples.
Getting Started: The Minimal Setup
Before we dive into playbooks, make sure you have the basics:
- A control machine (your laptop or a bastion host) with Ansible installed. On most Linux distros you can get it with
sudo apt-get install ansibleorsudo yum install ansible. - Password‑less SSH access to the target servers. A quick
ssh-copy-id user@hostwill set that up. - An inventory file that lists the hosts you want to manage. Keep it simple:
[webservers]
web01.example.com
web02.example.com
[dbservers]
db01.example.com
Save that as hosts.ini in the same folder as your playbooks.
Task 1 – Keep Packages Fresh
The Problem
Every day you run apt update && apt upgrade -y or the equivalent yum command on dozens of machines. Doing it by hand is a waste of time and you risk missing a host.
The Playbook
Create a file called update.yml:
---
- name: Update all packages on Linux hosts
hosts: all
become: true # run as root
tasks:
- name: Update apt cache (Debian/Ubuntu)
apt:
update_cache: yes
when: ansible_os_family == "Debian"
- name: Upgrade all packages (Debian/Ubuntu)
apt:
upgrade: dist
when: ansible_os_family == "Debian"
- name: Update yum cache (RHEL/CentOS)
yum:
update_cache: yes
when: ansible_os_family == "RedHat"
- name: Upgrade all packages (RHEL/CentOS)
yum:
name: "*"
state: latest
when: ansible_os_family == "RedHat"
Run it with:
ansible-playbook -i hosts.ini update.yml
Why This Works
Ansible automatically gathers facts about each host, including the OS family. The when statements let the same playbook handle both Debian‑based and RedHat‑based systems without duplication. The whole run finishes in a few minutes, and you get a clean report of which hosts succeeded or failed.
Task 2 – Rotate Logs and Clean Disk Space
The Problem
Log files grow unchecked, filling up /var/log and eventually causing services to crash. You probably have a cron job that runs logrotate, but you still need to prune old archives and check disk usage.
The Playbook
Save this as log_cleanup.yml:
---
- name: Rotate logs and clean old files
hosts: all
become: true
vars:
log_dir: /var/log
keep_days: 7
tasks:
- name: Run logrotate
command: logrotate -f /etc/logrotate.conf
args:
warn: false
- name: Find and delete old compressed logs
find:
paths: "{{ log_dir }}"
patterns: "*.gz"
age: "{{ keep_days }}d"
recurse: yes
register: old_logs
- name: Remove old logs
file:
path: "{{ item.path }}"
state: absent
loop: "{{ old_logs.files }}"
when: old_logs.matched > 0
- name: Report free space
command: df -h "{{ log_dir }}"
register: df_output
- name: Show free space
debug:
msg: "{{ df_output.stdout_lines }}"
Run it with:
ansible-playbook -i hosts.ini log_cleanup.yml
Why This Works
The find module lets you locate files older than a certain number of days, and the file module deletes them safely. The final debug step prints the disk usage so you can verify that you actually freed space. All of this replaces a handful of crontab lines with a single, auditable playbook.
Task 3 – Deploy a Simple Monitoring Agent
The Problem
You need a lightweight agent (like node_exporter) on every server to feed metrics to your Prometheus stack. Installing it manually on each host is tedious and error‑prone.
The Playbook
Create install_node_exporter.yml:
---
- name: Install node_exporter on Linux hosts
hosts: all
become: true
vars:
exporter_version: "1.6.1"
download_url: "https://github.com/prometheus/node_exporter/releases/download/v{{ exporter_version }}/node_exporter-{{ exporter_version }}.linux-amd64.tar.gz"
install_dir: /opt/node_exporter
tasks:
- name: Ensure install directory exists
file:
path: "{{ install_dir }}"
state: directory
mode: "0755"
- name: Download node_exporter archive
get_url:
url: "{{ download_url }}"
dest: "/tmp/node_exporter.tar.gz"
mode: "0644"
- name: Extract archive
unarchive:
src: "/tmp/node_exporter.tar.gz"
dest: "{{ install_dir }}"
remote_src: yes
creates: "{{ install_dir }}/node_exporter"
- name: Create systemd service file
copy:
dest: /etc/systemd/system/node_exporter.service
content: |
[Unit]
Description=Prometheus Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
ExecStart={{ install_dir }}/node_exporter-{{ exporter_version }}.linux-amd64/node_exporter
Restart=always
[Install]
WantedBy=multi-user.target
mode: "0644"
- name: Reload systemd and start service
systemd:
daemon_reload: yes
name: node_exporter
state: started
enabled: yes
Run it:
ansible-playbook -i hosts.ini install_node_exporter.yml
Why This Works
The playbook does everything: creates a folder, pulls the binary, unpacks it, writes a systemd unit, and starts the service. If you ever need to upgrade, just bump exporter_version and re‑run – Ansible will handle the rest.
Tips for Busy SysAdmins
- Keep playbooks in version control. A Git repo gives you history, rollbacks, and easy sharing with teammates.
- Use tags. Run
ansible-playbook --tags update update.ymlif you only want part of a larger playbook. - Test on a single host first. Add
-l web01.example.comto limit the run; once you’re happy, expand to the whole group. - Schedule with cron or systemd timers. A one‑line cron entry like
0 2 * * * /usr/bin/ansible-playbook -i /path/hosts.ini /path/update.ymlwill keep your fleet fresh every night.
Wrap‑Up
Automation isn’t a magic wand, but with a few well‑written Ansible playbooks you can shave hours off your weekly routine. The three examples above cover the most common daily chores – patching, log cleanup, and agent deployment – and they’re easy to adapt for your own environment. Remember, the goal is to let the computer do the repetitive work so you can focus on designing better systems, learning new tools, or finally taking that lunch break you keep postponing.
- → How to Choose the Right Industrial Indicator Light for Hazardous Environments @indicatorinsight
- → Build a Low‑Cost Autonomous Delivery Robot for Your Home in 7 Simple Steps @robofrontier
- → A Step-by‑by‑Step Guide to Selecting the Right Linear Brake for High‑Speed Automation @linearbrakehub
- → Designing a Fail‑Safe Brake System for Automated Production Lines: Best Practices and Safety Checklist @industrialbrakes
- → Boost Your Development Workflow with Machine-Learning-Powered Task Automation @aidevcompanion