Release Management Using VSTS

If you have been tracking Azure at all lately you know that it is growing at breakneck pace. Microsoft has really turned up the volume on their enterprise cloud at all levels.  Just diving in can sometimes be a rough experience. Azure is a wide open field with many paths to solve your problem. I would like to show you the path I have found to get my release management up and running for my complex micro-modularity and microservices.

In the last post we created an ASP.NET Project for Visual Studio Team Services (VSTS) Release in a minimal way.  Now we will check ‘the check box of continuous integration’ and ‘push the button of continuous deployment’. Then we will add a second deployment environment to get your creative juices flowing.


So to be clear, there is some configuration you need to do upfront that I won’t cover here.  Some of the setup is clearly part of the awkward dance of preview services.  But if you want to get ahead of the curve and take advantage of these services, I can attest to it being well worth it. They only need to be setup once.

We will:

  • Create an Azure Build definition.
  • Create an Azure Release definition
  • Deploy Azure Resource Group containing a Web Site
  • Configure a second environment

For the purpose of this tutorial you need the following:

  • Project to Deploy with Azure Resource Templates (follow tutorial, or fork it)
  • A VSTS account with a project, the RELEASE hub enabled and version control system (VCS), it is easy enough to use the hosted Git or Github or most any Git repo visible to the Internet.
  • A service end point configured in Team Services or TFS with rights to connect to your Azure subscription.
  • An agent that is capable of running the deployment tasks. I am just using the one on VSTS.
  • if you are using GitHub for version control you can connect it using a personal access token

Once you have the above resources you should be able to walk through the rest of this Release Management tutorial for Visual Studio Team Services.

Azure Build Definition

In your project click over to Build.  You will see a nice little green plus on the lefthand side that will create a new build definition.  Select the Visual Studio template and select the repo you are going to use.

new build def
New Build



new build def - repo
Connect Version Control System


build def - edit
Edit Build


If you are using github you can specify it later when you edit the configuration.  This template gives you a nice list of tasks that will handle our simple situation.  It is easy to add and remove tasks. I would encourage you to do so when you finish this tutorial. The build config is very robust, able to trigger on-prem builds and even using crazy automation tools like like Ant, Gradle, Grunt, Gulp, Maven… go nuts.

Version Control

The easiest thing to do is use the Git repo built into the project, but I am going to build the example code from GitHub. You can follow the link above to connect it to your VSTS account for use. The configuration looks like the following using the built-in VCS or def - Repository

Web Deploy Package

To make the deployment package MSBuild basically deploys to a zip file.  To trigger this you need to add ‘MSBuild Arguments’ on the Visual Studio Build step. In that field type

/p:DeployOnBuild=true;PublishProfile="Web Deploy Package"

After you make the change, click save. A great feature of the system is version controlling the builds. You allowed to rename the build here and add a comment. If you comment every save you create a rich history of changes, each of which can be scrutinized on the History tab.

Save Dialog

Continuous Integration (CI)

At this point verify you have checked ‘the check box of continuous integration’. Note that you can also schedule builds if you like ‘Nightly’ instead of ‘Continuous’.


check the check box of continuous integration
the check box of continuous integration



Now comes the fun part: Click Queue Build and watch it do it’s thing. When it is done you will find that these logs are saved and you can brows the artifacts created or download them as a zip.

Azure Release definition

Now click over to the Release tab. Release uses the same engine as build, so you will see many of similarities, and you can do many of the same tasks. Layout should be familiar, so click the green plus sign over on the left that says it is used to ‘Create a release definition’.  Choose the Azure Website Deployment template and click ok. This starts you out with a single environment that has a couple tasks.

Here the term ‘environment’ means no more than a single set of tasks, variables and sign-offs that can be strung together to make an automated release process.

You will note that you are encouraged to test often since the second task you are given is a test task. I personally run Unit Tests during build and Integration Tests after a release. If you wanted you could even have a little sanity test to run when you release to production.

First it is good to configure the Azure Web App Deployment task so you can save. Simply select your Azure Subscription endpoint, give your app a name, and select a location near you for now. Give the release config a name and click save.

Infrastructure Deployment

Right now you could click deploy and the thing would just go and use defaults and you would get a website in your Azure account.  However, you would not have any real control over how it would be billed and it would use whatever web.config you checked in. So in this step we will take control of all of this with a couple little JSON files.

