Adding a deploy hook
Deploy hooks are scripts that allow you to automate actions at various points during the deployment process for your applications. This allows you to customise your deployments by, for example, installing software packages or upgrading components.
We will be looking at some simple examples in this tutorial, but for a deeper understanding please read the full reference guide.
What you’ll need
Before you start, please check you have the following:
- A Cloud 66 Account — If you don’t already have one, sign up for a Cloud 66 account. There is a free community plan and you’ll get full unlimited access to all products free for 14 days.
- An existing application set up in Maestro — To make the most of this tutorial you need to have an app already set up in Maestro. Follow our Getting Started guide if you’re not sure how to do this.
Creating a deploy hook
Deploy hooks can be added to an application via the Dashboard. Like most other configuration templates in Maestro, Deploy hooks are YAML-formatted.
A deploy hook needs, at a minimum:
- a hook point i.e where in the deployment process the hook must be invoked
- a hook type - either a
commandor one of the two
- a target - defines which type(s) of servers will use this hook
- a hook field - the actual command or script being invoked
So, to write a deploy hook we must:
- Choose your environment - eg. example production, development, staging and so on.
- Define your hook point - eg. first_thing
- Define your hook type i.e. snippet, command or script.
- Define your target
- Define the hook fields you require.
Writing the YAML
The simplest kind of hook is the
command. This simply executes a command in the operating system as part of the deployment process.
We’re going to add the hook below to our demo application:
production: # Environment first_thing: # Hook point - command: apt-get install nmap -y # Hook type target: any # Hook fields execute: true
This hook will install the
nmap package on our server during the deployment process. We’ve added the
execute hook field because we want the command to be executed during deployment. If you don’t add this field, the code you’re calling won’t be executed.
When automating the installation of packages, remember to use the -y flag to answer yes to all prompts.
Adding the hook to your app
Hooks can be added to an application in one of two ways:
- Via the Configuration Files section of the Dashboard.
- By pushing a file to the CustomConfig git repo for the application
We’re going to use the first method in our tutorial because it’s quicker and simpler.
To add the hook:
- Open the Application Overview from your Dashboard
- Click on Configuration files in the Application panel on the right of the screen
- Click on the Deploy Hooks tab at the top of the Configure Services
- Copy and paste the example code above into the text area
- Click Preview and then check there are no errors in the parsed template file
- Add a commit message and click Commit to server
Deploying and testing
Now that our hook is in place, we need to re-deploy our application to see it in action.
- Navigate back to Application Overview
- Click the Build / Deploy button
- Watch the deploy log and you will see the “first _thing” deploy hook being called as part of the process
The best way to check whether your change has been applied to your server is to access it directly using SSH. Cloud 66 Toolbelt is the quickest way to do this.
Once you are connected to your server, type
nmap into the terminal. If your deploy hook was set up correctly, you will see the usage / help text for the nmap utility. If not, Ubuntu will complain that nmap is not installed.
Understanding hook points and ordering
Hook points are used to define the point in your deployment process at which a hook should be invoked. This is obviously critical when there are tight dependencies between the components of your application (i.e. one component relies on another component being installed first), but it is also important in terms of what actions and commands are possible. For example, running tasks against a database before the database server is installed will not work!
It’s important to understand the order in which hook points will occur in the flow of deployment. The simplified deployment process below shows where each deploy hook is triggered. Hooks are marked in bold italic. Some hooks have several possible values (
z). Click on the hook name to see a list of available options:
Deployment process (simplified)
- Server is fired up
- Operating system and standard system components installed → first_thing
- before_agent → Cloud 66 Agent is installed → after_agent
- before_x → Database is installed → after_x
- before_y → Database replication is configured → after_y
- before_data_mount → Data is mounted → after_data_mount (GlusterFS specific)
- custom_server (runs on custom servers only)
- before_nginx → NGINX is installed → after_nginx
- before_docker → Docker is installed after_docker
database & storage engine installation,
application framework installationrespectively.
- The last_thing hook runs only when ALL servers reach that point
Snippets are pre-defined hook scripts hosted in a Cloud 66 repository. These are commonly used scripts that we provide for ease of use. Like scripts (see below) these snippets are written in
For example the Cloud 66 ImageMagick snippet installs ImageMagick, the popular image processing application. You can use the example below to test it in your demo app:
production: # Environment first_thing: # Hook point - snippet: cloud66/imagemagick # Hook type target: any # Hook fields execute: true
You can test this in the same way as you did with the
command hook above.
Using inline scripts
Script hooks allow you to add your own logic to a deploy hook, either by calling a separate file using
source or by using
inline. Both of methods use
bash scripting (as do snippets above).
The hook below will create an arbitrary log file in /tmp using a simple inline script:
first_thing: # Hook point - inline: | #!/usr/bin/env bash echo "script called!" >> /tmp/inline_script.log target: any execute: true apply_during: all owner: root:root