Liauchuk Ivan
Liauchuk Ivan

Reputation: 2003

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

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?

Upvotes: 12

Views: 12095

Answers (3)

ajtrichards
ajtrichards

Reputation: 30565

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.

Upvotes: 8

daisura99
daisura99

Reputation: 1110

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

Upvotes: 0

EmptyArsenal
EmptyArsenal

Reputation: 7464

The recommended way to change AppSpec or custom scripts behavior is to utilize environment variables provided by the CodeDeploy agent. You have access to the deployment group name and the application name.

if [ "$DEPLOYMENT_GROUP_NAME" == "Staging" ]; then
  # Copy to /var/www/staging
elif [ "$DEPLOYMENT_GROUP_NAME" == "Development" ]; then
  # Copy to /var/www/development
elif [ "$DEPLOYMENT_GROUP_NAME" == "Production" ]; then
  # Copy to /var/www/html
else
  # Fail the deployment
fi

Upvotes: 4

Related Questions