Click Add Task. Under deploy click Add next to Azure Resource Group Deployment. I will admit when I first saw this I thought it sounded grand an complex. However, a couple clicks later I was elated with how simple it is.

When you click close you will notice the task is incompletely configured by default and at the end of your tasks.  Make it the first task by dragging the task to the start of the list. Then select your Azure Subscription service endpoint (I use a Service Principal for this). Then name the resource group. Later when you master variables you can name everything by convention using an environment specific variable. I always add ‘-resource’ to the resource group name for additional clarity.

Now click the ellipsis on the Template line.  It will tell you that you don’t have any build definitions linked.  Click ‘Link to a build definition’ and select the build definition you made earlier as the Source and click the Link button.

Now you have a tree of the artifacts created by that build when you ran it last.  The files you want will be under ‘drop’ and the folder name you gave your Resource Group project. Then under bin/Release/Templates select the WebSite.json file and click OK. Assign the Template Parameters value by clicking the ellipsis again, browsing to the same location and selecting the WebSite.parameters.json.

Now you are to the point where the magic starts and where things really started to click for me. Because you defined the website name and connection string as a parameter you can assign those via the Override Template Parameters field.  In this field set your values like this:

-hostingPlanName "myPlanName" -websiteName "myWebsiteName" -connectionString ",1433;Database=myDbName;User ID=myUsername;Password=MyPassword;Encrypt=True;"


One last thing to check before you release is that your Locations match between the Resource Group Deployment and the Web App Deployment. Then click Save.

Now the point of all this is to get you to continuous deployment. To enable this click the Triggers tab and check the check box, select your artifact source and select your environment. Then click save.  Now when you check in a change, it will build. When done building it will release.

Release Trigger

To give it a test without checking anything in click the release drop down and select Create Release. You can choose the artifacts from the release you did earlier and select the environment you just configured and click create. If the process succeeds you can verify by viewing the Resource groups in the Azure Portal.  The great thing about resource groups is now, to remove everything you just released to Azure, simply delete the resource group. To deploy it again, make a commit or release it manually.

The great thing about using the resource template is that if you make changes the environment will be updated to reflect those while you keep the progression of the environment under version control.

Configure a second environment

To understand why I think Release environments are cool, click the ellipsis on the Default Environment and ‘Configure variables’.  You will notice there are a variety of them predefined. Lets create one of our own.


At the bottom of the list click Add Variable. Name it ‘websiteName’ and give it a value you like. Click OK, and go back to your Resource Group Development task. In the Resource Group filed type:

$(websiteName) -resources

Then in your Override Template Parameters put $(websiteName) after -websiteName. Select the Azure Web App Deployment task and put the variable $(websiteName) in Web App Name field.

For a second, imagine you have a much more complex release environment you have configured. Now, click the ellipsis next to Default Environment again and click ‘Cone environment’ and call it something like QA.


Now configure variables on that environment and change value next to websiteName, perhaps appending ‘-qa’ or something. Click ok and Save the definition.  I don’t know about you but the first time I did something like this I giggled enough to make everyone in cubes around me feel uneasy.

Where to go from here

From here you can add more variables, parameter and infrastructure. Add a database or other services and make a self contained set of services so you can spin up tests of all sorts.  There are many tutorials out there for expanding on your JSON templates and great functionality built into Visual Studio (maybe Code too) to help you edit these configurations. I would be interested on where you personally take things from here.

In a post in the future up I will dig a little deeper into how I have overcome the issues of managing many tiny libraries using private NuGet repositories and multiple Git repositories.

After looking at VSTS Release, how does this compare to other tools you have used?


Release Management Using VSTS

ASP.NET Project for VSTS Release

So you have discovered the intense desire to manage your infrastructure as code and continuously deploy with your eyes closed. It is true, continuous integration and continuous deployment, once implemented, open a whole new set of opportunities. For me personally, most attractive of these is micro-functionality. Microservices are all the rage, but on a more fundamental level, it is hard to manage complex modularity without CI and CD.

For this reason I am going to assemble a refrence ASP.NET project that will demonstrate a common sinario in which the developer and Visual Studio are removed from the deployment process and endless deployments are made possible through Azure Resource Group template parameters. In a second post I will walk through setting up the Azure side of things.

