Command hooks
Use Command Hooks to execute custom scripts before, during, and after Amplify CLI commands (“amplify push”, “amplify api gql-compile”, and more). This allows you to extend Amplify’s best-practice defaults to meet your organization’s specific security guidelines and operational requirements.
Adding a command hook
Place your custom scripts in the amplify/hooks
directory and set the script file name to the desired command with a pre or post designation. For example post-add-function.js
will execute the script after amplify add function
. For more information about the script naming convention, see How to name command hook scripts.
For this example, let's create a hook to ensure that a minimum major Amplify CLI version is used before deployment (amplify push
).
Let's add pre-push.js
in the amplify/hooks
directory with the following contents. Note: You need to create a amplify/hooks
folder if your Amplify project was created prior to Amplify CLI version 5.5.0
1const fs = require('fs');2const parameters = JSON.parse(fs.readFileSync(0, { encoding: 'utf8' }));3
4// Get the running Amplify CLI major version number5const currentCLIMajorVersion = parameters.data.amplify.version.split('.')[0]6console.log('Amplify CLI major version: ', currentCLIMajorVersion)7
8const MINIMUM_MAJOR_AMPLIFY_CLI_VERSION = 59console.log('Minimum required Amplify CLI major version: ', MINIMUM_MAJOR_AMPLIFY_CLI_VERSION)10
11if (currentCLIMajorVersion < MINIMUM_MAJOR_AMPLIFY_CLI_VERSION) {12 // Non-zero exit code will stop the Amplify CLI command's execution13 console.log('Minimum CLI version requirement not met.')14 process.exit(1)15} else {16 console.log('Minimum CLI version requirement met.')17 process.exit(0)18}
Next, let's run amplify push
:
1amplify push
1----- 🪝 pre-push execution start -----2Amplify CLI major version: 53Minimum required Amplify CLI major version: 54Minimum CLI version requirement met.5----- 🪝 pre-push execution end -----
How to name command hook scripts
To hook into a command, the script file in the amplify/hooks
directory should be named with the following naming convention:
pre|post-<command>[-<sub-command>].extension
command
(required) - Amplify command.extension
(required) - by default.js
and.sh
are mapped to Node.js and Bash. To support more extensions or scripting runtimes, see Adding a custom scripting runtime.sub-command
(optional) - Amplify sub-command. Can be used to increase hook specificity. Example:pre-add-auth
andpre-mock-api
.
The following is an exhaustive list of all commands along with their subcommands that are supported by Amplify CLI:
commands | sub-commands (optional) |
---|---|
add | all categories (api , auth , etc.)codegen env |
update | all categories (api , auth , etc.)env |
remove | all categories (api , auth , etc.)env |
push | analytics , api , auth , function , hosting , interactions , storage , xr |
pull | env |
publish | - |
delete | - |
checkout | env |
list | env |
get | env |
mock | api , storage , function |
build | function |
status | notifications |
import | auth , storage , env |
gqlcompile | api |
addgraphqldatasource | api |
statements | codegen |
types | codegen |
Note: Multiple hook scripts with the same filename are not allowed
Access parameters in hook scripts
Command hooks receive two parameters, data
and error
. Amplify CLI passes parameters to hook scripts as a JSON string through standard input.
data parameter structure
1{2 "amplify": {3 "version": String,4 "environment": {5 "envName": String,6 "projectPath": String,7 "defaultEditor": String8 },9 "command": String,10 "subCommand": String,11 "argv": [ String ]12 }13}
- amplify
- version - current Amplify CLI version
- environment - current Amplify environment
- envName - current Amplify environment name
- projectPath - path to current Amplify project
- defaultEditor - chosen editor in init step. Example
vscode
- command - hooked Amplify CLI command. Example:
push
- subCommand - hooked Amplify CLI subcommand or plugin. Example
auth
,env
. - argv - list containing the arguments passed to Amplify CLI through the command line
error parameter structure
error is undefined
if no error is emitted. Otherwise, it has the following structure:
1{2 "message": String,3 "stack": String4}
- message - the error message emitted by Amplify CLI
- stack - the error stack emitted by Amplify CLI
How to access command hook parameters in Node.js
1const fs = require('fs');2const parameters = JSON.parse(fs.readFileSync(0, { encoding: 'utf8' }));3console.log(parameters.data, parameters.error)
How to access command hook parameters in Bash
First, install a JSON parser like jq
.
Then, parse the parameters:
1parameters=`cat`2data=$(jq -r '.data' <<< "$parameters")3error=$(jq -r '.error // empty' <<< "$parameters")4echo $data5echo $error
How to conditionally stop an Amplify CLI command execution
To stop the execution of Amplify CLI, the hook scripts can exit with a non-zero exit code.
1process.exit(1)
Advanced command hook configurations
You can optionally add hooks-config.json
in amplify/hooks
to configure custom scripting runtimes or manage external dependencies.
Adding a custom scripting runtime
By default, Node.js and Bash are supported. To support additional runtimes, add extensions
to the hooks-config.json
file in the amplify/hooks
folder.
An example showcasing python runtime support and different runtime settings based on operating system:
1{2 "extensions": {3 "py": {4 "runtime": "python3"5 },6 "js": {7 "runtime": "~/.nvm/versions/node/v14.17.1/bin/node",8 "runtime_windows": "node",9 "runtime_options": ["--require", "./payload.js"],10 }11 }12}
- The keys in the
extensions
( js, py ) are values that will be used asextension
in the naming convention used when naming the hook scripts. runtime
(required) - symlink (node
,python
,bash
) or path to executable (~/.nvm/versions/node/v14.17.1/bin/node
).runtime_windows
(optional) - windows specific symlink or path to executable.runtime_options
(optional) - Array of cli options to be passed to command hooks specific to runtime.
Managing third-party dependencies
Packages from external package managers like npm
can be used in command hooks scripts. In this example, you'll install axios
as a dependency for your Node.js hooks.
First, go to the hooks folder and install the axios
dependency.
1cd amplify/hooks2npm init3npm install axios
Note: If you use command hooks with Amplify Hosting CI/CD pipelines, you also need to have a preBuild
step configured to install the hook dependencies:
1backend:2 phases:3 preBuild:4 commands:5 - cd amplify/hooks6 - npm install7frontend:8...
Dependency directories and files, such as node_modules
, should be added to ignore
in hooks-config.json
.
1{2 "ignore": ["node_modules", "build"]3}
Note: All entries in ignore
should follow the .gitignore specification.
You can now use axios
in your hook scripts placed in the amplify/hooks
directory.
Executing different logic based on environment
When using multi-environment setup you can customize command hooks logic based on data.amplify.environment.envName
parameter.
1/**2 * @param data { { amplify: { environment: { envName: string, projectPath: string, defaultEditor: string }, command: string, subCommand: string, argv: string[] } } }3 * @param error { { message: string, stack: string } }4 */5const hookHandler = async (data, error) => {6 if (data.amplify.environment.envName === 'prod') {7 console.log('Executing pre-add-auth hook for prod environment');8 } else if (data.amplify.environment.envName === 'dev') {9 console.log('Executing pre-add-auth hook for dev environment');10 }11};12
13const getParameters = async () => {14 const fs = require("fs");15 return JSON.parse(fs.readFileSync(0, { encoding: "utf8" }));16};17
18getParameters()19 .then((event) => hookHandler(event.data, event.error))20 .catch((err) => {21 console.error(err);22 process.exitCode = 1;23 });
Using command hooks in Amplify's CI/CD pipeline
Command hooks are executed when CI/CD builds are triggered on Amplify Hosting. To execute hook scripts in the Amplify Hosting, add the hook scripts to the amplify/hooks
directory and commit them to your source control.
By default only pre-push
and post-push
hooks will be executed on builds in Amplify Hosting.
To use scripting runtimes other than Node.js and Bash, see Adding a custom scripting runtime and also update the Build Settings in Amplify Hosting to include the runtime executable.
In this example, you'll add a python
hook script running in the Amplify Hosting's CI/CD pipeline:
-
Add the python hook script along with
hooks-config.json
to the hooks directory.1touch amplify/hooks/hooks-config.json -
Navigate to your app in the Amplify Hosting and select App settings > Build settings to update the
preBuild
phase to install python.1...2backend:3phases:4 preBuild:5 commands:6 - yum install -y python37frontend:8... -
Add
python3
tohooks-config.json
and push the change to your source control to trigger the Amplify Hosting build.1{2 "extensions": {3 "py": { "runtime": "python3" }4 }5} -
You’re all set! The python command hooks will be executed in new CI/CD builds.
Command hook limitations with Amplify Studio
Command Hooks are not executed when updating a backend via Amplify Studio.