Deploying to AWS with Travis via ssh

gortron

gortron

Posted on May 10, 2020

Deploying to AWS with Travis via ssh

Introduction

The goal of this post is to provide a sample solution for setting up CICD from a GitHub repo to an AWS ec2 instance using Travis—I hope someone debugging this problem finds this useful.

I recently worked on a small personal project for a Discord bot, which I deployed on an AWS ec2 instance. My workflow for deploying my GitHub repo to my ec2 instance wasn't that onerous for a personal project—ssh to my ec2 instance, cd to repo, git pull, and restart pm2.

But it had a problem: any time a contributor made a pull request, I had to deploy the updated master using the workflow above. That approach works fine for one person, but makes less sense for a group of contributors. I needed a deployment methodology that would essentially recreate the steps above, but would do so anytime a pull request was merged to master. That sounded to me like I needed lightweight CICD tooling.

There are many tools to help set up CICD deployment to an AWS ec2 instance (Jenkins, Travis, CircleCI among them). I to setup a custom deployment on Travis, mainly because Travis is hosted and wouldn't require me to set up another ec2 and s3 instances.

Below, I'll describe how I executed this problem in brief. My solution is an adaptation from Thomas Parisot, so great thanks to him. He writes in greater depth about why his solution solves for security concerns with ssh'ing to ec2 from Travis, and I strongly consider anyone solving this problem to visit his blog as well.

Execution

1) Set up an ssh key for Travis

  • If you don't already have the Travis CLI tooling, use $ brew install travis
  • Make sure you have a .travis.yml file in the root directory of your project repo.
  • While in your root directory of your project repo, execute the following:
$ ssh-keygen -t rsa -b 4096 -C 'build@travis-ci.org' -f ./deploy_rsa
$ travis encrypt-file deploy_rsa --add
$ ssh-copy-id -i deploy_rsa.pub ec2-user@<your-ec2-instance>
$ rm -f deploy_rsa deploy_rsa.pub
$ git add deploy_rsa.enc

2) Set up your Travis custom deployment

  • The commands above will add most of what you need to your .travis.yml file. We will make changes, though, so that the encrypted deploy_rsa key gets added to ./tmp/ so that it doesn't accidentally get deployed:
before_deploy:
- openssl aes-256-cbc -K $encrypted_<...>_key -iv $encrypted_<...>_iv -in deploy_rsa.enc -out /tmp/deploy_rsa -d
- eval "$(ssh-agent -s)"
- chmod 600 /tmp/deploy_rsa
- ssh-add /tmp/deploy_rsa
  • Now that Travis is configures ssh in its before_deploy lifecycle, we will tell it what to do in its deploy lifecycle. We want it to ssh to our ec2 instance and execute a deployment script:
deploy:
  provider: script
  skip_cleanup: true
  script: ssh ec2-user@<your-ec2-instance> 'bash ./deploy.sh'
  on:
    branch: master

3) Write a deploy script for Travis to execute

  • The final step is to add a deployment shell script in the root directory of your ec2 instance. After a successful build, travis will ssh to your ec2 instance and call bash ./deploy.sh. So the last step is to add a deploy.sh script in the root directory of your ec2 instance.

  • Your deployment script will look unique from mine, but I'll provide mine below as guidepost.

  • As stated in my intro, I want mine to cd to my previously deployed repo, git pull to get the latest, yarn to add any missing dependencies, and pm2 restart all to re-start my Node server.

echo "Changing directory to ~/cupbot"
cd cupbot
echo "Pulling from git"
git pull
echo "Yarn'ing"
yarn
echo "Restarting pm2 instances"
pm2 restart all

Conclusion

I hope this was useful to anyone looking to deploy from a GitHub repo to an AWS ec2 instance. If you get stuck or need help, please don't hesitate to comment or reach out. The discord bot repo I deployed is available here as well.

💖 💪 🙅 🚩
gortron
gortron

Posted on May 10, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related