Skip to content

Instantly share code, notes, and snippets.

@gilfreund
Last active April 5, 2024 23:12
Show Gist options
  • Save gilfreund/166601021a2b79ba5071635a87595ea4 to your computer and use it in GitHub Desktop.
Save gilfreund/166601021a2b79ba5071635a87595ea4 to your computer and use it in GitHub Desktop.
Automatically mount EC2 free ephemeral disks into an LVM group

I have found the original script from a post by Leon Mergen. See also raid_ephemeral.sh from Joe Miller

I updated it for my needs, which were:

  • Work independently of device name (/dev/sdX, /dev/xvdX or /dev/nvmeXXX)
  • Avoid mounting a device which is already in use (some ami will mount the first epehermal device)
  • Avoid using metadata, as it's not trustworthy when using launch templates. This means the script does not know if the devices are EBS or Ephemeral. I would recommend not to use this if you have a mixed EBS/Ephemeral instance, as the volume will be corrupted if the instance is stoped.
#!/bin/bash
# based on code byLeon Mergen
# see: https://leonmergen.com/automatically-mounting-instance-store-on-an-aws-ami-150da3ffd041
LVDISPLAY=$(which lvdisplay)
PVCREATE=$(which pvcreate)
VGCREATE=$(which vgcreate)
LVCREATE=$(which lvcreate)
MOUNT=$(which mount)
MKDIR=$(which mkdir)
CHMOD=$(which chmod)
LVNAME="data"
MKFSCMD=$(which mkfs)
MKFS="$MKFSCMD -t xfs"
MOUNTPOINT="/scratch"
DEVICE_PREFIX="/dev"
if [ -b $DEVICE_PREFIX/dm-0 ] ; then
echo "LVM already configured, exiting ...."
exit 3
fi
echo No LVM configured, yet
function mount_volume {
if [ ! -d "$MOUNTPOINT" ]
then
$MKDIR -p ${MOUNTPOINT}
$CHMOD 0777 ${MOUNTPOINT}
fi
$MOUNT $1 ${MOUNTPOINT}
}
# Detects all local block devices present on the machine,
# skipping the first (which is assumed to be root).
function detect_devices {
# Get root device in order to identify naming scheme and to ignore then using.
local ROOT_DRIVE=$(blkid -L / -o device | cut -d "/" -f 3 | cut -c 1-7 )
# Find if there are devices
if [ -z $ROOT_DRIVE ] ; then
echo "No devices found, exiting ...."
exit 4
fi
local DEVICES_LIST=$(find /dev -type b | grep -v "$ROOT_DRIVE")
# Check if any of the devices is mounted
# Exit if there is only one devices, and it's mounted
for DEVICE in $DEVICES_LIST
do
if ! grep -q $(readlink -f $DEVICE) /proc/mounts
then
local DEVICES="$DEVICE $DEVICES"
else
if [ $i == 1 ]
then
echo "Ephemeral device already in use, exiting .."
exit 5
fi
fi
done
echo $DEVICES
}
# Creates a new LVM volume. Accepts an array of block devices to
# use as physical storage.
function create_volume {
for device in $@
do
$PVCREATE $device --yes
done
# Creates a new volume group which pools all
# available block devices.
${VGCREATE} $LVNAME $@
# Create a logical volume with all the available storage space
# assigned to it.
${LVCREATE} -l 100%FREE $LVNAME --yes
# Create a filesystem so we can use the partition.
${MKFS} $(get_volume)
}
function detect_volume {
local VOLCHECK=$($LVDISPLAY)
if [ ! -z "$VOLCHECK" ]
then
local VOLUME=$(${LVDISPLAY} | grep 'LV Path' | awk '{print $3}')
echo $VOLUME
fi
}
# Similar to detect_volume, but fails if no volume is found.
function get_volume {
local VOLUME=$(detect_volume)
if [ -z "$VOLUME" ]
then
echo "Fatal error: LVM volume not found!" 1>&2
exit 1
fi
echo $VOLUME
}
# Detect existing LVM volume
echo Start detect volume
VOLUME=$(detect_volume)
echo End detect volume
echo Start new volume
# And create a brand new LVM volume if none were found
if [ -z "$VOLUME" ]
then
echo Start create volume on DEVICE_SUFFIX $DEVICE_PREFIX
create_volume $(detect_devices $DEVICE_PREFIX)
echo End create volume
else
echo what is "$VOLUME"
fi
echo End new volume
mount_volume $(get_volume)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment