Reputation: 2003
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
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
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
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