Pages

Automating Linux LVM Provisioning Using a CSV File

Managing LVM creation across multiple Linux servers can quickly become repetitive and error-prone. In this post, we will walk through a simple, production-ready Bash automation that provisions PV, VG, LV, filesystem, mount point, and fstab entries on multiple servers using a CSV file as input.

This approach is ideal for system administrators who want repeatable, auditable, and scalable storage provisioning.

What This Script Does
Using a single CSV file, the script will:
  • Connect to each server listed in the CSV
  • Validate block devices
  • Create Physical Volumes (PV)
  • Create or reuse Volume Groups (VG)
  • Create Logical Volumes (LV)
  • Create filesystems (XFS or ext4) non-interactively
  • Mount the filesystem
  • Persist the mount in `/etc/fstab`
  • Log all actions per server
The script is idempotent, meaning it is safe to re-run.

CSV Input File
The CSV file is the source of truth for all provisioning operations.

File: `linux_lvm.csv`
# server_name,pv_name,vg_name,lv_name,lv_size,lv_type,mount_point
192.168.10.220,/dev/sda,datavg,lv_app,2G,xfs,/app
192.168.10.220,/dev/sda,datavg,lv_dba,2G,xfs,/dba
192.168.10.221,/dev/sda,datavg,lv_app,2G,xfs,/app
192.168.10.221,/dev/sdb,datavg,lv_dba,2G,xfs,/dba

Column Explanation
server_name  ---> Hostname or IP address to SSH into 
pv_name  ---> Block device to use as PV
vg_name  ---> Volume Group name 
lv_name ---> Logical Volume name
lv_size  ---> Size of the LV (example: 2G)
lv_type  ---> Filesystem type (`xfs` or `ext4`) 
mount_point  ---> Mount directory 

Script Overview

The script performs the following steps for each row in the CSV:
1. Reads the CSV (skipping the header)
2. Validates required fields and filesystem type
3. SSHs into the target server
4. Checks if the PV exists, otherwise creates it
5. Checks if the VG exists, otherwise creates it
6. Creates the LV if it does not exist
7. Detects existing filesystem signatures
8. Creates the filesystem safely and non-interactively
9. Mounts the filesystem
10. Adds a persistent `/etc/fstab` entry
11. Logs output to `/var/log/lvm_provision_<hostname>.log`

LVM Provisioning Script
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#!/bin/bash
# Author: adminCtrlX
# Purpose: LVM provisioning using server_name from CSV

CSV_FILE="/tmp/scripts/linux_lvm.csv"
SUPPORTED_FS="ext4 xfs"

[ ! -f "$CSV_FILE" ] && {
echo "ERROR: CSV file not found: $CSV_FILE"
exit 1
}

tail -n +2 "$CSV_FILE" | while IFS=',' read -r \
server_name pv_name vg_name lv_name lv_size lv_type mount_point
do
echo "========== Processing $server_name =========="

if [[ -z "$server_name" || -z "$pv_name" || -z "$vg_name" || -z "$lv_name" || \
-z "$lv_size" || -z "$lv_type" || -z "$mount_point" ]]; then
echo "ERROR: Missing mandatory CSV fields. Skipping row."
continue
fi

[[ ! "$lv_size" =~ ^[0-9]+G$ ]] && continue
[[ ! " $SUPPORTED_FS " =~ " $lv_type " ]] && continue

ssh "$server_name" sudo bash <<EOF
LOG_FILE="/var/log/lvm_provision_\$(hostname).log"
exec > >(tee -a "\$LOG_FILE") 2>&1

[ ! -b "$pv_name" ] && { echo "Block device not found"; exit 1; }
pvs "$pv_name" &>/dev/null || pvcreate "$pv_name"
vgs "$vg_name" &>/dev/null || vgcreate "$vg_name" "$pv_name"

LV_PATH="/dev/$vg_name/$lv_name"
lvs "\$LV_PATH" &>/dev/null || lvcreate -L "$lv_size" -n "$lv_name" "$vg_name"

FS_EXIST=\$(lsblk -no FSTYPE "\$LV_PATH")
if [ -z "\$FS_EXIST" ]; then
wipefs -a "\$LV_PATH"
mkfs.$lv_type -f "\$LV_PATH"
fi

mkdir -p "$mount_point"
mountpoint -q "$mount_point" || mount "\$LV_PATH" "$mount_point"
grep -q "\$LV_PATH" /etc/fstab || \
echo "\$LV_PATH $mount_point $lv_type defaults 0 0" >> /etc/fstab
echo "SUCCESS on \$(hostname)"
EOF
done
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Logging
Each server logs execution details to:
/var/log/lvm_provision_<hostname>.log
This makes troubleshooting and auditing straightforward.

Benefits of This Approach
  • CSV-driven infrastructure
  • No interactive prompts
  • Safe to re-run
  • Scales to dozens of servers
  • Clear separation of data and logic
  • Ideal for automation and CI/CD pipelines
Final Thoughts
Using a CSV-driven LVM provisioning script gives you consistency, speed, and reliability when managing storage across multiple Linux systems. This method is especially useful in environments where infrastructure must be provisioned repeatedly with minimal human error.
If you’d like to extend this further, consider adding:
  • DRY-RUN mode
  • Filesystem resize support
  • Wipe control per volume
  • Parallel SSH execution

No comments:

Post a Comment