How do I mount an Amazon EFS volume to an application directory in an Elastic Beanstalk environment?

Last updated: 2020-03-18

I want to mount an Amazon Elastic File System (Amazon EFS) volume to an application directory in an AWS Elastic Beanstalk environment.

Short Description

The following resolution uses the PHP solution stack as an example.

If you're using another solution stack, follow the same steps, but choose the correct application directory and staging directory for your solution stack from the following options:

-----------------------------------------------------
Solution stack             Application directory                    Staging directory
Nodejs                     /var/app/current                         /tmp/deployment/application
PHP                        /var/app/current                         /var/app/ondeck
Ruby (Passenger)           /var/app/current                         /var/app/ondeck
Ruby (Puma)                /var/app/current                         /var/app/ondeck
Java with Tomcat           /usr/share/tomcat*/webapps/ROOT          /tmp/deployment/application/ROOT
Java SE                    /var/app/current                         /var/app/staging
Python                     /opt/python/current/app                  /opt/python/ondeck/app
Go                         /var/app/current                         /var/app/staging
Single Container Docker    /var/app/current                         /var/app/staging
Multi-Container Docker     /var/app/current                         /var/app/staging
-----------------------------------------------------

Important: You can't mount an Amazon EFS volume directly to the application directory, because the contents of /var/app/current are moved to /var/app/current.old whenever an Elastic Beanstalk application is deployed. The current deployed source bundle is moved to the application directory. If you mount the Amazon EFS volume to /var/app/current, then that volume is moved to /var/app/current.old after the deployment is completed. For example, see the following eb-activity.log output:

===============================
[2020-02-12T02:28:18.237Z] INFO  [3159]  - [Application deployment Sample Application@1/StartupStage1/AppDeployEnactHook/01_flip.sh] : Starting activity...
[2020-02-12T02:28:18.431Z] INFO  [3159]  - [Application deployment Sample Application@1/StartupStage1/AppDeployEnactHook/01_flip.sh] : Completed activity. Result:
  ++ /opt/elasticbeanstalk/bin/get-config container -k app_staging_dir
  + EB_APP_STAGING_DIR=/var/app/ondeck
  ++ /opt/elasticbeanstalk/bin/get-config container -k app_deploy_dir
  + EB_APP_DEPLOY_DIR=/var/app/current
  + '[' -d /var/app/current ']'
  + mv /var/app/current /var/app/current.old
  + mv /var/app/ondeck /var/app/current
  + nohup rm -rf /var/app/current.old
===============================

Resolution

1.    Confirm that your source bundle is unzipped in the staging directory. See the following example eb-activity.log output:

===============================
[2020-02-12T02:28:16.336Z] INFO  [3159]  - [Application deployment Sample Application@1/StartupStage0/AppDeployPreHook/01_unzip.sh] : Starting activity...
[2020-02-12T02:28:16.631Z] INFO  [3159]  - [Application deployment Sample Application@1/StartupStage0/AppDeployPreHook/01_unzip.sh] : Completed activity. Result:
  ++ /opt/elasticbeanstalk/bin/get-config container -k app_user
  + EB_APP_USER=webapp
  ++ /opt/elasticbeanstalk/bin/get-config container -k app_staging_dir
  + EB_APP_STAGING_DIR=/var/app/ondeck
  ++ /opt/elasticbeanstalk/bin/get-config container -k source_bundle
  + EB_SOURCE_BUNDLE=/opt/elasticbeanstalk/deploy/appsource/source_bundle
  + rm -rf /var/app/ondeck
  + /usr/bin/unzip -d /var/app/ondeck /opt/elasticbeanstalk/deploy/appsource/source_bundle
  Archive:  /opt/elasticbeanstalk/deploy/appsource/source_bundle
     creating: /var/app/ondeck/.ebextensions/
    inflating: /var/app/ondeck/.ebextensions/logging.config  
    inflating: /var/app/ondeck/scheduled.php  
    inflating: /var/app/ondeck/index.php  
    inflating: /var/app/ondeck/cron.yaml  
    inflating: /var/app/ondeck/styles.css  
   extracting: /var/app/ondeck/logo_aws_reduced.gif  
  + chown -R webapp:webapp /var/app/ondeck
  + chmod 775 /var/app/ondeck
===============================

Note: All the appdeploy pre hooks in /opt/elasticbeanstalk/hooks/appdeploy/pre/ and .ebextensions are executed in the staging directory.

2.    Create a .ebextensions folder in the root directory of the source bundle.

3.    Add a formatted configuration file (YAML or JSON) to your directory to mount an Amazon EFS volume to a specific directory (for example, /efs).

4.    To mount your Amazon EFS volume to an application directory, complete the steps in either of the following Option 1 or Option 2 sections.

(Option 1) Create a symlink to a staging directory before the flip script moves the contents of the staging directory to the application directory

When appdeploy enact hooks are executed during a deployment in an Elastic Beanstalk environment, the contents of the staging directory are moved to the application directory. For example, in a PHP solution, the flip.sh script (first script of AppDeployEnactHook in /opt/elasticbeanstalk/hooks/appdeploy/enact/) moves the contents of the staging directory to the application directory.

To create a symlink from /efs that points to the staging directory, use container_commands to create a .config file in your .ebextensions folder. See the following example:

container_commands:
  01_symlink:
    command: ln -s /efs /var/app/ondeck/

Note: After deployment, the symlink points to the application directory.

(Option 2) Create a symlink to an application directory after the flip script moves the contents of the staging directory to the application directory

To create a symlink that points to the application directory, create a .config file in your .ebextensions folder. See the following example:

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/post/01_create_symlink.sh" :
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/bin/sh
      ln -s /efs /var/app/current/

Note: The preceding .config file uses the files key to create a .sh script file in the appdeploy post hooks. The .sh script creates a symlink in the application folder after the flip script moves the contents of the staging directory to the application directory.


Did this article help you?

Anything we could improve?


Need more help?