We need several utility scripts that need to be executed as part of setup and configuration of a AWS Elastic Beanstalk environment. "mount-all-instance-storage.sh" is one such utility script.
Most of the EC2 instance types come with instance storage with varied sizes, except for EC2 micro instance and few more. Instance storage or ephemeral storage is nothing but the local hard disk of the machine. They have no I/O costs unlike EBS (Elastic Block Store). EBS volumes are like network drives, highly available and persist independently from the life of an instance. However the contents of instance storage can persist only across reboots, but they are lost forever once the instance is terminated. After being aware of this then it is up to each application how to make use of this instance storage.
hudku.com uses Linux operating system and hence all the discussions are applicable only if you are using Linux.
All the instance stores are not mounted by default by AWS Elastic Beanstalk. We need to mount them as part of our application setup and we do it by executing the bash script file "mount-all-instance-storage.sh". Fortunately I found most of the required code at StackOverflow and let us thank the website as well as Ayush Gupta who posted the valuable script.
The script simply scans through all the available devices and for each device found, it formats it, mounts it and makes an entry in /etc/fstab file so that all the devices get mounted after every reboot. Only change I made to the script was not to mount each device and instead just make the entry in /etc/fstab file after formatting the device. Later I mount all the devices specified in fstab file in one shot using "mount -a" command. That way the correctness of the entries made to fstab get tested right away and we do not have to wait for a reboot to confirm it.
Another change I made to the script was to resize the root file system using the command "resize2fs". Beanstalk by default attaches a EBS volume of size 8GB and mounts it as the root volume. By using a custom AMI we could use a EBS volume of larger size as per the requirement. In such case we need to run "resize2fs" command to make the entire size of the volume available for use.
Then other major addition I made to the script is to create the system swap file. By default the swap file is not created under AWS Elastic Beanstalk environment. The swap file is critical and essential especially while using EC2 Micro Instance (t1.micro), where the available memory is only around 612MB. Without the swap file if an application demands more memory than available, it would simply abort. We try to create the swap file on the instance storage as we found its speed acceptable. On larger EC2 instance type with sufficient RAM, even if swap file is present, we found that it never got used. We try to create a swap file of size 1GB if available RAM is more than 2GB, otherwise the size of the swap file is increased to 2GB. You could change the location of the swap file and its size as per your requirement. After creating the swap we add its entry to /etc/fstab so that it is available even after a reboot.
We use the default swappiness specified in the file /proc/sys/vm/swappiness and we did not find any need to change it.
Unfortunately we could not make the system to recognize and use the swap file without requiring a reboot. If anybody could suggest it in the comments section it would be useful to everybody.
Here is the source code of the utility script "mount-all-instance-storage.sh".
#!/bin/bash # Execute "export DEBUG=1" to debug this script. # Set value to 2 to debug this script and the scripts called within this script. # Set value to 3,4,5 and so on to increase the nesting level of the scripts to be debugged. [[ $DEBUG -gt 0 ]] && set -x; export DEBUG=$(($DEBUG - 1)) memorySizeInMB=$(free -m | grep "Mem:" | awk '{print $2}') swapFileSizeInGB=1 if ([ $memorySizeInMB -lt 2048 ]) then swapFileSizeInGB=2 fi # By specifying mnt2 we are trying to use instance storage if available swapFileDir="/mnt2" swapFileName="swap_file" swapFileLinkDir=/var/cache/swap # This script formats and mounts all available Instance Store devices ##### Variables devices=( ) ##### Functions function add_device() { devices=( "${devices[@]}" $1 ) } function check_device() { if ([ -e /dev/$1 ]) then add_device $1 fi } function check_devices() { check_device sda2 check_device sda3 check_device sdb check_device sdc check_device sdd check_device sde } function print_devices() { for device in "${devices[@]}" do echo Found device $device done } function make_mount_entry() { echo "Formatting device $1 and will be mounted on $2" sudo mkfs -t ext4 $1 > /dev/null mkdir -p $2 if ([ $? -eq 0 ]) then echo "$1 $2 ext4 defaults 0 0" >> /etc/fstab fi } function mount_devices() { for (( i = 0; i < ${#devices[@]}; i++ )) do mountTarget=/mnt if ([ $i -gt 0 ]) then mountTarget=/mnt$(($i+1)) fi make_mount_entry /dev/${devices[$i]} $mountTarget done } function createSwapFile() { local swapFileDir=$1 local swapFileName=$2 local swapFileSizeInGB=$3 local swapFileLinkDir=$4 mkdir -p $swapFileLinkDir mkdir -p $swapFileDir$swapFileLinkDir # Create the swap file of size specified in GB dd if=/dev/zero of=$swapFileDir$swapFileLinkDir/$swapFileName bs=1M count=$((swapFileSizeInGB * 1024)) # Set the directory and file permissions chmod -R 600 $swapFileDir chown -R root:root $swapFileDir # Create a link to the swap file and set the permissions ln -s $swapFileDir$swapFileLinkDir/$swapFileName $swapFileLinkDir/$swapFileName chmod -R 600 $swapFileLinkDir chown -R root:root $swapFileLinkDir # Make the swap file (use force option to suppress warning and to not waste the first page) sudo mkswap -f $swapFileDir$swapFileLinkDir/$swapFileName # Setup fstab to make the changes permanent echo "$swapFileLinkDir/$swapFileName swap swap defaults 0 0" >> /etc/fstab # Turn the swap ON (Still reboot may be required) sudo swapoff -a sudo swapon -a # Turns on the swap specified in fstab # If everything succeeded then forcibly reboot for the swap file to come into effect if ([ $? -eq 0 ]) then echo "Rebooting the machine for the swap file to take effect - $(date)" sudo reboot -f fi } ##### Main # Check if our swap file exists. if ([ -e $swapFileDir$swapFileLinkDir/$swapFileName ]) then echo "Our swap file exists. That means this script has been already run. Nothing to do." exit 0 fi # Try resizing root volume in case if it is not already done if ([ -e /dev/sda1 ]) then sudo resize2fs /dev/sda1 fi # umount ephemeral0 so that we can format it if ([ -e /media/ephemeral0 ]) then sudo umount /media/ephemeral0 fi check_devices print_devices mount_devices # mount all the entries found in /etc/fstab sudo mount -a # Create the swap file after mounting all the devices createSwapFile $swapFileDir $swapFileName $swapFileSizeInGB $swapFileLinkDir