How To Use the Appdeploy Filesystem Hook

[rt_reading_time label=”Read Time:” postfix=”minutes” postfix_singular=”minute”]

AWS How-To Guide

Working with Filesystem Hooks in Amazon Elastic Beanstalk

It seems as if the appdeploy filesystem hooks go largely unnoticed with Amazon Elastic Beanstalk, so I set to find out more about this system and how it can be used more effectively.

Here is an example of a tree output from a base PHP AMI. Many of these directories and file names are well-named so we can take educated guesses as to what they do:

 $ tree /opt/elasticbeanstalk/hooks/
 /opt/elasticbeanstalk/hooks/
 ├── appdeploy
 │   ├── enact
 │   │   ├── 01_flip.sh
 │   │   └── 99_reload_app_server.sh
 │   ├── post
 │   │   └── 01_monitor_httpd_pid.sh
 │   └── pre
 │       ├── 01_unzip.sh
 │       ├── 02_setup_envvars.sh
 │       ├── 05_configure_php.sh
 │       ├── 10_composer_install.sh
 │       └── 12_update_permissions.sh
 ├── configdeploy
 │   ├── enact
 │   │   └── 99_reload_app_server.sh
 │   ├── post
 │   └── pre
 │       ├── 10_setup_envvars.sh
 │       └── 20_configure_php.sh
 ├── postinit
 ├── preinit
 │   ├── 01_setup_envvars.sh
 │   ├── 02_web_user.sh
 │   ├── 03_packages.sh
 │   ├── 04_configure_php.sh
 │   ├── 05_composer.sh
 │   ├── 10_layout.sh
 │   ├── 11_logging.sh
 │   ├── 22_pear.sh
 │   ├── 23_apache.sh
 │   └── 30_permissions.sh
 └── restartappserver
    ├── enact
    │   └── 01_restart.sh
    ├── post
    └── pre
        └── 10_configure_php.sh

appdeploy/post

In this blog post, we will focus on the appdeploy directory. We use appdeploy filesystem hook, especially the post directory, when we want to fire off a script that takes place after the application has been deployed.

For example, we want to install a custom varnish daemon into our Beanstalk server with a custom .ebextensions/xxx.config file:

$commands: 
 create_post_dir: 
  command: "mkdir -p /opt/elasticbeanstalk/hooks/
appdeploy/post" 
  ignoreErrors: true 
files: 
  "/opt/elasticbeanstalk/hooks/appdeploy/post/
varnish_script.sh": 
   mode: "000770" 
   owner: root 
   group: root 
   content: | #!/bin/bash echo 
"--------Starting Varnish Script------------" 
   ## change this to "restart" to flush cache 
on every deploy 
   start_cmd="reload" 
   if ! which varnishd >/dev/null 
2 1 ; then 
     echo "Installing Varnish" 
     rpm --nosignature -i  
https://repo.varnish-cache.org/redhat/
varnish-4.1.el6.rpm 
   yum install -y varnish  
        --disablerepo=amzn-updates  
        --disablerepo=amzn-main  
        --enablerepo=epel 
      start_cmd="start" 
    fi 
    echo "Starting Varnish" 
    service varnish ${start_cmd} 
    service varnishncsa ${start_cmd} 
    rm -- "$0"

Notice how we use commands to make sure the directory is there? We have found on some older EB AMIs the directory may not exist, so we create it while ignoring errors (the -p should ignore the error, but we add the extra ignoreErrors just to be complete).

When the application is unzipped, the /opt/elasticbeanstalk/hooks/appdeploy/post/varnish_script.sh file is dropped into place but not executed when a command would be. The script is set to be executable and Elastic Beanstalk handles the rest – it will be executed after the https server has been restarted and after  post/01_monitor_httpd_pid.sh is ran.

Also, notice the rm -- "$0" at the end of this script. That tells the script to delete itself. If you do not remove the script it will be left over in subsequent installations – especially if you remove it from your .ebextensions/xxx.config file. If you do not remove the script on every run (or at least manage your system appropriately) you will have inconsistent systems and unintended consequences.

appdeploy/pre

Notice that the 01_unzip.sh is as ‘early’ as you can get into the hooks. For example, this will run just after unzipping:

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/pre/02-aa.sh":
    mode: "000770"
    owner: root
    group: root
    content: |
      #!/bin/bash
      echo "ran 02-aa" > /tmp/02-aa.txt

You will end up with a /tmp/02-aa.txt file because of the last line where we echo "ran 02-aa" into the temp file. Notice how our script ran immediately after the 01_unzip.sh script:

 $ tree /opt/elasticbeanstalk/hooks/ | head -10 
 /opt/elasticbeanstalk/hooks/
  ├── appdeploy │
  ├── enact
  │ │ ├── 01_flip.sh
  │ │ └── 99_reload_app_server.sh
  │ ├── post
  │ │ └── 01_monitor_httpd_pid.sh
  │ └── pre
  │ ├── 01_unzip.sh
  │ ├── 02-aa.sh
  $ cat /tmp/02-aa.txt 
  ran 02-aa 

appdeploy/enact

If you wanted to do something with the system after the /var/app/current directory was swapped around but before the webserver was restarted, you would drop in a file between the numbers 01 and 99 (non-inclusive). For example, you may need to have a shell script that works with /var/app/current before apache is reloaded.

All Done Using the Appdeploy Filesystem Hook

Feel free to dive in and create your own scripts to figure out exactly when they ran. It is easiest to watch /var/log/eb-activity.log for when things are done as it contains some very good logging about what scripts are triggering and in which order.

Happy scripting!

Hidden layer

Share on linkedin
Share on twitter
Share on facebook
Share on email

Onica Insights

Stay up to date with the latest perspectives, tips, and news directly to your inbox.

Explore More Cloud Insights from Onica

Blogs

The latest perspectives on navigating an ever-changing cloud landscape

Case Studies

Explore how our customers are driving cloud innovation in their industries

Videos

Watch an on-demand library of cloud tutorials, tips and tricks

Publications

Learn how to succeed in the cloud with deep-dives into pressing cloud topics