This is the first post in the Real World Problems with Windows Azure Web Sites blog series, as it intends to answer one of the most common questions I receive when I’m doing presentations about Windows Azure Web Sites. This situation demonstrates a typical setup, wherein a site owner has multiple environments to which they push their web site. This setup is extremely valuable for staging site releases and for delivering solid web applications or for doing A-B testing of a site’s changes. In order to make sure your changes are okay, it helps to have a staging and production environment to use to make sure things are good before one makes their changes live in a production environment. My good friend and colleague Cory Fowler blogged about continuous deployment with Windows Azure Web Sites, and my other good buddy Magnus Martensson did a great presentation at Windows AzureConf on the topic. I’ve done countless demonstrations of continuous deployment with Web Sites, but one question always comes up, that this post intends to answer.
That’s all well and good and I know I can deploy my site automatically each time I make a change, but that’s not realistic. It’s like, if I use Windows Azure Web Sites to host my site, it’ll be deployed each time I check in code – even when I didn’t want to deploy the site. How do I control what gets deployed and control the deployment and maintain quality?
That’s a great question, and it’s one that most have struggled to answer. It’s also a barrier for many who are thinking of using Windows Azure Web Sites but who don’t want to manage their site like they’re running their company out of a garage. This “happy path” deployment mantra isn’t real-world, especially for site owners who want to stage changes, test them out, and be certain their changes won’t cause any problems following a hasty deployment process.
Multiple Sites for Multiple Environments
As with any multiple-environment setup, the first thing I need to do to support having multiple environments is to create multiple sites in Windows Azure Web Sites. Using the portal, this is quite simple. The screen shot below shows you what this would look like. Note, I’ve got a “real” site, that’s my production site area, and I’ve also added a staging site to the account.
In particular, take note of how both of these sites are in the “free” tier. Let’s say you’ve got a production site in the “non-free” zone because you want to map your domain name to it, scale it up or out, or whatever else. I’ll leave my staging site in the free tier and not incur any charges on it.
Why is this important? Because I won’t need to pay anything additional for having multiple sites. Since most users won’t have the staging URL, or it won’t matter what it is since it’ll just be for testing purposes, I don’t need to map a domain name to it, scale it, or anything like that. It’s just there for whenever I need to do a deployment for testing purposes or verification purposes. This setup won’t require you to spend any more money.
Using GitHub.com for Continuous Deployment
In this example, I’ll be using GitHub.com to manage my source code. You don’t have to use GitHub.com for this, so if you’re new to Git don’t freak out, you have other options like CodePlex, BitBucket, or TFS. Heck, you could even automate an FTP deployment if you want to.
The first step in setting up GitHub.com integration with a web site is to load up the site’s dashboard and to click the Quick Link labeled “Set up Git publishing” as is illustrated in the screen shot below.
Once the repository setup completes, the portal will allow me to specify what type of Git repository I want to connect to my site. I’ll select GitHub.com from the list of options, as you’ll see below.
If this is the first time I’ve tried to connect a GitHub.com repository to a web site, I’ll be asked to allow the partnership to take place.
By clicking the Allow button, I let GitHub.com know I’m okay with the partnership. The final step in tying a repository to a site is to select the repository I want to be associated with the site, which you’ll see in the screen shot below.
I’ll repeat this process for the staging site, too, and I’ll associate it with the exact same repository. This is important, as I’ll be pushing code to one repository and wanting the deployment to happen according to which site I want to publish.
Two Sites, One Repository? Really?
Sounds weird, right? I’ve got two sites set up now, one for the production site, the other for the staging site, but I’ve associated both sites with the same repository. Seems a little weird, as each time I push code to the repository, I’ll be deploying both sites automatically. The good part is, there’s this awesome feature in Git that I can use to make sure I’m deploying to the right spot. That feature is called branching, and if you’re acquainted with any modern source control management product, you probably already know about branching. You probably already use branching to control deviations in your code base, or to fix features and bugs. With Windows Azure Web Sites’ support for branches, you can use them for environmentally-specific deployment practices too. The best part is, it’s quite easy to set up, and that’s just what I’ll show you next.
Configuring Branch Associations
Before I write any code, I’ll need to set up the branch “stuff” using the portal. To do this, I’ll go into my production site’s dashboard and click the Configure link in the navigation bar. Scrolling down about half way, I can see that the production site’s set up to use the master branch. The master branch is the default branch for any Windows Azure Web Site, but as you’ll see here, the portal gives me the ability to change the branch associated with an individual web site.
Now, I’ll go into my staging site and I’ll set the associated branch for that site to staging. This means that, each time I check code into the master branch, it’ll be deployed to the production site, and each time I check code into the staging branch, it’ll be deployed to the staging site.
With the setup out of the way I’ll be able to write some code that’ll be deployed automatically when I need it to be deployed, and to the right place.
Code, Commit, Deploy
Now that my sites are all configured and pointing to the right branches I’ll need to set up local Git repository, write some code, and check that code into the repository. Once that’s all done I’ll create a second branch called staging that I’ll use to push code to my staging site.
The first step is, obviously, to write some code. I won’t do much complicated stuff for this demo. Instead I’ll just make a simple MVC site with one view. In this view I’ll just put a simple message indicating the site to which I intend to deploy the code.
Now, I’ll open up Powershell to do my Git stuff. As Phill Haack points out in this epic blog post on the topic, posh-git is a great little tool if you’re a Powershell fan who also uses Git as a source control method.
I’ll initialize my Git repository using git init, then I’ll tell the Git repository where to push the code whenever I do a commit using the git remote add origin [URL] command. Finally, I’ll use the git add and git commit commands to push all of my changes into my local repository. All of the files in this changeset will scroll up the screen, and when the commit completes I’ll push the changes back up to GitHub.com, to the master branch, using the git push origin [branch] command.
Once the commit finishes and the code is pushed up to GitHub.com, Windows Azure Web Sites will see the commit and perform a deployment. If you’re watching the portal when you do the commit you’ll see the deployment take place [almost magically].
If I click the Browse button at the bottom of the portal the site will open up in a browser and I can verify that the change I just committed was deployed. So far, so good.
Setting Up the Staging Branch
Now that the production site’s been deployed I need to set up the staging environment. To do this, I’ll go back into my favorite Git client, Powershell, and I’ll create a new branch using the git checkout –b [branch] command. This will create a new branch in my local Git repository. Then, it’ll switch to that repository and make it active. If I type git branch in Powershell, it’ll show me all the branches in my local repository. The green line indicates the branch I’m currently working on.
Now that the branch has been created, I’ll make some small change in the code of the site. Once this change has been made I’ll be pushing it up to GitHub.com again, but this time I’ll be pushing it into the newly-created staging branch, so the production branch code in the master branch is safe and sound.
Switching back to Powershell, I’ll commit the changes to the staging branch in my local repository. Then, I’ll push that code back up to GitHub.com, this time specifying the staging branch in my git push command.
This time, I’ll watch the staging site in the portal. As soon as the publish is complete, the portal will reflect that a deployment is taking place.
Once the deployment completes, I can check the changes by clicking the Browse button at the bottom of the portal page. When the staging site opens up, I can see that the changes were pushed to the site successfully.
If go back to the production site, it still says Production on it. Pushing to the staging site didn’t affect my production site, and vice-versa. I’ve got dual-environment deployments, based on source code branches, and I’m able to test things out in one environment before pushing those changes to production. Everyone wins!
Local Git Branch Niftiness
One of the neat things about using Git branches (at least it was nifty to me), is that all the code for all the branches is stored in your local repository. Switching between branches automatically results in the source code being restored on your local drive. The whole thing happens automatically. Demonstrating how this works is as easy as switching branches while you have a source code file open in Visual Studio.
So let’s say I still have the staging branch set as my working branch and I’ve got the source code open up in Visual Studio. If I got to my Powershell client again and switch the branch using the git checkout [branch] command, Git changes the branch on the fly for me. In so doing, all the files in the local directory are replaced with the files from the newly-selected branch.
The moment I switch back to Visual Studio, it warns me that the file has changed on disk and asks me if I’d like to reload it.
If I click the Yes button and then look at my file, I’ll see that the file has been changed to the one resident in the new branch.
In this way, Git keeps all the branches of my source code in my local repository, so I can make changes to the branches as needed and then commit those changes back to the local repository. Once I’m ready, I can push those files back up to the origin (in this case, GitHub.com), and everything’s cool.
Web site environments are a real-world method of controlling, gating, and reverting deployments. Using multiple environments, development shops can make sure their changes took place properly before crashing a production site with poor changes. Windows Azure Web Sites is a real-world web hosting platform that can be used to solve real web site challenges. With a little thought and planning, it’s easy to use Windows Azure Web Sites to host multiple versions of a web site. Testing can happen live, without affecting production deployments. I hope this post has introduced a good method of achieving separate site environments, and that you can see yet another way Windows Azure Web Sites can help you get your site up and running, keep it continually deployed, and reduce your concerns over the nature of continuously deploying to a production web site environment using simple tricks like Git branches.