BM-Bloggers

The blogs of Black Marble staff

You never know how people will use a tool

You never know how people will use a tool once it is out ‘in the wild’. I wrote my Generate Release Notes VSTS extension to generate markdown files, but people have attempted to use it in other ways.

I realised, via an issue raised on Github, that it can also be used, without any code changes, to generate other formats such as HTML. The only change required is to provide an HTML based template as opposed to markdown one.

I have added suitable samples to the wiki and repo

How you can keep using Lab Management after a move to VSTS (after a fashion)

I have posted on previously how we used TFS Lab Management to provision our test and development environments. With our move to VSTS, where Lab Management does not exist, we needed to look again at how to provision these labs. There are a few options…

Move to the Cloud – aka stop using Lab Management

Arguably the best option is to move all your lab VMs up to the cloud. Microsoft even has the specific service to help with this Azure DevTest Labs. This service allows you to create single VMs or sets of VMs for more complex scenarios using of ARM templates.

All good it seems, but the issue is that adoption of a cloud solution moves the cost of running the lab from a capital expenditure (buying the VM host server) to an operational cost (monthly cloud usage bill). This can potentially be a not insignificant sum; in our case we have up to 100 test VMs of various types running at any given time. A sizeable bill.

Also we need to consider that this is a different technology to Lab management, so we would need to invest time to rebuild our test environments using newer technologies such as ARM, DSC etc. A thing we should be doing, but I would to avoid doing it for all our projects today.

Now it is fair to say that we might not need all the VMs keep running all the time, better VM management could help alleviate the costs, and DevTest Labs has tools to help here, but it won’t remove all the costs.

So is there a non-cloud way?

Move to Systems Center

Microsoft’s current on premises recommended solution is to use System Center, using tasks within your build and release pipeline to trigger events via SC-VMM.

Now as Lab Management also makes use of System Center SC-VMM this might initially sound a reasonable step. Problem is that the way Lab Management uses System Center is ‘special’. It does not leverage any of the standard System Center tools really. Chances are anyone who investing time in using Lab Management makes little or no use of System Center own tools directly.

So if you want to use System Center without Lab Management you need to work in a very different way. You are into the land of System Center orchestrations etc.

So again you are looking at a new technology, this might be appealing for you, especially if you are using System Center to manage your on premised IT estate, but it was not a route I wanted to take.

Keeping Lab Management running

So the short term answer for us was to keep our Lab Management system running, it does what we need (network isolation the key factor for us), we have a library of ‘standard VMs’ built and we have already paid for the Hyper-V hosts. So the question became how to bridge the gap to VSTS?

Step 1 – Leave Lab Management Running

When we moved to VSTS we made the conscious choice to leave our old TFS 2015.3 server running. We removed access for most users, only leaving access for those who needed to manage Lab Management. This provided us with a means to start, stop, deploy  network isolated Lab Environments.

KEY POINT HERE – The only reason our on-premised TFS server is running is to allow a SC-VMM server and a Test Controller to connect to it to allow Lab Management operations.

image

Another important fact to remember is that network isolation in each labs is enabled by the Lab Test Agents running on the VMs in the Lab; so as well as communicating with the Test Controller the agents in the environments also manage the reconfiguration of the VMs network adapters to provide the isolation. Anything we do at this point has to be careful not to ‘mess up’ this network configuration.

Problem is you also use this Test Agent to run your tests, how do you make sure the Test Agent runs the right tests and send the results to the right place?

We had already had to build some custom scripts to get these agents to work the TFS vNext build against the on-prem TFS server. We were going to need something similar this time too. The key was we needed to be able to trigger tests in the isolated environment and get the results back out and up to VSTS all controlled within a build and release pipeline.

We came up with two options.

Option 1 Scripts

First option is to do everything with PowerShell Scripts Tasks within the release process.

image

  1. Copy the needed files onto the VM using the built in tasks
  2. Use PowerShell remoting to run MSTest (previously installed on the target VM) – remember you have to delete any existing .TRX result file by hand, it won’t overwrite.
  3. Copy the test results back from the VM (RoboCopy again)
  4. Publish the test results TRX file using the standard VSTS build task for that job.

There is nothing too complex, just a couple of PowerShell scripts, and it certainly does not effect the network isolation.

However, there is a major issue if you want to run UX tests. MSTest is running on a background thread, so your test will fail it cannot access the UI thread.

That said, this is a valid technique as long as either

  • Your tests are not UX based e.g. integration tests that hit an API
  • You can write your UX test to use Selenium PhantomJS

Option 2 do it the ‘proper’ VSTS way

VSTS has tasks built in to deploy a Test Agent to a machine and run tests remotely, including UX tests. The problem was I had assumed these tasks could not be used as they would break the network isolation, but I thought I would give it  try anyway. That is what test labs are for!

image

Inside my release pipeline I added

  1. Copy the needed files onto the VM using the built in tasks, as before
  2. A deploy Test Agent Task
  3. Run functional tests Task, which also handles the publish

