AWS CodeDeploy - GitLab

Integrating with GitLab CI runners you should setup and add the file .gitlab-ci.yml to your repository with the following components

image: docker_hub_image
before_script:
  - git submodule sync --recursive
  - git submodule update --init --recursive  
  - sudo apt-get install zip unzip rsync -y
  - chmod +x step1_script.sh
  - chmod +x step2_script.sh      
deploy_app:
  stage: deploy
  script:
    - step2_script.sh
  when: on_success
  only:
      - master
	  
build_app:
  stage: build
  script:
    - step1_script
  when: on_success
  only:
      - branches

The intention is to build and deploy the application code from GitLab to the target AWS CodeDeploy listening agents.

In this case EC2 spot request machines running with codedeploy and cloudwatch agents already running on them.  Details are it a packer generated AMI is generated and then used as the image for a launch configuration which then is used as the base controlling agent for the AutoScalingGroup.  Anyway on to the configuration details.

Package

Clone the GitLab contents to the CI runner folder contents and also move the appropriate appspec.yml file into the folder prior to zipping it up.  Going to use the AWS CodeDeploy zip file format deployment.

#!/usr/bin/env bash
# Init packaging directory
# ../
#   contents


# Delete output zip file if necessary
rm output_file.zip

rm -rf "output_folder"
mkdir -p "output_folder/dest1"
mkdir -p "output_folder/dest2"

# Copy files to output folder
rsync -av --progress . ./gitlab_user/gitlab_repo --exclude=.git --exclude=submodule/.github --exclude=output_folder
rsync -av --progress ./output_folder/dest1
rm -rf "output_folder/dest2"
cd output_folder/dest1
cp <path_to_appspec_file>/appspec.yml ../appspec.yml
rm *.yml
cd ..
zip -r ../output.zip .
cd ..

# Delete the output folder
rm -rf "output_folder"

Stage

Now stage the output zip file and register it to the S3 folder for deployment.  This step does not deploy the application to the applicable AWS CodeDeploy listening agents i.e. the autoscaling group with EC2 machines listening for push deployments.

#!/bin/bash
aws s3 cp output.zip "s3://<accessible_s3>/output_$UNIQUE_ID_FOR_DEBUGGING.zip"
aws deploy register-application-revision --application-name output \
        --s3-location "bucket=<accessible_s3>,bundleType=zip,key=output_$UNIQUE_ID_FOR_DEBUGGING.zip" \
        --description "output ($UNIQUE_ID_FOR_DEBUGGING)"

Deploy

This step triggers the AWS CodeDeploy process to take the above revision (latest) and now apply it to all listening AWS CodeDeploy agents running on EC2 machines within the AutoScalingGroup.

#!/usr/bin/env bash
aws deploy create-deployment --application-name output \
      --deployment-config-name CodeDeployDefault.OneAtATime \
      --deployment-group-name output \
      --s3-location "bucket=<accessible_s4>,bundleType=zip,key=output_$UNIQUE_ID_FOR_DEBUGGING.zip"

appspec.yml - This file which is in the root path of the AWS code deploy zip file from above instructs code deploy with pipeline triggers that can run before installation and after installation.  There are more hooks that can be interfaced, but this installation is for a dynamic language applicaiton that copies the git contents to the destination and then sets itself up.  Note that this is deployed to a target linux machine of ubuntu 18.04 and that it run as root unless specified with the runas option.

version: 0.0
os: linux
files:
  - source: /
    destination: /home/ubuntu/<dest_path>
hooks:
  BeforeInstall:
    - location: <file_path_in_zip_above>/action_run_before.sh
  AfterInstall:
    - location: <file_path_in_zip_above>/action_run_after.sh
      runas: ubuntu