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
const fs = require('fs');const parameters = JSON.parse(fs.readFileSync(0, { encoding: 'utf8' }));
// Get the running Amplify CLI major version numberconst currentCLIMajorVersion = parameters.data.amplify.version.split('.')[0]console.log('Amplify CLI major version: ', currentCLIMajorVersion)
const MINIMUM_MAJOR_AMPLIFY_CLI_VERSION = 5console.log('Minimum required Amplify CLI major version: ', MINIMUM_MAJOR_AMPLIFY_CLI_VERSION)
if (currentCLIMajorVersion < MINIMUM_MAJOR_AMPLIFY_CLI_VERSION) { // Non-zero exit code will stop the Amplify CLI command's execution console.log('Minimum CLI version requirement not met.') process.exit(1)} else { console.log('Minimum CLI version requirement met.') process.exit(0)}
Next, let's run amplify push
:
amplify push
----- 🪝 pre-push execution start -----Amplify CLI major version: 5Minimum required Amplify CLI major version: 5Minimum CLI version requirement met.----- 🪝 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
{ "amplify": { "version": String, "environment": { "envName": String, "projectPath": String, "defaultEditor": String }, "command": String, "subCommand": String, "argv": [ String ] }}
- 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:
{ "message": String, "stack": String}
- 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
const fs = require('fs');const parameters = JSON.parse(fs.readFileSync(0, { encoding: 'utf8' }));console.log(parameters.data, parameters.error)
How to access command hook parameters in Bash
First, install a JSON parser like jq
.
Then, parse the parameters:
parameters=`cat`data=$(jq -r '.data' <<< "$parameters")error=$(jq -r '.error // empty' <<< "$parameters")echo $dataecho $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.
process.exit(1)
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:
{ "extensions": { "py": { "runtime": "python3" }, "js": { "runtime": "~/.nvm/versions/node/v14.17.1/bin/node", "runtime_windows": "node", "runtime_options": ["--require", "./payload.js"], } }}
- 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.
cd amplify/hooksnpm initnpm 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:
backend: phases: preBuild: commands: - cd amplify/hooks - npm installfrontend:...
Dependency directories and files, such as node_modules
, should be added to ignore
in hooks-config.json
.
{ "ignore": ["node_modules", "build"]}
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.
/** * @param data { { amplify: { environment: { envName: string, projectPath: string, defaultEditor: string }, command: string, subCommand: string, argv: string[] } } } * @param error { { message: string, stack: string } } */const hookHandler = async (data, error) => { if (data.amplify.environment.envName === 'prod') { console.log('Executing pre-add-auth hook for prod environment'); } else if (data.amplify.environment.envName === 'dev') { console.log('Executing pre-add-auth hook for dev environment'); }};
const getParameters = async () => { const fs = require("fs"); return JSON.parse(fs.readFileSync(0, { encoding: "utf8" }));};
getParameters() .then((event) => hookHandler(event.data, event.error)) .catch((err) => { console.error(err); process.exitCode = 1; });
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.touch 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....backend:phases:preBuild:commands:- yum install -y python3frontend:... -
Add
python3
tohooks-config.json
and push the change to your source control to trigger the Amplify Hosting build.{"extensions": {"py": { "runtime": "python3" }}} -
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.