Create a Logical volume using Ansible


In our last guide, we have seen how to manage user accounts using ansible. By following in this guide let us see how to create a new logical volume (LVM) filesystem using ansible.

Ansible
Ansible

To read about more topics on “Ansible” you can refer to the below links.

  1. Install and configure Ansible Automation IT Tool
  2. Install Ansible using Python installation manager pip
  3. How to create a host’s Inventory using Ansible

Updated Playbook on 01-01-2020 without partitioning

This updated playbook created with lvg, lvol, file, filesystem and mount modules. Make sure to replace your hostname or host group by replacing “linuxsysadmins”. Replace the remote user account as well with your user account.

The account requires administrative privilege.

---
- hosts: linuxsysadmins
  become: true
  become_method: sudo
  become_user: root
  remote_user: devops

  vars_prompt:
    - name: "raw_disks"
      prompt: "Raw disk used for create a Physical Volume"
      private: no

    - name: "vg_name"
      prompt: "Name of the Volume Group"
      private: no
 
    - name: "lv_name"
      prompt: "Name of the logical Volume"
      private: no
 
    - name: "require_lv_size"
      prompt: "Size of Logical volume to be created."
      private: no

    - name: "fs"
      prompt: "Type of filesystem need to be created."
      private: no

    - name: "mount_point"
      prompt: "Mount the filesystem under."
      private: no

  tasks:

    - name: Create the "{{ vg_name }}" Volume group.
      lvg:
        pvs: "/dev/{{ raw_disks }}"
        vg: "{{ vg_name }}"
        pesize: "8"
        pv_options: '-Z y'
        force: no
        state: present
 
    - name: Create the "{{ lv_name }}" Logical Volume.
      lvol:
        vg: "{{ vg_name }}"
        lv: "{{ lv_name }}"
        size: "{{ require_lv_size }}"
        active: yes
        force: no
        state: present
    
    - name: Create a "{{ fs }}" filesystem on lvm "/dev/mapper/{{ vg_name}}-{{ lv_name}}".
      filesystem:
        fstype: "{{ fs }}"
        dev: "/dev/mapper/{{ vg_name }}-{{ lv_name }}"
        force: no

    - name: Create a directory to mount the filesystem.
      file:
        path: "{{ mount_point }}"
        state: directory
        mode: '0755'

    - name: Mount the created "{{ fs }}" filesystem.
      mount:
        path: "{{ mount_point }}"
        src: "/dev/mapper/{{ vg_name}}-{{ lv_name}}"
        fstype: "{{ fs }}"
        opts: rw,nosuid,noexec
        state: mounted
...

Copy above playbook and create a .yml file to keep the indentation.

# cat > logical_volume.yml

Then press RETURN and paste the above-copied content. To save the file press CTRL+D twice. That’s it we are good with saving the YAML file without messing the indentation.

Creating a Logical Volume with partitioning

Warning: Strictly advice to use this playbook in a new build server.

What I’m trying to perform here is to create a new filesystem using /dev/sdb. Server Operating System installed in “/dev/sda” by following we need to create a mount point for “/datas” in this case we have 100 GB of disk “/dev/sdb” and it needs to be created using logical volume. Create the filesystem and mount under /datas.

What does this Ansible playbook do?

  • Defined in which host this playbook needs to be run.
  • Amend with variables prompt which will take user input.
  • Defined with tasks to create file systems, mount, fstab entry.
  • Partitions using fdisk
  • Create Volume group with each 8 MB in PE size.
  • New logical volume from the volume group by using 100% of the space in VG.
  • Create a filesystem in the newly created logical volume. (ext3, ext4, xfs)
  • Mount the newly created filesystem with required mount options.

Partitioning Disk using Fdisk

You may ask how I’m using the fdisk to create a partition. It simple by using an echo.

# /bin/echo -e "n\np\n1\n\n\nt\n8e\nw" | sudo fdisk "{{ disk_name }}"

new line represent hereby Pressing an “Enter Key”.

n\ = new partition, new line
np\ = primary, new line
n1\ = 1 st primary, 1 and new line
n\ = new line
n\ = new line
nt\ = t and new line
n8e\ = LVM type 8e and new line
nw” = write and exit, new line

|” = forwarding all inputs to fdisk command on a disk.

This is how we are using fdisk to create a partition using the echo command.

Warning: Never use in an existing production environment. If you know what you doing kindly point to right disk to avoid data loss.

Playbook

Here the playbook starts.

