Yuri Astrakhan
Yuri Astrakhan

Reputation: 9965

Automate GCP persistent disk initialization

Are there any scripts that automate persistent disks formatting and attaching to the Google Cloud VM instance, instead of doing formatting & mounting steps?

The persistent disk is created with Terraform, which also creates a VM and attaches the disk to it with the attached_disk command.

I am hoping to run a simple script on the VM instance start that would:

Upvotes: 14

Views: 6826

Answers (3)

Raj Saxena
Raj Saxena

Reputation: 872

The marked answer did not work for me as the sudo blkid /dev/sdb part always returned a value (hence, true) and the script would exit.

I updated the script to check for the entry in fstab and added safety options to the script.

#!/bin/bash
set -uxo pipefail

MOUNT_DIR=/mnt/disks/persistent_storage
DISK_NAME=my-disk

# Check if entry exists in fstab
grep -q "$MOUNT_DIR" /etc/fstab
if [[ $? -eq 0 ]]; then # Entry exists
    exit
else
    set -e # The grep above returns non-zero for no matches & we don't want to exit then.

    # Find persistent disk's drive value, prefixed by `google-`
    DEVICE_NAME="/dev/$(basename $(readlink /dev/disk/by-id/google-${DISK_NAME}))"

    sudo mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard $DEVICE_NAME
    sudo mkdir -p $MOUNT_DIR
    sudo mount -o discard,defaults $DEVICE_NAME $MOUNT_DIR

    # Add fstab entry
    echo UUID=$(sudo blkid -s UUID -o value $DEVICE_NAME) $MOUNT_DIR ext4 discard,defaults,nofail 0 2 | sudo tee -a /etc/fstab
fi

Here's the gist if you want to download it - https://gist.github.com/raj-saxena/3dcaa5c0ba0be88ed91ef3fb50d3ce85

Upvotes: 9

ayuuk ja'ay
ayuuk ja'ay

Reputation: 384

Formatting, mounting and adding entry in /etc/fstab is necessary almost all the time. Here is a solution I came up with and might help others. This can also, for sure, be improved. I added echo commands to explain what each block does.

About disk name you could add device_name on your terraform code when you attach your disks to the instance(s) like mentioned here: https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_attached_disk

device_name - (Optional) Specifies a unique device name of your choice that is reflected into the /dev/disk/by-id/google- tree of a Linux operating system running within the instance. This name can be used to reference the device for mounting, resizing, and so on, from within the instance.*

#!/bin/bash

DISKS_PATH=/dev/disk/by-id

DISKS=(disk1 disk2)

check_disks () {
    for disk in "${DISKS[@]}"; do
        MOUNT_DIR="/$disk"
        echo "$MOUNT_DIR"
        if sudo blkid $DISKS_PATH/google-${disk}; then
            echo "$disk is already formatted, nothing to do"
            echo "checking if $disk is present in fstab"
            UUID=$(sudo blkid -s UUID -o value $DISKS_PATH/google-${disk})
            grep -q "UUID=${UUID} $MOUNT_DIR" /etc/fstab
            if [[ $? -eq 0 ]]; then
                echo "$disk already present in fstab, continuing with checking mount"
                echo "Now checking if $disk is already mounted"
                grep -qs "$MOUNT_DIR" /proc/mounts
                if [[ $? -eq 0 ]]; then
                    echo "$disk is already mounted, so doing nothing  with mount"
                else
                    echo "$disk is not mounted, so mounting it"
                    sudo mkdir -p $MOUNT_DIR
                    sudo mount -o discard,defaults $DISKS_PATH/google-${disk} $MOUNT_DIR
                fi
            elif [[ $? -ne 0 ]]; then
                echo "$disk not present in fstab, so adding it"
                echo UUID="$UUID" $MOUNT_DIR ext4 discard,defaults,nofail 0 2 | sudo tee -a /etc/fstab
                echo "Now checking if $disk is already mounted"
                grep -qs "$MOUNT_DIR" /proc/mounts
                if [[ $? -eq 0 ]]; then
                    echo "$disk is already mounted, so doing nothing  with mount"
                else
                    echo "$disk is not mounted, so mounting it"
                    sudo mkdir -p $MOUNT_DIR
                    sudo mount -o discard,defaults $DISKS_PATH/google-${disk} $MOUNT_DIR
                fi
            fi
        else
            echo "Formatting ${disk}"
            sudo mkfs.ext4 $DISKS_PATH/google-${disk};
            echo "Creating directory for ${disk} on $MOUNT_DIR"
            sudo mkdir -p $MOUNT_DIR
            echo "adding  $disk in fstab"
            UUID=$(sudo blkid -s UUID -o value $DISKS_PATH/google-${disk})
            echo UUID="$UUID" $MOUNT_DIR ext4 discard,defaults,nofail 0 2 | sudo tee -a /etc/fstab
            echo "Mounting $disk"
            sudo mount -o discard,defaults $DISKS_PATH/google-${disk} $MOUNT_DIR
        fi
    done
}

check_disks

Upvotes: 2

neilH
neilH

Reputation: 3438

Have you considered using a startup script on the instance (I presume you can also add a startup-script with Terraform)? You could use an if loop to discover if the disk is formatted, then if not, you could try running the formatting/mounting commands in the documentation you linked (I realise you have suggested you do not want to follow the manual steps in the documentation, but these can be integrated into the startup script to achieve the desired result).

Running the following outputs and empty string if the disk is not formatted:

 sudo blkid /dev/sdb

You could therefore use this in a startup script to discover if the disk is formatted, then perform formatting/mounting if that is not the case. For example, you could use something like this (Note*** If the disk is formatted but not mounted this could be dangerous and should not be used if your use case could involve existing disks which may have already been formatted):

#!/bin/bash


if sudo blkid /dev/sdb;then 
        exit
else 
        sudo mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb; \
        sudo mkdir -p /mnt/disks/newdisk
        sudo mount -o discard,defaults /dev/sdb /mnt/disks/newdisk
fi

Upvotes: 10

Related Questions