When this was run the deploy Test Agent task de-configures (and removes) the old TFS 2015 Test Agent put on by Lab Management and installs the current version. However, and this is important, it does not break the network isolation as this is all setup during VM boot and/or repair. The Lab will report itself a broken in the Lab Management UI as the Test Agent will not be reporting to the Test Controller, but it is still working

Once the new agent is deployed, it can be used to run the test and the results get published back to VSTS, whether they be UX tests or not.

If you restart, redeploy, or repair the Network Isolated environment the 2015 Test Agent gets put back in place, so making sure the network isolation is fixed.

Conclusion

So Option 2 seems to deliver what I needed for now

  • I can use the old tech to manage the deployment of the VMs
  • and use the new tech to run my tests and get the results published to the right place.

Now this does not means I should not be looking at DevTest Labs to replace some of my test environments, also Azure Stack might provide an answer in the future.

But for now I have a workable solution that protects my past investments while I move to a longer term future plan.

New version of my Parameters.Xml Generator Visual Studio add-in now supports VS2017 too

I have just published Version 1.5 of my Parameters.Xml Generator Visual Studio add-in . After much fiddling this VSIX now supports VS2017 as well as VS2013 and VS2015.

The complexity was that VS2017 uses a new VSIX format, V3. You have to makes changes to the project that generates the VSIX and to the VSIX manifest too. The FAQ says you can do this within VS2015 my hand, but I had no luck getting it right. The recommended option, and the method I used, is to upgrade your solution to VS2017 (or the RC at the time of writing as the product has not RTM’d yet).

This upgrade process is a one way migration, and you do have to check/edit some key items

  • Get all your references right, as I was using the RC of VS2017  this meant enabling the use of Preview packages from Nuget in the solution.
  • Makes sure the install targets (of Visual Studio) match what you want to install too
  • Add prerequisites (this is the big new addition in the VSIX 3 format)
  • And the one that stalled me for ages – Make sure you reference the right version of the Microsoft.VisualStudio.Shell.<VERSION>.dll . You need to pick the one for the oldest version of Visual Studio you wish to target. In my case this was Microsoft.VisualStudio.Shell.12.0.dll. For some reason during the migration this got changed to Microsoft.VisualStudio.Shell.14.0.dll which gave the strange effect that the VSIX installed on 2013, 2015 and 2017. But in 2013, though I could see menu item, it did not work. This was fixed by referencing the 12.0 DLL .

Can’t add users to a VSTS instance backed by an Azure Directory

I have a VSTS instance that is backed by an Azure Directory. This is a great way to help secure a VSTS instance, only users in the Azure Directory can be added to VSTS, not just any old MSA (LiveIDs). This is a directory that can be shared with any other Azure based services such as O365, and centrally managed and linked to an on-premises Active Directory.

When I tried to add a user to VSTS, one that was a valid user in the Azure Directory, their account did not appear in the available users drop down.

 image

Turns out the problem was who I was logged in as. As yo can see from the screenshot I have three Richard accounts in the VSTS instance (and Azure Directory), a couple of MSAs and a guest work account from another Azure Directory. I was logged in as the guest work account.

All three IDs as administrators in VSTS, but it turned out I needed to be logged in as the MSA that owned the Azure subscription contains the Azure Directory. As soon as I used this account the dropdown populated as expected and I could add the users from the Azure Diretcory

image

Debug your Bot with Visual Studio debugger

I previously posted using ngrok to debug your Node/C# bot, and mentioned that you can also use the Visual Debugger under certain circumstances.

These circumstances are:

  • You are using the .NET Bot Builder
  • You are using Azure which supports remote debugging
  • You have a DLL that contains debugging information - typically this means a Debug build

If all these are true then you can download the Azure SDK and attach your local Visual Studio environment to the remote process.

See how in this short video:

Creating Website Slots and SQL Elastic Pools using Azure Resource Templates

Recently I have been helping a number of organisations automate the deployment of their applications to Azure and came across a couple of scenarios that were not documented: Deploying an App Services web site with slots and SQL connection string settings, and the creation of a SQL Elastic Pool. Of those, the SQL Elastic Pool I found to be written up already by Vincent-Philipe Lauzon and all credit to him - my template draws on his excellent article.

The Web slots and configuration, however, I didn't find. There are templates that deploy a web site, and some that deploy configuration settings into that web site (indeed, creating a new Web+SQL template through Visual Studio does just that). However, I could find none that deployed slots and none that added the config to the slot.

You can find the full template in my GitHub Repo. The template code to deploy a slot and associated config is shown below. This sits in the nested resources bock within the website resource, for reference.

The trick with the config, as it turns out, is the resource type. If you examine the connectionStrings node within a slot through Resource Explorer you will see it reported as Microsoft.Web/sites/config. However, if you click the PowerShell tab for the same note you will see the type reported as Microsoft.Web/sites/slots/config. Make sure that the resource name matches the config section (i.e. connectionStrings - or appsettings, etc).

