Automatic deploy to Azure Web App with Circle CI v2.0

Ulrik Strid
4 min readMar 15, 2017

--

I recently wrote this blogpost that had information on how to host your create-react-app application on Azure with github integration. This is kind of a part two where I set up CI with circle CI. Again, everything you need is in this repo.

Background

I like the “get going” mentality of create react app. But as someone who really like the Azure I felt like there were too much work. The path that was documented was to create a (node) server and host my files with that. But why would I have to when IIS (or whatever runs Azure App Service) can do it for me. I wanted a easy way but I still wanted to follow best practices with continuous integration and version control.

I had a setup where azure pulled the latest code from master and deployed it straight to production and that was a easy solution. I did not have to push my code manually with ftp but there were still some confidence missing that I want from my CI environment. I wanted a setup where I can work with pull requests and when I merge them in to master the CI builds it and gets it to production some how.

To solve this I found 3 solutions.
1. Automate the ftp pushing
2. Push to a git repo in the App Service
3. Let my CI environment push to a “production branch” in github and deploy from that.

I went with 3, I tried the first and it feels like a gigant hack and I already have a git repo, I don’t need two. 2 is probably at least as good as 3 but it’s not what I chose.

What now?

I wanted to try the new version 2 beta of CircleCI as I love to live on the bleeding edge.

So the setup was going to be something like this:
1. Push code to new branch
2. Test code on CI
3. Merge to master when tests pass
4. Test code on master
5. Automatic merge to production branch
6. Deploy code on Azure App Service

Step 1–4 is pretty much automatic when starting with circle and github. But as I am now running version 2 there were some new stuff in the circle.yml. First of all we need to convert the very basic settings to something that is more verbose.

machine:
node:
version: 6.10.0
-- becomes --version: 2
jobs:
build:
working_directory: ~/azure-appservice-static
docker:
- image: node:6.10.0
steps:
- checkout
- run:
name: Install Dependencies
command: npm install
- run:
name: NPM Test
command: npm test

This might look like it is worse, but what changed is really that we removed the magic and now have a declarative workflow. First we create and “cd” to our working dir and choose a docker image. Then we checkout the code from git and start running our commands. Personally I think this is great. Our tests are now running on the new version of CircleCI. Now it should be easy to just run a deploy command when our tests pass on master.

At end of circle.yml# Deploy production
- deploy:
command: |
if [ "${CIRCLE_BRANCH}" == "master" ];
then ./scripts/publish.sh production;
fi
./scripts/publish.sh#!/bin/bash
git config --global user.email "$USER_EMAIL"
git config --global user.name "$USER_NAME"

git checkout -b "$1"
git merge master
git commit -am "$CIRCLE_BRANCH build#$CIRCLE_BUILD_NUM"
git push --force --set-upstream origin $1

But wait, this doesn’t work. CircleCI does not have the permissions to push to my repo. We have to add a ssh key to our github repo and to CircleCI with the correct permissions. I followed these instructions. Something that threw me for a curveball was that CircleCI did not use my key at first, but then I found something in the docs for 2.0 that looks something like this.

steps:
- add-ssh-keys:
fingerprints:
- "SO:ME:FIN:G:ER:PR:IN:T"

BAM! It works. Now all I had to do was point Azure Web App to use my production branch instead of my master branch. As the publish script is parameterized we can use it if we want the develop branch to go to beta or something like that as well.

Conclusion

This setup has not been as pain free as I would have wanted it to be. It was a few hours work to figure it out.

CircleCI v2.0 sped up my builds by about 4–8 times, from about 2 minutes to 15–30 seconds. This is just a very basic create-react-app project and I want to do some heavier testing before I can call this a real conclusion but it seems fast. The circle.yml becomes a bit more complicated but it feels powerful. The one thing that I had problems with was that I could not stop my production branch from being built on circle, but I was told that it is in the backlog.

You can find the final scripts with caching of node_modules in the repo mentioned in the start.

Thanks for reading and hope it helped.

--

--

Ulrik Strid

Father, husband, programmer. I am a javascript consultant. Fascinated with Azure and interested in most things "new".