In modern infrastructure environments, storage requirements are dynamic—new disks are frequently added to systems, especially in cloud and virtualized environments. Manually detecting, configuring, and mounting these disks is time-consuming and error-prone.
This blog walks through an automated approach using Ansible to dynamically detect new disks and configure them with Logical Volume Manager (LVM)—end-to-end, without manual intervention.
Why Automate Disk Provisioning?
Traditionally, storage provisioning involves multiple manual steps:
- Identifying unused disks
- Creating physical volumes (PV)
- Creating volume groups (VG)
- Creating logical volumes (LV)
- Formatting and mounting
Automation helps:
- Reduce human errors
- Ensure consistency across systems
- Speed up provisioning (seconds vs minutes)
- Enable event-driven infrastructure
Solution Overview
This playbook automates the complete lifecycle:
- Detect unpartitioned disks
- Filter valid target disks
- Install required dependencies
- Create LVM structure (PV → VG → LV)
- Format filesystem
- Mount and persist configuration
Key Components Explained
1. Dynamic Disk Detection
The playbook leverages Ansible facts (ansible_devices) to identify disks with no partitions:
unpartitioned_disks: "{{ ansible_devices | dict2items | selectattr('value.partitions', 'equalto', {}) }}"
This ensures only unused disks are considered.
2. Intelligent Disk Filtering
Not all devices should be used. The playbook excludes:
-
Device mapper entries (
dm-*) -
CD-ROM devices (
sr*)
reject('match', '^dm-.*')
reject('match', '^sr.*')
This avoids accidental modification of system-critical or virtual devices.
3. Dependency Installation
Before performing LVM operations, required packages are installed:
-
lvm2→ LVM management -
xfsprogs→ Filesystem tools -
sg3_utils→ SCSI utilities
This ensures the system is ready for storage operations.
4. Safety Check
The playbook includes a fail-safe:
- name: Fail if no suitable empty disk was found
This prevents unintended execution when no valid disk is available.
5. LVM Creation Workflow
The playbook automates:
- Physical Volume (PV) creation
- Volume Group (VG) creation
- Logical Volume (LV) allocation (100% of space)
Using Ansible modules:
-
community.general.lvg -
community.general.lvol
This ensures idempotent and repeatable execution.
6. Filesystem Creation
A filesystem (default: XFS) is created:
fstype: xfs
XFS is widely used in enterprise Linux environments due to its scalability and performance.
7. Mounting and Persistence
Finally:
- Mount point is created
- Filesystem is mounted
-
/etc/fstabis updated automatically
This guarantees persistence across reboots.
End-to-End Workflow Visualization
New Disk → Detect → Filter → Validate
→ Create PV → Create VG → Create LV
→ Format → Mount → Persist
Key Benefits of This Approach
✅ Fully Automated
No manual intervention required after disk attachment.
✅ Idempotent
Safe to run multiple times—no duplicate configurations.
✅ Scalable
Works across hundreds or thousands of servers.
✅ Error-Resilient
Built-in checks prevent misconfiguration.
✅ Standardized
Enforces consistent naming and structure.
Sample playbook
---
- name: Dynamic Disk Detection and LVM Setup
hosts: all
become: true
vars:
vg_name: "data_vg"
lv_name: "data_lv"
mount_path: "/mnt/data"
fs_type: "xfs"
tasks:
- name: Find unpartitioned disks
set_fact:
unpartitioned_disks: "{{ ansible_devices | dict2items | selectattr('value.partitions', 'equalto', {}) | map(attribute='key') | list }}"
- name: Filter for actual physical/virtual disks
set_fact:
target_disk: "{{ ansible_devices | dict2items | selectattr('value.partitions', 'equalto', {}) |
map(attribute='key') | list |
reject('match', '^dm-.*') |
reject('match', '^sr.*') |
list }}"
- name: Show the real new disk
debug:
msg: "The actual new disk is: /dev/{{ target_disk | first }}"
- name: Install required packages for LVM and filesystem management
ansible.builtin.package:
name:
- lvm2
- xfsprogs
- sg3_utils
state: present
- name: Fail if no suitable empty disk was found
ansible.builtin.fail:
msg: "No unpartitioned disks found on the system."
when: target_disk is not defined
- name: Create Physical Volume and Volume Group
community.general.lvg:
vg: "{{ vg_name }}"
pvs: "/dev/{{ target_disk | first }}"
state: present
- name: Create Logical Volume (100% of VG space)
community.general.lvol:
vg: "{{ vg_name }}"
lv: "{{ lv_name }}"
size: 100%FREE
state: present
- name: Create Filesystem on Logical Volume
community.general.filesystem:
fstype: "{{ fs_type }}"
dev: "/dev/{{ vg_name }}/{{ lv_name }}"
- name: Ensure Mount Directory exists
ansible.builtin.file:
path: "{{ mount_path }}"
state: directory
mode: '0755'
- name: Mount the volume and update fstab
ansible.builtin.mount:
path: "{{ mount_path }}"
src: "/dev/{{ vg_name }}/{{ lv_name }}"
fstype: "{{ fs_type }}"
state: mounted
No comments:
Post a Comment