{
          "apiVersion": "2015-08-01",
          "name": "[concat(variables('website').websiteName, '/', variables('website').slotName)]",
          "type": "Microsoft.Web/Sites/slots",
          "location": "[resourceGroup().location]",
          "dependsOn": [
            "[concat('Microsoft.Web/Sites/', variables('website').websiteName)]"
          ],
          "tags": {
            "displayName": "Slot"
          },
          "properties": {
          },
          "resources": [
            {
              "apiVersion": "2015-08-01",
              "name": "[concat(variables('website').websiteName, '/', variables('website').slotName, '/connectionStrings')]",
              "type": "Microsoft.Web/Sites/slots/config",
              "location": "[resourceGroup().location]",
              "dependsOn": [
                "[concat('Microsoft.Web/Sites/', variables('website').websiteName, '/slots/', variables('website').slotName)]"
              ],
              "tags": {
                "displayName": "SlotConnectionStrings"
              },
              "properties": {
                "DefaultConnection": {
                  "value": "[concat('Data Source=tcp:', reference(concat('Microsoft.Sql/servers/', variables('sqlServer').name)).fullyQualifiedDomainName, ',1433;Initial Catalog=', variables('sqlServer').stagingDbname, ';User Id=', parameters('sqlAdminLogin'), '@', variables('sqlServer').name, ';Password=', parameters('sqlAdminPassword'), ';')]",
                  "type": "SQLServer"
                }
              }
            }
          ]
        }

Use NuGet with Azure Functions

Azure Functions are "serverless" pieces of functionality. You can take your existing C# or JavaScript code and it becomes a single unit of maintenance, upgrade, scale etc.
One of the key differences is the way that code is authored out of the box - although you can use an IDE like Visual Studio you can also use the browser as your IDE.
There are a few nuances that you need to be aware of - such as adding NuGet packages.
It's easy once you know how though! see how you can do this in this short video.


The configuration I pasted in to my project.json is here:

{
 "frameworks": 
 {  
  "net46":
  { 
   "dependencies":
   {
    "Newtonsoft.Json" : "9.0.1" 
   }
  }
}

Debug your Bot with ngrok

Once you have deployed your Bot to Azure, what do you do if you need to debug or diagnose any issues with the Bot code?

If you are using the .NET Bot Builder you can use the Visual Studio remote debugger and attach your local debugger in Visual Studio to the remote process.  Azure supports this but other hosting providers do not, and of course your Bot needs to be .NET and you need to have debugging symbols available. 

What do you do if:

  • you are using Node?
  • or, do not have debugging symbols?
  • or, hosting your Bot application with a provider that doesn’t support the VS Remote Debugger?

Well you are in luck because you can use ngrok to deal with all these constraints. 

Ngrok provides a secure tunnel to your local machine via a publicly accessible endpoint.

In this short video see how you can use it to debug your Bot application locally. ngrok will work with any language/any technology using common transport protocols (like HTTP).

So, to summarise:

  1. Download ngrok from https://ngrok.com/
  2. Extract the zip file to a folder of your choosing.
  3. Open a command prompt in the above folder, and run
    ngrok http 80
    (change 80 to the local port you want to expose)
  4. Change your client application to point to the ngrok.io endpoint
  5. Test and debug!

Version 2.0.x of my Generate Release Notes VSTS Task has been released with release rollup support

I have just released a major update to my Generate Release Notes VSTS Build extension. This V2 update adds support to look back into past releases to find when there was a successful release to a given stage/environment and creates a rollup set of build artifacts, and hence commits/changesets and workitems, in the release notes.

 

 

This has been a long running request on GitHub for this extension which I am pleased to have been able to address.

To aid backwards compatibility, the default behaviour of the build/release tasks is as it was before, it can be used in a build or in and release, and if in a release it only consider the artifacts in the current release that ran the task.

If you want to use the new features you need to enable them. This is all on the advanced properties

 

image

 

You get new properties to enable scanning past releases until the task find a successful deployment to, by default, the same stage/environment that is currently being released too. You can override this stage name to allow more complex usage e.g. generating the releases notes for what is changed since the last release to production whist in a UAT environment.

This change also means there is new variable that can be accessed in templates, this $Releases which contains all the releases being used to get build artifacts. This can be used on release notes to show the releases being used e.g.

 

**Release notes for release $defname**
**Release Number**  : $($release.name)   
**Release completed** $("{0:dd/MM/yy HH:mm:ss}" -f [datetime]$release.modifiedOn) **Changes since last successful release to '$stagename'**  
**Including releases:**  
$(($releases | select-object -ExpandProperty name) -join ", " )  

 

Generating a content

 

Release notes for release Validate-ReleaseNotesTask.Master
Release Number : Release-69 
Release completed 05/01/17 12:40:19
Changes since last successful release to 'Environment 2' 
Including releases: 
Release-69, Release-68, Release-67, Release-66 

 

Hope you find this extension useful