appspec_versioned_before_install

Learn how to prepare your CodeDeploy environment with a

CodeDeploy AppSpec Before Install Script

This document details a bash script designed for the before_install hook in an AWS CodeDeploy AppSpec file. This script is crucial for preparing the environment before the main application deployment begins, ensuring a clean and correctly configured setup.

Understanding the Before Install Script

The before_install phase in CodeDeploy is executed on the instance before the application is copied to the destination. It's the ideal place to perform system-level configurations, such as creating necessary users and groups, setting up directories, and backing up existing application data.

Script Breakdown and Functionality

#!/usr/bin/env bash
set -ex

# global variables
APP_USER=snake
APP_GROUP=snake
DATESTAMP="$(date +%F)"
TIMESTAMP="$(date +%s)"

function detect_previous_version(){
  if [ -f /opt/codedeploy-agent/deployment-root/${DEPLOYMENT_GROUP_ID}/.version ]
  then
    PREVIOUS_VERSION="$(cat /opt/codedeploy-agent/deployment-root/${DEPLOYMENT_GROUP_ID}/.version)"
  else
    PREVIOUS_VERSION="initial"
  fi
}

function debug_env(){
  echo "LIFECYCLE_EVENT=${LIFECYCLE_EVENT}" > /tmp/codedeploy.env
  echo "DEPLOYMENT_ID=${DEPLOYMENT_ID}" >> /tmp/codedeploy.env
  echo "APPLICATION_NAME=${APPLICATION_NAME}" >> /tmp/codedeploy.env
  echo "DEPLOYMENT_GROUP_NAME=${DEPLOYMENT_GROUP_NAME}" >> /tmp/codedeploy.env
  echo "DEPLOYMENT_GROUP_ID=${DEPLOYMENT_GROUP_ID}" >> /tmp/codedeploy.env
}

# functions
function user_and_group_check(){
  id -u ${APP_USER} > /dev/null && EXIT_CODE=${?} || EXIT_CODE=${?}
  if [ ${EXIT_CODE} == 1 ]
    then
      sudo groupadd --gid 1002 ${APP_GROUP}
      sudo useradd --create-home --gid 1002 --shell /bin/bash ${APP_USER}
  fi
}

function create_backup() {
  sudo mkdir -p "/opt/backups/${DATESTAMP}"
  # on initial deploy skip backups
  if [ -d "/home/snake/app/current" ]
  then
    TARGET_DIR=$(readlink -f /home/snake/app/current)
    sudo tar -zcf "/opt/backups/${DATESTAMP}/app-backup_${PREVIOUS_VERSION}.tar.gz ${TARGET_DIR}/"
  fi
}

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

if [ "$DEPLOYMENT_GROUP_NAME" == "Staging" ]
then
    echo "Staging Environment"
fi

# detect previous version
detect_previous_version
# debug env vars for codedeploy
debug_env
# ensure the user exists
user_and_group_check
# create a backup
#create_backup
# log status
log_status

Key Script Components Explained

Global Variables

  • APP_USER and APP_GROUP: Define the user and group for the application.
  • DATESTAMP and TIMESTAMP: Used for creating dated backups and logs.

Core Functions

  • detect_previous_version(): Reads the previously deployed version from a file, essential for version tracking and rollback strategies.
  • debug_env(): Logs important CodeDeploy environment variables to a temporary file for debugging purposes.
  • user_and_group_check(): Ensures the specified application user and group exist on the instance. If not, it creates them.
  • create_backup(): Creates a compressed tarball of the current application directory before a new deployment, safeguarding against data loss. This is skipped on the initial deployment.
  • log_status(): Records the completion of the 'before install' step in the logs.

Conditional Logic

The script includes a conditional check for the Staging deployment group, allowing for environment-specific actions or logging.

Execution Flow

The script first detects the previous version, then logs environment variables, ensures the application user and group are present, attempts to create a backup (if not the initial deployment), and finally logs the completion of the before_install phase.

Best Practices and Considerations

  • Idempotency: Ensure functions like user_and_group_check are idempotent, meaning they can be run multiple times without causing unintended side effects.
  • Error Handling: The set -ex command ensures that the script exits immediately if any command fails and prints the commands as they are executed, aiding in debugging.
  • Permissions: Ensure the CodeDeploy service role has the necessary permissions to create users, groups, directories, and write to backup locations.
  • Backup Strategy: Regularly review and test your backup and restore procedures. Consider offloading backups to a more persistent storage solution like S3.
  • Environment Variables: Leverage CodeDeploy's built-in environment variables for dynamic configuration.

Further Resources