Connection Strings and Migrations with EF6

Entity Framework 7 seems to be shaping up as a key part of my development stack.  However there are a host of things it does not yet do so I have stuck with Entity Framework 6 for most of my current development.  One of the flaws I have found in EF6 is that it is difficult to get it to use a specific connection string for code migrations. This makes automated migrations with VSTS Release even more difficult. There are even stack overflow questions about it that venture down some dark paths to get it right.

The method I have chosen when using EF6 is to make sure my migrations are clean and selectively enable automatic migrations. Then I assign a connection string per deployment as described here. So far this is the best and only way I can find that makes sense.  If you have other ideas let me know in the comments.

Looking at Infrastructure as Code, it seems like a daunting task. Especially if you are like me and have had a brush with sickening array of tools that are needed in some environments to get the job done.  Tools like Jenkins, Chef, Puppet, Ansible… sure they are OSS so they deserve support. On Azure, all you need for IaC are a couple JSON files, no extra software and no Admin involvement to get the right packages installed or make sure the OS configured correctly.

So if you want to skip to the end, grab the JSON and jump to the next post to see where VSTS uses them. I will try my best to give you a concise walk through from here on out so you can understand the things I like about this solution.

Visual Studio Solution

I will assume a level of comfort with Visual Studio, and save bits on the internet by being terse here.  From VS, choose to create a new project. From the New Project dialog select ASP.NET Web Application. For fun select MVC in the New ASP.NET Project dialog and then check WebApi.  Leave ‘Host in the cloud’ unchecked because we will be taking a different path. Click ok to create the solution.

Next we need to configure the web project with a publish profile to create a deployment package when built on VSTS. Right Click the web application project and select ‘Publish’. On the Publish Web dialog select ‘Custom’. When prompted for a name I always name it ‘Web Deploy Package’ so I can use the same build template over and over without a bunch of reconfiguring. On the next screen select a Publish method of ‘Web Deploy Package’. For a package location you should choose somewhere that will be picked up by the Artifacts step(s) in your build task. This usually defaults to a mask like “**\bin\$(BuildConfiguration)\**”, so if you choose your “bin\Release” directory you can get going quickly. Then go ahead and click publish to see what happens. When you check things in, it is best to leave the bin directory out of your commit, so this configuration will save you that way too.

You will see that deploying a WebApi or oData project is as easy as deploying a website. Using this method you can add any service offered by Azure like Service Fabric or to setup VMs if you like mucking about at the OS level.  I hope that after you take this first step you will try some other crazy things. Just remember to delete the resource group after you play with it. As a side note, deleting a resource group in Azure removes everything in it. So when you get down to deploying this you can simply delete the resource group and not worry about unknown things hanging out to penny and dime you down the month.

After you have your solution with a website, right click it and add a new project.  In the Add New Project dialog select Azure Resource Group. In the Select Azure Template list select ‘Web app’ and click ok.  There are other interesting options here, but for this demo, I want to show that there is already a DB up and running that this app will connect to.

Infrastructure as Code (IAS)

Don’t be afraid. As I have written in the past, there is no need for name soup or acronym mehem. Just a JSON file and a mouse.

At the time of writing the Azure Resource Group template that I have installed is using API version ‘2015-08-01’.  You can verify this by opening the WebSite.Json in the Azure resource Group project. The default templates can certainly get you going as is. However there is no way to pass in a connection string or application configuration.  By default the template makes some junked up website name that I dislike as well so we will tweak that too.

In the WebSite.json we want to add website name and connection string so we can assign them during release. First you want to add parameters for `websiteName` and `connectionstring` as shown in this Gist. You can simply delete the websiteName variable and replace all instances of `variables(‘webSiteName’)` with `parameters(‘webSiteName’)`. Then you need to add the section that does the inserting of the values to the WebApp environment in the `Microsoft.Web/sites` section as seen in the gist.


I hope this gets you on your way, and perhaps lets you see the potential of parameterized Azure IaC. Next you should commit this to your project on VSTS. (Although you could just as easily use GitHub with VSTS Build and Release) In the next article I will walk you through configuring Azure to deploy the same code to different environments with their own connection strings.

git the code here

ASP.NET Project for VSTS Release

Testing WordPress on Azure

