Setup and Mount AWS EFS on Linux EC2 Instance

From Bonus Bits
Jump to: navigation, search

Purpose

This article gives the steps to mount an Amazon Web Service Elastic File System on CentOS or RHEL 6 EC2 Instance. Could be used to store shared web content for like Wordpress or Mediawiki. Then have multiple web servers share the NFS share in an autoscaling group.

One thing to note is that there is a different target link per availability zone. So in our CloudFormation template we need a little magic to set the fstab correctly.


Create Security Group

Create a Security Group to allow EC2 Instance mount the EFS (NFS).

  1. Login to AWS web console
  2. Open EC2 | Security Groups
  3. Select Create New Security Group
  4. Enter a name and description
  5. Select VPC
  6. Select NFS and Anywhere for inbound role
  7. Select Create
  8. Copy the Security Group Group ID of the new Security Group
  9. Edit the new Security Group
  10. Change the inbound anywhere to custom
  11. Paste in the Security Group ID
    1. This means anything assigned to the Security Group will have access to the EFS


Create EFS

  1. Login to AWS web console
  2. Select Elastic File System
  3. Select Create file system
  4. Select VPC
  5. Select Private subnets that the EC2 Instances are on for the availability zones
  6. Remove the default security group from each availability zone
  7. Paste or start typing the EFS Security Group ID in for each availability zone
  8. Select Next Step
  9. Add Name Tag and any others
  10. Select Generic or Max I/O type
  11. Select Next Step
  12. Select Create file system


Install Dependencies

CentOS/RHEL/Amazon

sudo yum install -y nfs-utils

Ubuntu

sudo apt-get install nfs-common


Get DNS URL

Get the DNS NFS Mount Point for the Availability Zone our EC2 instance is in.

  1. Open EFS Web Console
  2. Select the newly created EFS
  3. Click on the DNS Names hyperlink on bottom left
Aws efs show dns link


Manual Mount Test

mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 $(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone).fs-00000000.efs.us-west-2.amazonaws.com:/ /local/mount/path


Setup Auto Mount (fstab)

  1. Edit /etc/fstab
    vim /etc/fstab
    
  2. Add the following
    <mount-target-DNS>:/ <efs-mount-point> nfs4 nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 0 0
    1. Example
      us-west-2b.fs-3754efa1.efs.us-west-2.amazonaws.com:/ /var/www/html/wordpress/wp-content nfs4 nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 0 0


Mount

After adding the entries to the fstab then run one of the following commands to mount and test functionality.

  1. Remount all in fstab
    mount -a
    
  2. Remount just nfs mounts in fstab
    mount -a -t nfs4
    


Cloud Init Example

As I mentioned earlier, EFS has separate mount hostnames for each availability zone. So if we are using CloudFormation to setup our web servers then we'll need to add some script logic to update the fstab appropriately.

Add this to the Userdata section of the Launch Configuration or Instance Resource in the CloudFormation Template.

Example 1

#cloud-config
package_upgrade: true
packages:
- nfs-utils
runcmd:
- mkdir -p /path/to/mount
- chown ec2-user:ec2-user /path/to/mount
- echo "$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone).fs-00000000.efs.aws-region.amazonaws.com:/ /path/to/mount nfs4 nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 0 0" >> /etc/fstab
- mount -a -t nfs4

Example 2

  1. Parameters Section
    Or the information could be added to the mapping section if you want the template to be static
    # EFS Mount  
    EfsMountPoint1:
      Type: String
      Default: /path/to/mount1
    EfsMountPoint2:
      Type: String
      Default: /path/to/mount2
    EfsFileSystemId1:
      Type: String
      Default: fs-00000000
    EfsFileSystemId2:
      Type: String
      Default: fs-00000000
    EfsMountOwner1:
      Type: String
      Default: ec2-user
    EfsMountOwner2:
      Type: String
      Default: ec2-user
    
  2. LaunchConfiguration or Instance Section UserData: Fn::Base64:
    UserData:
      Fn::Base64:
        !Sub |
          #!/bin/bash -xe
          yum update -y
          yum install -y aws-cfn-bootstrap awscli nfs-utils cloud-init
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource MasterInstances --region ${AWS::Region} -c ascending
          /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource MasterAutoScalingGroup --region ${AWS::Region}
          mkdir -p ${EfsMountPoint1}
          mkdir -p ${EfsMountPoint2}
          chown ${EfsMountOwner1}:${EfsMountOwner1} ${EfsMountPoint1}
          chown ${EfsMountOwner2}:${EfsMountOwner2} ${EfsMountPoint2}
          echo "$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone).${EfsFileSystemId1}.efs.aws-region.amazonaws.com:/ ${EfsMountPoint1} nfs4 nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 0 0" >> /etc/fstab
          echo "$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone).${EfsFileSystemId2}.efs.aws-region.amazonaws.com:/ ${EfsMountPoint2} nfs4 nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 0 0" >> /etc/fstab
          mount -a -t nfs4
    

Related Articles


Sources