Introduction
In a Linux environment, maintaining an up-to-date server inventory is an important part of system administration. Manually collecting information such as hostname, IP address, operating system, kernel version, memory, CPU, DNS configuration, and service status can be time-consuming, especially when managing multiple servers.
In my On-Premises DevOps Infrastructure Project, I created Bash scripts to automate Linux server inventory collection from a central Ansible server.
The solution supports both RHEL and Ubuntu servers and generates a CSV report that can be emailed to the administrator.
Infrastructure
The inventory collection is executed from the Ubuntu-based Ansible server ans01.
RHEL Servers
lamp01
zap01
pup01
web01
db01
jen01
son01
Ubuntu Servers
ans01
kub01
kub02
kub03
tomd01
tomp01
gra01
dock01
The central server connects to each target server using SSH and executes the appropriate collection script with sudo.
Recommended Script Names
I recommend using names that clearly distinguish data collection from inventory processing.
RHEL
rhel_inventory_collect.sh
rhel_inventory.sh
rhel_inventory_collect.sh— runs on each RHEL server and collects system information.rhel_inventory.sh— runs from the Ansible server, processes the RHEL server list, collects the data, creates the CSV, and sends the report.
Ubuntu
ubuntu_inventory_collect.sh
ubuntu_inventory.sh
ubuntu_inventory_collect.sh— runs on each Ubuntu server and collects system information.ubuntu_inventory.sh— runs from the Ansible server and creates the Ubuntu inventory report.
This naming convention makes the purpose of each script immediately clear.
1. RHEL Inventory Collection
The RHEL collection script gathers:
Hostname
IP address
DNS servers
RHEL version
Kernel version
Chrony status
Postfix status
Total memory
Swap
CPU count
System manufacturer
The script intentionally does not collect unnecessary information such as SELinux, Firewalld, NTP status, NFS/CIFS mounts, disk details, or partition details.
RHEL Collection Script
Save the script as:
rhel_inventory_collect.sh
#!/bin/bash
# Purpose: Collect basic RHEL system details
# Version: 1.0
# Author: Vallabh Darole
> /tmp/server_check_list
RHOSTNAME=$(hostname)
IPDETAILS=$(hostname -I | xargs)
DNSSERVERS=$(grep '^nameserver' /etc/resolv.conf | awk '{print $2}' | xargs)
OS=$(cat /etc/redhat-release)
KERNELV=$(uname -r)
if systemctl is-active --quiet chronyd; then
CHRONYD="CHRONYD OK"
else
CHRONYD="CHRONYD KO"
fi
if systemctl is-active --quiet postfix; then
MAIL="MAIL OK"
else
MAIL="MAIL KO"
fi
MEMORY=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
SWAP=$(awk '/SwapTotal/ {print $2}' /proc/meminfo)
CPU=$(grep -c '^processor' /proc/cpuinfo)
MACHINE=$(dmidecode -s system-manufacturer 2>/dev/null | xargs)
echo "$RHOSTNAME,$IPDETAILS,$DNSSERVERS,$OS,$KERNELV,$CHRONYD,$MAIL,$MEMORY,$SWAP,$CPU,$MACHINE" \
>> /tmp/server_check_list
2. RHEL Server List
Create:
rhel_list
with:
lamp01
zap01
pup01
web01
db01
jen01
son01
3. RHEL Inventory Script
Save the main script as:
rhel_inventory.sh
The script:
Reads the RHEL server list.
Removes any previous temporary collection file.
Copies the collection script to the remote server.
Executes it using
sudo.Retrieves the collected information.
Appends the information to a CSV file.
Removes temporary files from the remote server.
Creates an email message.
Sends the inventory report as an attachment.
#!/bin/bash
# Purpose: Collect RHEL server inventory
# Version: 1.0
# Author: Vallabh Darole
echo "Enter your email ID:"
read -r EMAIL
OUTPUT="/tmp/server_check_list.csv"
MESSAGE="/tmp/MESSAGE"
HOSTLIST="/home/ansible/script/rhel_list"
> "$OUTPUT"
echo "HOSTNAME,IPDETAILS,DNSSERVERS,OS,KERNELV,CHRONYD,MAIL,MEMORY(KB),SWAP(KB),CPU,MACHINE" \
>> "$OUTPUT"
while IFS= read -r i
do
[ -z "$i" ] && continue
echo "======================================"
echo "Processing $i..."
echo "======================================"
timeout 10 ssh -n "$i" \
'sudo rm -f /tmp/server_check_list'
scp -q rhel_inventory_collect.sh \
"$i:/tmp/rhel_inventory_collect.sh"
if timeout 10 ssh -n "$i" \
'sudo bash /tmp/rhel_inventory_collect.sh'
then
echo "Collection successful: $i"
if timeout 10 ssh -n "$i" \
'sudo cat /tmp/server_check_list' >> "$OUTPUT"
then
echo "Data collected: $i"
else
echo "ERROR: Unable to collect data from $i"
fi
else
echo "ERROR: Collection failed on $i"
fi
timeout 10 ssh -n "$i" \
'sudo rm -f /tmp/server_check_list /tmp/rhel_inventory_collect.sh'
done < "$HOSTLIST"
DATE=$(date)
{
echo "Please find the RHEL server inventory created on:"
echo "$DATE"
echo
echo "Servers checked:"
cat "$HOSTLIST"
} > "$MESSAGE"
mutt -s "RHEL Server Inventory - $DATE" \
-a "$OUTPUT" -- "$EMAIL" < "$MESSAGE"
echo "RHEL inventory process completed."
4. Ubuntu Inventory Collection
The same approach is used for Ubuntu servers.
The Ubuntu collection script gathers:
Hostname
IP address
DNS servers
Ubuntu version
Kernel version
Time synchronization status
Postfix status
Memory
Swap
CPU
System manufacturer
The script also checks different time synchronization services because Ubuntu systems may use chrony, chronyd, or systemd-timesyncd.
Save the script as:
ubuntu_inventory_collect.sh
#!/bin/bash
# Purpose: Collect basic Ubuntu system details
# Version: 1.0
# Author: Vallabh Darole
> /tmp/server_check_list
RHOSTNAME=$(hostname)
IPDETAILS=$(hostname -I | xargs)
DNSSERVERS=$(grep '^nameserver' /etc/resolv.conf | awk '{print $2}' | xargs)
OS=$(grep PRETTY_NAME /etc/os-release | cut -d '"' -f 2)
KERNELV=$(uname -r)
if systemctl is-active --quiet chrony; then
CHRONYD="CHRONY OK"
elif systemctl is-active --quiet chronyd; then
CHRONYD="CHRONYD OK"
elif systemctl is-active --quiet systemd-timesyncd; then
CHRONYD="TIMESYNC OK"
else
CHRONYD="TIME SYNC KO"
fi
if systemctl is-active --quiet postfix; then
MAIL="MAIL OK"
else
MAIL="MAIL KO"
fi
MEMORY=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
SWAP=$(awk '/SwapTotal/ {print $2}' /proc/meminfo)
CPU=$(grep -c '^processor' /proc/cpuinfo)
MACHINE=$(sudo dmidecode -s system-manufacturer 2>/dev/null | xargs)
echo "$RHOSTNAME,$IPDETAILS,$DNSSERVERS,$OS,$KERNELV,$CHRONYD,$MAIL,$MEMORY,$SWAP,$CPU,$MACHINE" \
>> /tmp/server_check_list
5. Ubuntu Server List
Create:
ubuntu_list
with:
ans01
kub01
kub02
kub03
tomd01
tomp01
gra01
dock01
Here, ans01 is the Ubuntu Ansible control server itself. Including it allows the same inventory process to collect information from the Ansible server as well.
6. Ubuntu Inventory Script
Save the main script as:
ubuntu_inventory.sh
#!/bin/bash
# Purpose: Collect Ubuntu server inventory
# Version: 1.0
# Author: Vallabh Darole
echo "Enter your email ID:"
read -r EMAIL
OUTPUT="/tmp/ubuntu_server_check_list.csv"
MESSAGE="/tmp/ubuntu_MESSAGE"
HOSTLIST="/home/ansible/script/ubuntu_list"
> "$OUTPUT"
echo "HOSTNAME,IPDETAILS,DNSSERVERS,OS,KERNELV,TIME-SYNC,MAIL,MEMORY(KB),SWAP(KB),CPU,MACHINE" \
>> "$OUTPUT"
while IFS= read -r i
do
[ -z "$i" ] && continue
echo "======================================"
echo "Processing $i..."
echo "======================================"
timeout 10 ssh -n "$i" \
'sudo rm -f /tmp/server_check_list'
scp -q ubuntu_inventory_collect.sh \
"$i:/tmp/ubuntu_inventory_collect.sh"
if timeout 10 ssh -n "$i" \
'sudo bash /tmp/ubuntu_inventory_collect.sh'
then
echo "Collection successful: $i"
if timeout 10 ssh -n "$i" \
'sudo cat /tmp/server_check_list' >> "$OUTPUT"
then
echo "Data collected: $i"
else
echo "ERROR: Unable to collect data from $i"
fi
else
echo "ERROR: Collection failed on $i"
fi
timeout 10 ssh -n "$i" \
'sudo rm -f /tmp/server_check_list /tmp/ubuntu_inventory_collect.sh'
done < "$HOSTLIST"
DATE=$(date)
{
echo "Please find the Ubuntu server inventory created on:"
echo "$DATE"
echo
echo "Servers checked:"
cat "$HOSTLIST"
} > "$MESSAGE"
mutt -s "Ubuntu Server Inventory - $DATE" \
-a "$OUTPUT" -- "$EMAIL" < "$MESSAGE"
echo "Ubuntu inventory process completed."
7. Why ssh -n Is Important
One issue encountered during testing was that only the first server was processed.
The server list contained:
lamp01
zap01
pup01
web01
db01
jen01
son01
but the generated CSV contained only lamp01.
The reason is that ssh can consume input from the same standard input used by the while read loop.
Using:
ssh -n
prevents SSH from reading from the loop's input.
Therefore the script uses:
ssh -n "$i"
for all SSH operations.
This is an important detail when writing Bash automation that processes a list of servers.
8. Temporary File Cleanup
The collection script creates:
/tmp/server_check_list
on the target server.
After retrieving the data, the inventory script removes:
sudo rm -f /tmp/server_check_list
and:
sudo rm -f /tmp/rhel_inventory_collect.sh
or:
sudo rm -f /tmp/ubuntu_inventory_collect.sh
This prevents old inventory information from being appended to a new report.
The collection script also starts with:
> /tmp/server_check_list
This is important because the previous version of the script appended new information to an existing file, resulting in duplicate rows with old and new formats.
9. Directory Structure
The final automation directory on ans01 looks like:
/home/ansible/script/
│
├── rhel_list
├── rhel_inventory.sh
├── rhel_inventory_collect.sh
│
├── ubuntu_list
├── ubuntu_inventory.sh
└── ubuntu_inventory_collect.sh
Generated reports:
/tmp/server_check_list.csv
/tmp/ubuntu_server_check_list.csv
10. Execution
Make the scripts executable:
chmod +x rhel_inventory.sh
chmod +x rhel_inventory_collect.sh
chmod +x ubuntu_inventory.sh
chmod +x ubuntu_inventory_collect.sh
Run the RHEL inventory:
./rhel_inventory.sh
Run the Ubuntu inventory:
./ubuntu_inventory.sh
The generated CSV reports can then be emailed to the operations or infrastructure team.
Benefits
This automation provides several benefits:
Reduces manual server inventory collection.
Provides consistent information across servers.
Supports multiple Linux distributions.
Generates a CSV report suitable for Excel.
Can be scheduled through cron.
Uses the existing Ansible control server.
Cleans up temporary files automatically.
Handles multiple servers through simple host-list files.
Can easily be extended with additional checks.
Future Improvements
The scripts can be further enhanced by:
Adding Ansible instead of direct SSH execution.
Generating Excel
.xlsxfiles instead of CSV.Adding server reachability checks.
Recording failed servers separately.
Adding execution timestamps.
Adding application/service inventory.
Adding CPU utilization and filesystem utilization.
Storing historical inventory reports.
Scheduling the reports using cron.
Integrating the inventory process with Jenkins.
Conclusion
This Bash-based inventory solution provides a simple and practical way to automate Linux server information collection from a central Ubuntu Ansible server.
Using separate collection and inventory scripts keeps the design modular:
Central Ansible Server
|
+---- RHEL Inventory
| |
| +-- rhel_inventory.sh
| +-- rhel_inventory_collect.sh
|
+---- Ubuntu Inventory
|
+-- ubuntu_inventory.sh
+-- ubuntu_inventory_collect.sh
This approach can be used as a foundation for a larger Linux infrastructure inventory and health-check automation framework.
No comments:
Post a Comment