---
- hosts: "{{ hosts_prompt }}" ## This will get from "hosts_promt" as an input of any Hostname or Host group
  gather_facts: no
  connection: ssh

  vars_prompt:
   - name: "hosts_prompt" ## Host where playbook about to play
     prompt: "Enter the Host or Host group need to run with this Playbook"
     private: no

   - name: "disk_name" ## Which disk we are using to create a partition for a logical volume. eg(/dev/sdb,/dev/sdc)
     prompt: "Disk used for creating partition"
     private: no

   - name: "pvs_name" ## Disk after partition
     prompt: "Disk name after creating with partition"
     private: no

   - name: "vg_name" ## Name of Volume group about to create.
     prompt: "Enter VG name to be created"
     private: no

   - name: "lv_name" ## Name of Logical Volume about to create.
     prompt: "Enter LV name to be created"
     private: no

   - name: "file_system" ## What type of filesystem it can be ext3, ext4 or xfs etc.
     prompt: "Type of file system required?"
     private: no

   - name: "mount_point" ## In what name mount point should be created.
     prompt: "Where need to mount?"
     private: no
   
  tasks:
   - name: Create Partition for "{{ mount_point }}" file system
     remote_user: ansible
     become: yes
     become_method: sudo
     shell:
       /bin/echo -e "n\np\n1\n\n\nt\n8e\nw" | sudo fdisk "{{ disk_name }}" ## Create the partition on a disk.

   - name: Create VG for vg_u01
     remote_user: ansible
     become: yes
     become_method: sudo
     lvg:
       vg: "{{ vg_name }}" ## Name of Volume group.
       pvs: "{{ pvs_name }}" ## Physical Volume created using partition eg (/dev/sdb1 or /dev/sdc1)
       pesize: 8

   - name: Create LVM lv_u01 for "{{ mount_point }}" file system.
     remote_user: ansible
     become: yes
     become_method: sudo
     lvol:
       vg: "{{ vg_name }}"
       lv: "{{ lv_name }}" ## Name of Logical volume need to be created
       size: 100%FREE ## All the PE's in Volume group will be used for creating the logical volume.

   - name: Create the file system on newly created Logical volume for "{{ mount_point }}".
     remote_user: ansible
     become: yes
     become_method: sudo
     filesystem:
       fstype: "{{ file_system }}" ## What type of filesystem required eg:(ext3, ext4, xfs etc.)
       dev: "/dev/mapper/{{ vg_name }}-{{ lv_name }}" ## Full related path of device mapper to be created with creating FS.

   - name: Mount the created filesystem ## This is to create the FSTAB entry and mount the Filesystem.
     remote_user: ansible
     become: yes
     become_method: sudo
     mount:
       path: "{{ mount_point }}" ## Mount point where to mount the FS.
       src: "/dev/mapper/{{ vg_name }}-{{ lv_name }}" ## Full related path of device mapper to be mounted under mount point.
       fstype: "{{ file_system }}" ## Filesystem type
       opts: rw,noatime,noexec,nodev,nosuid ## Mount options
       state: mounted

That’s it we have successfully created with a new Filesystem on a remote server with ansible lvm. This will help in case we are deploying with the number of new servers. Make sure to not use in an existing production environment.

Conclusion

This guide walks through creating a logical volume using ansible with specific modules. In our next guide will cover with more stuff related to ansible. Subscribe to the newsletter and stay tuned.

7 thoughts on “Create a Logical volume using Ansible

  1. Hello Babin, thanks for creating this playbook and this is very informative. I have tried this and was successful in my testing environment. i have one query on this.
    hosts_prompt is interactive here, but i think we have to define all hosts in inventory file first and hosts are being picked up from inventory file when we enter hostname.
    do we have any way to run the playbook in remote host without defining hosts from inventory file? rather it run on remote hosts when we enter hostnames when prompt asks.
    “[WARNING]: Could not match supplied host pattern, ignoring: “

  2. hi Babin,
    Thank you for this tutorial, was great. How would I go about adding a 2nd disk say /sdc and extending the vg,lv and extending the filesystem. I suppose you could use the shell command but was hoping there is easier way.

  3. Hey, nice job!
    I was researching about LVM and ansible, using the LVM module i couldn’t create a striped volume.
    Any sugestion?

  4. Hi,

    What about Ansible modules lvol, filesystem… ect which are idempotent ?
    What do you think about a playbook that can be run even after data took place ?
    So for example after asking for more physical volume, you may want to just to modify some file system size (in a group_var file) and run a playbook to do the rest of work safely

Comments are closed.