appspec_versioned_after_install

Understand and manage your CodeDeploy

CodeDeploy AppSpec AfterInstall Script

Understanding the AfterInstall Lifecycle Hook

The AfterInstall lifecycle hook in AWS CodeDeploy is a critical stage in your deployment process. It executes after the application revision has been copied to the destination instance but before the application is configured and started. This script is essential for tasks like setting up systemd services, creating symbolic links to the latest release, installing dependencies, and ensuring correct file permissions.

Bash Script Breakdown

The following bash script outlines a common setup for a Python application deployment. It leverages several functions to modularize the deployment steps, making it easier to understand and maintain.

Systemd Unit File Configuration

This function ensures that the systemd service file is correctly placed and that systemd is reloaded to recognize the new service definition.

function systemd_unit_file_check() {
  echo "copying systemd unit file in place"
  sudo cp "${CD_INSTALL_TARGET}/configs/python-app.service" /etc/systemd/system/python-app.service
  sudo systemctl daemon-reload
}

Release Versioning and Symlinking

To enable rollbacks and manage different versions of your application, it's common practice to version each deployment. This function removes the old current symlink and creates a new one pointing to the latest deployed version. It also copies necessary configuration and source files to the new release directory.

function remove_symlink(){
  if [ -d /home/snake/app/current ] 
  then
    sudo rm -rf /home/snake/app/current
    sudo mkdir -p /home/snake/app
  fi
}

function symlink_release() {
  sudo mkdir -p "/home/${APP_USER}/app/${DEPLOYMENT_ID}/configs"
  sudo mkdir -p "/home/${APP_USER}/app/${DEPLOYMENT_ID}/dependencies"
  sudo cp ${CD_INSTALL_TARGET}/configs/sample.env /home/${APP_USER}/app/${DEPLOYMENT_ID}/.env
  sudo cp ${CD_INSTALL_TARGET}/configs/hypercorn.toml /home/${APP_USER}/app/${DEPLOYMENT_ID}/configs/hypercorn.toml
  sudo cp ${CD_INSTALL_TARGET}/dependencies/requirements.pip /home/${APP_USER}/app/${DEPLOYMENT_ID}/dependencies/requirements.pip
  sudo cp -r ${CD_INSTALL_TARGET}/src/* /home/${APP_USER}/app/${DEPLOYMENT_ID}/
  sudo ln -s /home/${APP_USER}/app/${DEPLOYMENT_ID} /home/${APP_USER}/app/current
}

Dependency Installation

After the application files are in place, this function installs the required Python dependencies using pip, ensuring your application has all its necessary libraries.

function install_dependencies(){
  sudo python3 -m pip install -r /home/${APP_USER}/app/current/dependencies/requirements.pip
}

Setting File Permissions

Correct file ownership and permissions are crucial for application security and functionality. This function ensures that the application files are owned by the designated application user and group.

function set_permissions() {
  sudo chown -R ${APP_USER}:${APP_GROUP} /home/${APP_USER}/
}

Logging Deployment Status

A simple logging function to indicate that the AfterInstall step has completed successfully.

function log_status(){
  echo "[${DATESTAMP}] after install step completed"
}

Execution Flow

The script then calls these functions in a logical order to perform the deployment tasks:

# copy systemd unit file if not in place
systemd_unit_file_check

# remove symlink and version the installed target
remove_symlink
symlink_release

# install the dependencies
install_dependencies

# set permissions
set_permissions

# log status
log_status

Further Considerations

For more complex deployments, you might need to add steps for database migrations, cache clearing, or other environment-specific configurations within this script. Always ensure your script is idempotent and handles potential errors gracefully.

Refer to the AWS CodeDeploy AppSpec Hooks documentation for more details on lifecycle events.