It is hard to keep up on all the different ways to get an application out to a public facing host.  You hear names like Chef, Vagrant, Puppet, Ansible, Docker, Cloudstuff… At the end of the day you just have to pick the one that makes sense for you.  Hopefully you can do that without going all the way down the road of fully implementing your production environment with all this before you can decide.  Here I will show you one way it can be done without too much fuss and without a 3rd party tool family so big you cant remember all their names.

Some of the old-timers may remember “poor man’s” IT tools.  My flavor I like to call ‘Ghetto Hacks’, or when they are elegant I like to call them a ‘Dixie Mix’.  This solution isn’t exactly the most elegant, but it is possible to run a production environment from it as it does not introduce any non-production worthy dependencies.  It basically does it’s thing and can be thrown out.  In fact I run a bunch of domains that I have setup this exact way.

Some people like to adopt a bunch of cute tools so they can talk ‘name soup’ at the water cooler.  My first goal was to sidestep this for a more unified front.  I also like to keep environments pure.  What I mean is I don’t like to use a Ruby script to drive a Python script that installs a PHP script.  This does not mean I wont use shell script or OS built-ins, but I like to minimize the external installs and dependencies and use native tools.


So now lets take a deep breath before we take this shallow dive.  I will introduce the stack and then show you how easy it is to create a WordPress Website and WP-CLI to configure it from CMD, even if you use a Mac.

The Stack

So lets start with the host. As the title states we are using Azure, which is a Windows-ish environment.  I say this because many users unfamiliar with the OS in the last 10 years may be surprised how at home they can be quickly.  You may be familiar with ipconfig on Windows sharing use cases with ifconfig in unix.  What you may not know is that there are many things that can make you feel at home.  For example in the CMD shell on Azure you can type ls -la and get a directory listing. As an interesting side note there is a shell for Azure written in Node.js called KuduExec, if that makes you feel at home.  We obviously wont be using that here.

Now is where you would normally get into ‘Cheppet or ‘Vagrible. I have instead chosen to use ‘Websites’, a name I can remember.  No OS management necessary.  You may be asking, based on the name, what is the difference between Websites and your $1.35/month shared hosting.  Without editorializing more than I already have, think “all the power and none of the ceremony” of a fully virtualized environment, a non-“Ceremonialized” environment.

I have chosen WordPress because it has a low barrier to entry for users and I think it is somewhat of a common tool.  I also choose it because it is PHP and isn’t the first thing you would think to run on Azure.  I must point out that programming language discussions sometimes degrade to unproductive arguments. All sides usually expose their ignorance by arguing against the negatives that existed 20 years ago (often before most participants were born or could talk).  “ET was the worst game ever.” So a PHP on Azure is some what of a ‘PB and ketchup sandwich’ in the world of cloud.  To set you at ease Windows and Azure has run PHP well for years, so I hope you like the simplicity of the combination.

STEPS: The Instance

The obvious first step is to get a single instance up and running.  Preferably this would be a free operation so we can be sure of the option and the path.  Gladly, Azure gives us a free tier to make it happen, and scale when we are ready.

  1. In this case I will walk you through using the portal.  At a later date I will do this same tutorial via shell (cmd or PowerShell).

  2. From the portal home you will select ‘New’ > ‘Web + Mobile’.
  3. At the bottom select ‘Azure Marketplace’.
  4. On the right side you will see a search box where it says ‘Search Everything’.  Type “wordpress” and hit enter.
  5. There will be two items at the top for WordPress, we want the one that is “WordPress” only with a Publisher of “WordPress” and Category of “Web Apps”. (not Scalable WordPress)
  6. When you click on that you will get a description. Click the ‘Create’ button at the bottom.
  7. The next frame will show what you want to call the resource group and some configurations.  For the sake of this experiment start with ‘Web App- Configure required settings’.
    • URL: you need to pick something unique
    • Pricing Tier: to select the free tier:
      • click on this option and in the next frame click ‘View all’.
      • At the bottom click ‘F1 Free’ and ‘Select’.
      • This will be good enough for testing.
    • Click ‘OK’ at the bottom of that frame.
  8. Give your database a descriptive name by clicking ‘Database’ and changing it to something like “MyWpDb” at the top.
    • To proceed you need to click ‘Leagal Terms’ and accept the terms if you agree.
  9. Click ‘OK’ at the bottom of the Database frame.  This will return you to the ‘WordPress’ frame.
  10. Click Create.

You will see ‘1’ next to notifications on the left-hand menu.  Clicking it will show that Azure is creating your instance.

Kudu ServicesWhen you create an Azure Website in the background a second site is created at which exposes the Kudu Console (Kudu is also the deployment engine for Azure Websites).  This is where you will gain access to Powershell and CMD, more on that later. (but if you are ancious click ‘Debug console’ > ‘CMD’ and type ‘ls -la’ then ‘cd’-around and notice how things above the shell window change).

If you click ‘Home’ and then the tile that was created there you will see a panel that describes the resources you have created.  You have created a Web app, an Applicion Insights profile and a MySQL Database.  You also see various other information about the site, including ‘estimated spend’ which will help you keep ontop of the ‘for pay’ sites should you decide to upgrade for any additional features in the future.


Since we are going to use wp-cli to configure the site, you should install that before hitting the site.  Click on your web app and right at the top click “All Settings”.  Scroll down to “Extensions” and click it.  Then click the add button at the top.Installed web app extensions - Microsoft Azure You will then be presented with a list, from which you should choose WordPress CLI by Cory Fowler.

Now, to show you it works, visit the Diagnostic Console via  Click Debug console.  Then, for the purposes of this post, click CMD.  Then to make sure everything is working type 'wp cli version'.  This should display the version of wp-cli you are using.

To make things easy for me, I like to make a wp-cli.yml file in the site root.  This allows me to do operations directly on the root site without specifying it every time.  So create a wp-cli.yml file with the following contents and upload to your d:\home\site\wwwroot:


core config:
 extra-php: |
 define( 'WP_DEBUG', true );
 define( 'WP_POST_REVISIONS', 50 );

Obviously replacing the content in the brackets with your own.  This information can be obtained from the portal (All settings > Application settings > Connection strings [you may need to click “Show connection strings”]).  Note that the WP_DEBUG constant should only be used while testing.

STEPS: CMD Configuration

Now, to setup the first site, it is simply one command (replacing %name% with your values):

wp --path=%install_dir% core multisite-install --subdomains --title=%siteTitle% --admin_user=%admin% --admin_password=%adminpw% --admin_email=%adminaddr%

Breaking down this command a little, we know that the %install_dir% is going to be D:\home\site\wwwroot.  Here we are doing a install for WordPress Multisite, so we can point several domains at the same piece of code which makes updates and maintenance quite a bit easier.  For you to understand the rest of the options the documentation is quite good.

Wp-cli makes installing extensions easy also.  For example, if you are planning on importing your previous site I would recomend generating thumbs seperate from the import process with the regenerate-thumbnails extension, which is installed like this:

plugin install regenerate-thumbnails --activate

Then say you want to install and activate a great Bootstrap based theme named after a different part of the shoe:

wp theme install toebox --activate

Perhapse you want to install the WP Theme Unit Test data  to test your own theme.  You could do the following:

php -r "readfile('');" > wptest.xml
wp import wptest.xml --authors=create --skip="image_resize"
wp media regenerate --yes

Now, visit your site and see what you have.  Hit the /wp-admin url and login with the username and password you specified in the install command above and see that everything is there.


You may think that this tutorial ended abruptly. Hopefully you only reach this summary if you were not following along on your own free account.  I hope you were totally distracted from this post when you started playing around with the Azure Debug console and started reading the WP-CLI documentation.  But in the event that you find yourself back here to finish reading this post, thank you.

As with any platform Azure has it’s quirks.  Ones that you probably aren’t used to. It is developing at a break-neck pace, and they are highly attuned to their users.  Managing websites without the ceremony of VMs is something that is achievable now, and I hope you see this.  Personally I have moved away from these “Ceremonalized” environments because I don’t have the time to invest in DevOps or finding and paying someone else to do it for me.  I build and tear-down whole sites daily for testing using little more than Composer, WP-CLI and some batch files.  I hope you can remember those names.  I might not be one of the cool kids speaking the slur of name soup, but my lean running, massively scalable site makes my customers money and keeps their customers happy and coming back.  I hope the same or better success in your endeavor.  What have you had success with? Leave a comment.

Testing WordPress on Azure