Skip to content

Instantly share code, notes, and snippets.

@rarylson
Created September 28, 2016 02:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rarylson/9095c56137a60a7fdb7bb2b420f0ad04 to your computer and use it in GitHub Desktop.
Save rarylson/9095c56137a60a7fdb7bb2b420f0ad04 to your computer and use it in GitHub Desktop.
Mount helper for AWS EFS filesystems on AWS EC2 hosts
#!/bin/sh
# vim: et colorcolumn=80
set -e
# Mount helper for mounting AWS EFS filesystems on AWS EC2 hosts
#
# AWS EFS filesystems must be mounted as NFS4 filesystems using URLs (called
# "mount target DNS") that are different for each available zone.
# An EFS URL has the following format:
#
# 'availability-zone'.'file-system-id'.efs.'aws-region'.amazonaws.com
#
# With this helper, it's possible to use URLs that are valid independent of
# the availability zone.
# The new URL format will be:
#
# 'file-system-id'.efs.'aws-region'.amazonaws.com
#
# This helper depends on `mount.nfs4` ('nfs-utils' package) and `ec2metadata`
# ('cloud-guest-utils' package).
#
# See: - http://man7.org/linux/man-pages/man8/mount.8.html#EXTERNAL_HELPERS
# - http://docs.aws.amazon.com/efs/latest/ug/mount-fs-auto-mount- \
# onreboot.html
# Constants
PROGRAM="mount.efs-nfs4"
VERSION="1.0.1"
MOUNT_NFS4="/sbin/mount.nfs4"
EC2METADATA="/usr/bin/ec2metadata"
# Check dependencies
[ -x "$MOUNT_NFS4" ] || exit 1
[ -x "$EC2METADATA" ] || exit 1
# Functions
usage() {
echo "usage: $PROGRAM remotetarget dir [-rvVwfnsh] [-o nfsoptions]"
echo "options: check 'mount.nfs4 -h' for more info"
}
version() {
echo "$PROGRAM: $VERSION"
}
usage_and_exit() {
if [ -n "$1" ]; then
echo "$PROGRAM: $1" >&2
fi
usage >&2
exit 1
}
# Change args order to place positional args at the end
option_args=""
positional_args=""
while [ "$#" -ne 0 ]; do
case "$1" in
-o)
option_args="$option_args $1 $2"
shift 2
;;
-*)
option_args="$option_args $1"
shift
;;
*)
positional_args="$positional_args $1"
shift
;;
esac
done
set -- $option_args $positional_args
# Parse option args
verbose=0
mount_nfs4_options=""
while getopts ":hVrvwfnso:" _param; do
case "$_param" in
h)
usage_and_exit
;;
V)
version
exit
;;
v)
verbose=1
mount_nfs4_options="$mount_nfs4_options -v"
;;
rwfns)
mount_nfs4_options="$mount_nfs4_options -$OPTARG"
;;
o)
mount_nfs4_options="$mount_nfs4_options -o $OPTARG"
;;
:)
usage_and_exit "option requires an argument -- '$OPTARG'"
;;
\?)
usage_and_exit "invalid option -- '$OPTARG'"
;;
esac
done
# Parse positional args
shift "$((OPTIND - 1))"
if [ "$#" -eq 0 ]; then
usage_and_exit "no remote target provided"
elif [ "$#" -eq 1 ]; then
usage_and_exit "no mount point provided"
elif [ "$#" -gt 2 ]; then
usage_and_exit "invalid number of parameters"
fi
efs_remote_target="$1"
mount_point="$2"
# Converting the EFS remote target to a valid NFS4 remote target
if ! output=$("$EC2METADATA" --availability-zone 2>&1); then
usage_and_exit "error while getting ec2 metadata -- $output"
fi
remote_target="${output}.${efs_remote_target}"
# Mount using mount.nfs4
cmd=$(echo "$MOUNT_NFS4 $remote_target $mount_point $mount_nfs4_options" | \
tr -s " ")
[ "$verbose" -eq 1 ] && echo "$PROGRAM: runnning $cmd"
$cmd
@rarylson
Copy link
Author

rarylson commented Sep 28, 2016

Mount helper for AWS EFS filesystems on AWS EC2 hosts

Deprecated: Currently, AWS has the project EFS Mount Helper, a much more mature and stable approach to do the same thing. Prefer the AWS project instead.

AWS EFS filesystems must be mounted as NFS4 filesystems using URLs (called "mount target DNS") that are different for each available zone.

An EFS URL has the following format:

'availability-zone'.'file-system-id'.efs.'aws-region'.amazonaws.com

The problem with this format is that if we create an image of a host and use this image to launch a new instance in a different availability zone, the EFS entries in /etc/fstab must be replaced (manually or via cloud init userdata).

With this helper, it's possible to use URLs that are valid independent of the availability zone.

The new URL format will be:

'file-system-id'.efs.'aws-region'.amazonaws.com

This helper depends on mount.nfs4 ('nfs-utils' package) and ec2metadata ('cloud-guest-utils' package).

See:

Install

To download the script:

wget https://gist.githubusercontent.com/rarylson/9095c56137a60a7fdb7bb2b420f0ad04/raw/259d1dccfd8b172da520658e5994574bbd3fd143/mount.efs-nfs4

To install the dependencies:

apt-get install cloud-guest-utils nfs-utils

And to install the mount helper:

cp mount.efs-nfs4 /sbin/

Usage

Put a line like this in /etc/fstab:

'file-system-id'.efs.'aws-region'.amazonaws.com:/  /path/to/mounting/point  efs-nfs4  nfsvers=4.1  0  0

And the command above will now work:

mount /path/to/mounting/point

@jontaspontas
Copy link

Hi

This is exactly what iam looking for.
It works as supposed when iam doing a "mount -a"
But when i reboot the instance it hangs and i have to mount the volume and remove the fstab entry to get the instance start again.

Any ide why the phenomena happens?

Regards Jonas

@barranteslucas
Copy link

@rarylson: awesome! thank you for this!

I had to change the path of EC2METADATA, which in my case was /opt/aws/bin/ec2-metadata
Also in my case this command:
ec2-metadata --availability-zone
returns something like this: placement: us-east-1c
So I had to add a cut to the script just to get the name of the availability-zone
ec2-metadata --availability-zone|cut -d " " -f 2

@jontaspontas: Maybe this helps.

@jontaspontas
Copy link

Hi @rarylson

I solved it by adding this to my mount point in /etc/fstab "efs-nfs4 nfsvers=4.1,nobootwait,nofail 0 0"
And then adding in "mount -a" in /etc/rc.local

So now the servers boots and mounts as supposed.

/J

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment