Home Linux Disk Management How To Use Ansible To Automate Logical Volume Manager (LVM) In Linux

How To Use Ansible To Automate Logical Volume Manager (LVM) In Linux

How To Work With LVM Using Ansible

By Karthick
10.2K views

As part of the LVM series, we have seen how to export and import logical volumes between different machines in the previous article. In this article, we will see how to use ansible to automate the Logical Volume Manager (LVM) setup in Linux.

Ansible is a simple and easy-to-use automation tool that offers different modules to work with disk management in Linux. When you have more machines to install and configure the operating system with the same configuration then ansible is of great use. A particular use case I can think of is when you are building a cluster where all the servers have the same storage space and need the same LVM partition scheme.

Creating a logical volume manually involves 4 steps.

  • STEP 1: Initialize the drive as the physical volume.
  • STEP 2: Create a volume group for the physical volume.
  • STEP 3: Create the logical volume from the volume group.
  • STEP 4: Format the logical volume and mount the file system.

To learn how to perform the above 4 steps manually, take a look at our introduction to LVM article.

Linux Logical Volume Manager (LVM) Guide For Beginners

As the first step, you need to gather disk-related information for the target host. This is a useful task when you want to decide the space allocation dynamically.

Either you can do it manually or use the ansible facts mechanism which collects the disk-related facts. The below playbook will retrieve the disk-related information of the target host.

---
- name: LVM Setup
 hosts: localhost
 connection: local
 gather_facts: true

 tasks:
   - name: Collect stats for hardware
     ansible.builtin.setup:
       gather_subset:
         - hardware

   - name: Print the stat output for devices
     ansible.builtin.debug:
       var: hostvars[inventory_hostname].ansible_devices

The above playbook will first collect the hardware details using the setup module. In the second task, the output of ansible_devices alone will be printed.

Collect Storage-Related Information from Ansible Facts
Collect Storage-Related Information from Ansible Facts

You can further apply all sorts of filters as per your requirement to get specific data and compute dynamic values for new partition creations. For example, the below task will print all the devices that start with sd* and their size.

- name: Print the disk size only for sd disks
 ansible.builtin.debug:
   msg: "{{ ansible_devices[item].size }}"
 loop: "{{ ansible_devices.keys() | map('regex_search', 'sd.*') | select('string') | list }}"

Since I have only one disk it prints the sda disk size.

TASK [Print the disk size only for sd disks] **********************************************
ok: [localhost] => (item=sda) => {
    "msg": "931.51 GB"
}

Ansible Playbook for Creating LVM

I will be using the following playbook for demonstration. You can replicate the same code by changing the disk name and partition size per your requirement. I will walk you through each task in the playbook with its output in the subsequent sections.

---
- name: LVM Testing
 hosts: localhost
 become: true
 gather_facts: False

 tasks:
   - name: Partition /dev/sdd disk
     community.general.parted:
       device: /dev/sdd
       number: 1
       flags: [ lvm ]
       state: present
       part_end: 5GiB

   - name: Task for PV and VG
     community.general.lvg:
         vg: ostechnixlab
         pvs: /dev/sdd1

   - name: Logical volume with 1GB size
     community.general.lvol:
       vg: ostechnixlab
       lv: labpart1
       size: 1G

   - name: Format the volume with ext4 fs
     community.general.filesystem:
       fstype: ext4
       dev: /dev/ostechnixlab/labpart1

   - name: Target directory under /opt/
     ansible.builtin.file:
       path: /opt/lvm_test/
       state: directory
       mode: '0755'

   - name: mount the lv on /data1
     ansible.posix.mount:
       path: /opt/lvm_test/
       src: /dev/ostechnixlab/labpart1
       fstype: ext4
       state: mounted

Create Volume using Parted Module

As the first step, you must create a volume from the raw disk with lvm as the type. You can either use the entire disk or further partition the disk and just use only that particular partition for LVM.

Ansible uses parted module for creating partitions. This is similar to parted command in Linux which is used to configure device partitions.

Heads Up: parted in a community module that ships with the community.general namespace. If you do not have community modules installed, install them using the below command.

$ ansible-galaxy collection install community.general

I have a disk /dev/sdd with 15GB in size.

$ lsblk /dev/sdd
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdd    8:48   0  15G  0 disk 

