Technical Blog


Technical and Product News and Insights from Rackspace

How to use the Appdeploy Filesystem hook


Originally published in Apr 2017, at Onica.com/blog

It seems as if the Appdeploy Filesystem hooks go largely unnoticed with Amazon Elastic Beanstalkยฎ, so we set to find out more about this system and how to use it more effectively.

Working with Filesystem hooks in Amazon Elastic Beanstalk

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 make educated guesses about 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

This blog post focuses on the appdeploy directory. We use the Appdeploy Filesystem hook, especially the post directory, when we want to fire off a script that takes place after the application deploys.

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 that the directory might not exist on some older EB AMIs, so we create it while ignoring errorsโ€”the -p should ignore the error, but we add the extra ignoreErrors just to be complete.

When you unzip the application, the /opt/elasticbeanstalk/hooks/appdeploy/post/varnish_script.sh file drops into place but doesn’t execute when a command would be. The script is set to be executable, and Elastic Beanstalk handles the rest. The HTTPS server restarts, executes the script, and runs post/01_monitor_httpd_pid.sh.

Also, notice the rm -- "$0" at the end of this script. That tells the script to delete itself. If you don’t remove the script, it is 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 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 runs 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 end up with a /tmp/02-aa.txt file because of the last line where we echoed 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 want to do something with the system after swapping around the /var/app/current directory but before restarting the web server, drop in a file between01 and 99 (non-inclusive). For example, you might need to have a shell script that works with /var/app/current before Apache reloads.

All done using the Appdeploy Filesystem hook

Feel free to dive in and create your scripts to figure out exactly when they run. It is easiest to watch /var/log/eb-activity.log to see when things complete. This log contains some very good logging about what scripts trigger in which order.

Learn more about Rackspace AWS services.

Use the Feedback tab to make any comments or ask questions. You can also click Sales Chat to chat now and start the conversation.

post avatar
Matt Charoenrath

Marketing leader experienced in growing brands while scaling and modernizing marketing organizations through a balance of creativity, process, and technology to captivate audiences and achieve results.

Share this information: