Recently, Donovan asked me to work with Dynatrace getting their unbreakable pipeline working with VSTS and Azure. The concept is like this: Use Dynatrace to monitor your environments and protect your pipeline with the monitoring. With Dynatrace you can define exactly what you want to monitor as well as the thresholds for what you are monitoring in a json file. Monitoring as code. So they way this unbreakable pipeline works is after releasing to an environment, we send that monspec file to dynatrace where it will check and see if the newly deployed code is breaking any monitoring thresholds. And if it is breaking something, block the release.
This sounded like the perfect use case for the Release Gates in VSTS! So I set out to build a post release release gate that would send the monspec to Dynatrace to see if there were any violations. And if there were, fail the gate.
I built out the gate using a REST api and hosted it in Azure App Service and everything worked great. After release to an environment, VSTS would trigger my REST api where it would grab the correct monspec file from source control, query Dynatrace with it and from the result, it would look at the number of violations and if the number was greater than 0, it would fail the vsts gate. Since the query potentially could take a “long’” time, I made the gate an async gate.
Next, after talking with Donovan, we decided that it really made more sense to have the gate as an Azure function instead of a REST api hosted in Azure App Service. The biggest reason is that with functions, you only get charged when the function runs. While Azure App Service, you get charged for the app service!
And here is where things became interesting. From Visual Studio, I File > New projected an azure function project. Next, i tried to add the nuget package Microsoft.TeamFoundation.DistributedTask.WebApi (this package is needed to write VSTS gates) and got this error:
Oh… ok… looks like there is a version mismatch between the Microsoft.NET.Sdk.Functions (Azure functions) library and Microsoft.TeamFoundation.DistributedTask.WebApi (VSTS gate stuff). They are both using Newtonsoft.Json… except… they are using different versions. Long story short. I tried a million different things and nothing worked. I pinged the product group and this is a known bug and it will be addressed soon. In the mean time, I still needed a work around. I decided the easiest thing to do was downgrade my Microsoft.TeamFoundation.DistributedTask.WebApi nuget package to something that still used newtonsoft.Json version 9.0.1. The first one that did was Microsoft.TeamFoundation.DistributedTask.WebApi version 15.133.0.
Except now, when my function get’s triggered, I get this error when I try to get the TaskHttpClient from VSTS
The error message is:
{“Error converting value \”Microsoft.TeamFoundation.ServiceIdentity;9876b697-b002-4d00-b24c-ab4d4c70f519:Build:2c6ac193-6c0f-40bb-a5cf-a16ed793d100\” to type ‘Microsoft.VisualStudio.Services.Identity.IdentityDescriptor’. Path ‘authenticatedUser.descriptor’, line 1, position 201.”}
What the what?????
After a lot of googling and talking with the product group, I found this article.
TLDR
Add this to the beginning of your function:
TypeDescriptor.AddAttributes(typeof(IdentityDescriptor), new TypeConverterAttribute(typeof(IdentityDescriptorConverter).FullName));
TypeDescriptor.AddAttributes(typeof(SubjectDescriptor), new TypeConverterAttribute(typeof(SubjectDescriptorConverter).FullName));
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
And… voila. Everything started working again.
Writing Async Release Gates for VSTS Using Azure Functions
Recently, Donovan asked me to work with Dynatrace getting their unbreakable pipeline working with VSTS and Azure. The concept is like this: Use Dynatrace to monitor your environments and protect your pipeline with the monitoring. With Dynatrace you can define exactly what you want to monitor as well as the thresholds for what you are monitoring in a json file. Monitoring as code. So they way this unbreakable pipeline works is after releasing to an environment, we send that monspec file to dynatrace where it will check and see if the newly deployed code is breaking any monitoring thresholds. And if it is breaking something, block the release.
This sounded like the perfect use case for the Release Gates in VSTS! So I set out to build a post release release gate that would send the monspec to Dynatrace to see if there were any violations. And if there were, fail the gate.
I built out the gate using a REST api and hosted it in Azure App Service and everything worked great. After release to an environment, VSTS would trigger my REST api where it would grab the correct monspec file from source control, query Dynatrace with it and from the result, it would look at the number of violations and if the number was greater than 0, it would fail the vsts gate. Since the query potentially could take a “long’” time, I made the gate an async gate.
Next, after talking with Donovan, we decided that it really made more sense to have the gate as an Azure function instead of a REST api hosted in Azure App Service. The biggest reason is that with functions, you only get charged when the function runs. While Azure App Service, you get charged for the app service!
And here is where things became interesting. From Visual Studio, I File > New projected an azure function project. Next, i tried to add the nuget package Microsoft.TeamFoundation.DistributedTask.WebApi (this package is needed to write VSTS gates) and got this error:
Oh… ok… looks like there is a version mismatch between the Microsoft.NET.Sdk.Functions (Azure functions) library and Microsoft.TeamFoundation.DistributedTask.WebApi (VSTS gate stuff). They are both using Newtonsoft.Json… except… they are using different versions. Long story short. I tried a million different things and nothing worked. I pinged the product group and this is a known bug and it will be addressed soon. In the mean time, I still needed a work around. I decided the easiest thing to do was downgrade my Microsoft.TeamFoundation.DistributedTask.WebApi nuget package to something that still used newtonsoft.Json version 9.0.1. The first one that did was Microsoft.TeamFoundation.DistributedTask.WebApi version 15.133.0.
Except now, when my function get’s triggered, I get this error when I try to get the TaskHttpClient from VSTS
The error message is:
{“Error converting value \”Microsoft.TeamFoundation.ServiceIdentity;9876b697-b002-4d00-b24c-ab4d4c70f519:Build:2c6ac193-6c0f-40bb-a5cf-a16ed793d100\” to type ‘Microsoft.VisualStudio.Services.Identity.IdentityDescriptor’. Path ‘authenticatedUser.descriptor’, line 1, position 201.”}
What the what?????
After a lot of googling and talking with the product group, I found this article.
TLDR
Add this to the beginning of your function:
TypeDescriptor.AddAttributes(typeof(IdentityDescriptor), new TypeConverterAttribute(typeof(IdentityDescriptorConverter).FullName));
TypeDescriptor.AddAttributes(typeof(SubjectDescriptor), new TypeConverterAttribute(typeof(SubjectDescriptorConverter).FullName));
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
And… voila. Everything started working again.