I will create a partition that is /dev/sdd1 of size 5GB. The following task uses the parted module to partition /dev/sdd1 of 5GB with lvm as type.

  • device: Provide the block device name like /dev/sda, /dev/sdb etc.
  • number: The number of partitions that will be created. Here it is set as 1.
  • flags: It sets the type for your partition. In this case, it is LVM.
  • state: Setting the state to "present" will create the partition.
  • part_end: Size for the partition.
- name: Partition /dev/sdd disk
 community.builtin.parted:
   device: /dev/sdd
   number: 1
   flags: [lvm]
   state: present
   part_end: 5GiB

Following is the output for the above task.

Create Volume using Parted Module
Create Volume using Parted Module

Run the lsblk command to check the partition.

$ lsblk /dev/sdd
NAME   MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdd      8:48   0  15G  0 disk 
└─sdd1   8:49   0   5G  0 part 

Create Physical Volume and Volume Group

The next step is to initialize /dev/sdd1 as physical volume and add it to a volume group. Use the lvg module which is also maintained under community.general namespace.

The following task will initialize /dev/sdd1 as physical volume and add it to the volume group named ostechnixlab.

- name: Task for PV and VG
  lvg:
      vg: ostechnixlab
      pvs: /dev/sdd1

Following is the output for the above task.

Create Physical Volume and Volume Group
Create Physical Volume and Volume Group

You can also initialize multiple physical volumes and add them to the volume group.

- name: Task for PV and VG
  lvg:
      vg: ostechnixlab
      pvs: /dev/sdd1, /dev/sdd2, /dev/sdd3

You can also define the extent size. By default, it is set to 4MB.

- name: Task for PV and VG
  lvg:
      vg: ostechnixlab
      pvs: /dev/sdd1, /dev/sdd2, /dev/sdd3
      pesize: 8

You can check the volume group status by running the following command.

$ sudo vgs ostechnixlab
  VG           #PV #LV #SN Attr   VSize  VFree 
  ostechnixlab   1   0   0 wz--n- <5.00g <5.00g

Create Logical Volume

The next step is to create the logical volume using the community-maintained lvol module.

In the below task, I am creating a logical volume called lbapart1 from the volume group ostechnixlab. The total size of the volume group is 5GB and the logical volume is set to 1GB in size.

- name: Logical volume with 1GB size
  community.general.lvol:
    vg: ostechnixlab
    lv: labpart1
    size: 1G

Below is the output for the above task.

Create Logical Volume
Create Logical Volume

Run the lvs command to check the volume created.

$ sudo lvs
   LV       VG            Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  labpart1 ostechnixlab  -wi-a----- 1.00g    

Mount the Logical Volume

In this step, you will mount the logical volume to start consuming it. At first, you must format the volume with any supported file system type and mount the volume.

I will divide the above steps into 3 tasks.

  1. The first task will format the volume with the ext4 file system. For this filesystem module should be used which is part of the "community.general" namespace.
  2. The second task will use the file module to create a directory with the volume that will be mounted. For this, the file module should be used which is part of the "ansible.builtin" namespace.
  3. The third task will mount the formatted volume in the file system we created in the second task. For this, the mount module should be used which is part of the "ansible.posix" namespace.
- name: Format the volume with ext4 fs
  community.general.filesystem:
   fstype: ext4
   dev: /dev/ostechnixlab/labpart1

- name: Target directory under /opt/
  ansible.builtin.file:
   path: /opt/lvm_test/
   state: directory
   mode: '0755'

- name: mount the lv on /data1
 ansible.posix.mount:
   path: /opt/lvm_test/
   src: /dev/ostechnixlab/labpart1
   fstype: ext4
   state: mounted

Following is the output for the above tasks.

Mount Logical Volume
Mount Logical Volume

You can use the mount and/or df command to verify the file system type and mount status.

$ mount | grep -i labpart1
/dev/mapper/ostechnixlab-labpart1 on /opt/lvm_test type ext4 (rw,relatime)
$ df -h /opt/lvm_test/
Filesystem                         Size  Used Avail Use% Mounted on
/dev/mapper/ostechnixlab-labpart1  974M   24K  907M   1% /opt/lvm_test

Conclusion

In this article, we have seen what are the different ansible modules that we can use to create partitions, logical volume and mount the file system. You can create a dedicated role for LVM and reuse it across different environments dynamically just by passing arguments.

You May Also Like

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

This website uses cookies to improve your experience. By using this site, we will assume that you're OK with it. Accept Read More