Is there any possibility to use CodeDeploy environment variables in section files of AppSpec file

Viewed 7688

I have website, which stored on AWS EC2 servers.

We have 2 servers, one for production environment and another one for development and staging environments.

Development and staging environments located in different folders. For example development env stored in /var/www/development, while staging stored in /var/www/staging.

I'd like to use AWS CodeDeploy to upload files directly from bitbucket. I put AppSpec file, which copy source code to /var/www/html folder and install all dependencies and configurations. But I want my AppSpec file to copy source code to /var/www/development or to /var/www/staging depending on Development group, that was selected.

Is there is any way to do it or, maybe, there are some better approach in my situation?

3 Answers

The appspec.yml is a bit inflexible so use the following to deploy code in to different folders on the same instance.

version: 0.0
os: linux
files:
  - source: /
    destination: /var/www/my-temp-dir
permissions:
  - object: /var/www/my-temp-dir
    owner: ec2-user
    group: ec2-user
hooks:
  BeforeInstall:
    - location: ci/integrations-deploy-pre.sh
      runas: root
  AfterInstall:
    - location: ci/integrations-deploy-post.sh
      runas: root

Inside of my integrations-deploy-post.sh file, I then use the CodeDeploy environment variables to move the files in to the place I need them to be;

#!/bin/bash
    
if [ "$DEPLOYMENT_GROUP_NAME" == "Staging" ]
then
    cp -R /var/www/my-temp-dir /var/www/my-staging-dir
    chown -R ec2-user:ec2-user /var/www/my-staging-dir

    # Insert other commands that need to run...
fi

if [ "$DEPLOYMENT_GROUP_NAME" == "UAT" ]
then
    cp -R /var/www/my-temp-dir /var/www/my-uat-dir
    chown -R ec2-user:ec2-user /var/www/my-uat-dir

    # Insert other commands that need to run...
fi

NOTE: In my integrations-deploy-post.sh You'll also need the commands you want to run on production. Removed for simplicity.

I had the same problem, but I used source control as a solution to this. My workflow is using Gitlab CI > AWS Code Pipeline (S3 Source and CodeDeploy).

So in my development branch, my AppSpec file would look like this:-

version: 0.0
os: linux
files:
  - source: /
    destination: /var/www/html/my-project-dev
hooks:
  AfterInstall:
    - location: scripts/after_install.sh
      timeout: 400
      runas: root

in my staging branch:-

version: 0.0
os: linux
files:
  - source: /
    destination: /var/www/html/my-project-staging
hooks:
  AfterInstall:
    - location: scripts/after_install.sh
      timeout: 400
      runas: root

My Gitlab-CI just uses a shell executor to my EC2 instance and it basically compresses my project folder and uploads to S3.

.gitlab-ci.yml

stages:
  - deploy
setup dependencies:
  stage: .pre
  script:
    - echo "Setup Dependencies"
    - pip install awscli
deploy to s3:
  stage: deploy
  script:
    - tar -cvzf /tmp/artifact_$CI_COMMIT_REF_NAME.tar ./*
    - echo "Copy artifact to S3"
    - aws s3 cp /tmp/artifact_$CI_COMMIT_REF_NAME.tar s3://project-artifacts/

clean up:
  stage: .post
  script:
    - echo "Removing generated artifact"
    - rm /tmp/artifact_$CI_COMMIT_REF_NAME.tar

Note that $CI_COMMIT_REF_NAME is used to differentiate the artifact file being generated. In development branch it would be artifact_development.tar, in staging branch artifact_staging.tar.

Then, I have 2 pipelines listening to the two respective artifacts which deploys to 2 different CodeDeploy Application.

Not sure if this is the best way, surely welcome any suggestions that is better

Related