• 0.11

Mount EBS Volume to Amazon Elastic Beanstalk Environment

Sometimes it is necessary to use disc storage in your Elastic Beanstalk environment. And you need this storage to be persistent between environment terminations. The best option is to attach an EBS volume to a running EC2 instance on boot up (it will be automatically detached on termination of the instance). Full workflow is as following:

  • Check whether the EBS volume is already attached to the current EC2 instance (if it is, ignore the rest of the workflow);
  • Attach the given EBS volume to the current instance
  • Create a new directory
  • Mount the device to the directory
  • Change permissions of the directory to enable Tomcat access to it

Let's configure this workflow using ebextensions (read more about them here). Create a ebs-volume.config file in src/main/ebextensions:

commands:
  01-attach-volume:
    command: |
      export JAVA_HOME=/usr/lib/jvm/jre && \
      export EC2_HOME=/opt/aws/apitools/ec2 && \
      export IN_USE=$(/opt/aws/bin/ec2-describe-volumes --hide-tags \
        --aws-access-key ${aws.key} \
        --aws-secret-key ${aws.secret} \
        ${ebs.volume} | grep "in-use") && \
      if [ -z "${IN_USE}" ]; then
        /opt/aws/bin/ec2-attach-volume ${ebs.volume} \
          -i $(/opt/aws/bin/ec2-metadata --instance-id | cut -c14-) \
          -d /dev/sdf \
          --aws-access-key ${aws.key} \
          --aws-secret-key ${aws.secret} &&
        mkdir -p /mnt/ebs-volume &&
        sleep 30 && \
        mount /dev/xvdf /mnt/ebs-volume && \
        chown -R tomcat.tomcat /mnt/ebs-volume
      fi

As you see, this ebs-volume.config file doesn't contain real security data like AWS key, secret key, or volume name. This information has to be provided to Maven during build time in your settings.xml file (for example):

<settings>
  <profile>
    <id>production</id>
    <properties>
      <ebs.volume>vol-8a8a8a8a</ebs.volume>
      <aws.key>AKIA3G4DFXFQJI8U6CQA</aws.key>
      <aws.secret>Z9ISuYTdV7kIV50YWT3uaycJ4fw+3uQ+XtEVIV1t</aws.secret>
    </properties>
  </profile>
</settings>

During packaging, as suggested in here, the properties will be substituted by maven-war-plugin.

That's it. On every reboot (or restart) of the EC2 instance your EBS volume will be attached to it. In this example we assumed that your Elastic Beanstalk application has only one environment (and never scale up). For bigger cases with many environments in one application you probably have to use some service-oriented solutions, like database servers, search engine servers, etc.