Thursday, August 24, 2017

Setting up automatic deployment to azure web app

This is something we have been working on for a long time, far too long. There are so many samples and options out there it was very difficult for us to set up, and now that we finally have our environment up and running I thought I'd share our experience.

Our set up

First, let me describe our current set up.

See, with SharePoint hosted add-ins, Provider hosted add-ins, click once applications and other services (like licensing, captcha, etc) - we had to set up a web app on azure.

That web app serves as a CDN for our JS/CSS/HTML/Images and a few asp.net apps, and we had to set it up to be globally available, so using a traffic manager we have a few servers around the world handling local traffic.

Now, we set up one extra server for what we call a "fast ring" release cycle.
That's where we publish our beta versions for testing, and after a short cooling period we push them to the production servers.

So, basically each app we release requires us to publish to 1 fast ring server, and later to a few production servers in what you can imagine is a very time consuming and error prone publishing process.

Also, every server we added to the mix required the developer to publish to that server as well.

So automating this was a high priority for us from the beginning.

Automation options

I've continuously discussed and read about azure automated deployments, and was very happy to see there were a lot of options to publish to azure but neither answered all of our needs.

Synced library (DropBox, OneDrive, etc)

This option was by far the easiest to set up. You basically register one of these services to be the source of your web app.
Surprisingly, no OneDrive for business support - only personal OneDrive. Actually, this is more than a surprise, it is flat out ridiculous since the target audience here is clearly a business user with a very high likelihood to be a O365 subscriber!

But that wasn't what threw me off.

You would get a sub folder in your service, and map it to a server.
So, I could build a "production" folder and "fast ring" folder and map them to their servers. Easy enough.
Then, I would have to sync that client to my dev machine, and "publish" my web apps into that local folder.
That would in turn sync the changes into the cloud, and at that point it gets tricky.
There isn't a way for azure to detect changes and start the update automatically.
You would have to visit each and every web app and click the "sync" button to have them sync their content with the storage service.
I'm sure I could write a script or some code that would automate this, but I was trying to avoid writing any code for something like this - so moving on.

Azure continuous deployment from visual studio online

In azure, under the web app there is a way to set up a connection to a project in Visual Studio online.
Since all our source code is stored in visual studio online anyways in Git repositories - I really had my hopes up.
Setting this up was just impossible.
Since we have an MSDN azure subscription where all our services are set up, and our O365 tenant is on a different subscription, our visual studio online was associated with our O365 tenant so that we can use those logins.
It seems it made it impossible to associate that visual studio online account with our azure MSDN subscription, so I tried and tried and it seemed to be impossible so I gave up.

Visual studio online "Build & Release"

Finally, I went to visual studio online and noticed there is a way to configure it to build your project on their servers and set it up to publish and release to many remote services, including azure.

I honestly struggled with setting up the build on the server. I got it to work on some projects, others threw errors and I was about to give up. I'm sure its possible and I will definitely work on it again until I get it working like I want it, but even though - getting it to publish a click once project for example would be complex, using our code signing tools and many of our pre/post build custom events and so on - it might be too complex to do.
But, I came up with a simpler way of doing it.
We would build our projects locally, and publish them locally.
Web applications - as a deployment package file. this produced a zip file, that we would check in the source control.
Next we can publish that zip file package to azure, and set up a trigger for the publish task on that zip file so that it would run automatically whenever the zip file changed.

For click once - we basically check in the "publish" folder, and did the same thing - put a trigger on it, and set up a task to publish that entire folder every time it changes.

This allows us to still build and publish using our dev machines, and have visual studio online job only handle publishing the content to the web servers in azure.

Next, we decided our "master" branch would be our production. Created a "fast ring" branch that would be published to the fast ring and we were done.

That was by far the easiest to set up (connecting to azure subscription took 2-3 minutes, but at least it worked), and was automatically triggering whenever we pushed a new version.

The only downside is, that I couldn't set it up to build the package on the server, but like I said - still working on it.

So, if you are working in visual studio online, obviously I would recommend this approach. But if you are not - you should check it out anyways, since the build & release tasks there support getting your source code from many sources (GitHub, Remote Git repo, Subversion) has a ton of build and publish tasks you can add and supports publishing to many services (not just Azure).

Also cool - is that I now get an email saying if a publish went through OK or failed. So I do have some monitoring on whats going on moving forward, which is great.

Definitely the easiest one to set up, and I wish we had done this a year ago.

If you have experience with something like that, please share your thoughts in the comments below, also questions are always welcome.

No comments: