Clean Install from Azure DevOps

When you perform an incremental ARM template release via Azure DevOps, you run into the risk that manual adjustments to logic apps or other artifacts like servicebus subscriptions are overlooked. For that reason it’s a good idea to always start from a clean canvas. As all of your resources are added to a resource group, the easiest approach would be to delete the resource groups in your project. Be careful. Authorizations granted at the resource level will be removed along with the resource group. This could be an undesirable side effect. The easy solution to that would be to remove all resources in the resource group instead of removing the resource group itself.

The good news is that resource groups referred to in a release pipeline are automatically recreated when they don’t exist. That means, resource groups can safely be deleted. It also means, you don’t have to run an ARM template to create a resource group. There’s one very important assumption here. The account under which the pipeline runs, must have Contributor rights in your subscription. It’s not enough to be Contributor at the resource group level. I mention the fact, because Developers are typically in a group with contributor rights to one or more resource groups. That means you wouldn’t be able to recreate reource groups when your pipelines were running under a Developer account.

So, how we can find the account under which the pipeline runs. If you go to Azure DevOp / Project / Project Settings, you will find an option to add one or more service connections. Typically you will make a service connection for Non-Production and a service connection for Production.  See also: https://docs.microsoft.com. When you select one of the service connections, you will get to the screen below.

From this screen you can click [Manage Service Principal]. Now you will get to a screen where the related service principal is shown.

You can lookup the service principal in Azure Active Directory under App Registrations. As a developer, you will have limited rights in Azure Active Directory. So, first I opened my (non-production/production) subscription. If you select Access Control / Role Assignments, you will find the service principal has Contributor rights at the subscription level. You can do the same for the o/t/a/p resource groups. Select Access Control / Role Assignments and you will  find the service principal has Contributor rights at the resource group level.

Using AzureCLI in DevOps

To create a table and perform a set of inserts, you can use the Azure CLI action in a DevOps Release pipeline. Reference the script and pass your arguments, like so:

StorageTableCreate.cmd:

call az storage table create –name %1 –account-name %2

call az storage entity insert –table-name %1 –account-name %2 –entity PartitionKey=[systema] RowKey=system Active=true Active@odata.type=Edm.Boolean LastRevision=1000000 LastRevision@odata.type=Edm.Int32 –if-exists fail

call az storage entity insert –table-name %1 –account-name %2 –entity PartitionKey=[systemb] RowKey=system Active=true Active@odata.type=Edm.Boolean LastRevision=1000000 LastRevision@odata.type=Edm.Int32 –if-exists fail & exit 0

Note that the first statement doesn’t end with ‘exit 0’. This means that the next insert statement will be processed, regardless of the result of the first insert. This means: a record will be added if a record for that system doesn’t exist yet. 

Using private NuGet Feed

If you want to use custom assemblies as NuGet packages in Visual Studio and your DevOps pipelines, you will have to add your assembly to the Assemblies folder in DevOps (dev.azure.com) first.

In DevOps, select  Assemblies, Connect to Feed  and click Visual Studio, you will see the path you need under Source. For example:

https://pkgs.dev.azure.com/%5Bcustomer%5D/_packaging/Shared%40Local/nuget/v3/index.json

Next you can go to Visual Studio:

  • Go to Tools > NuGet Package Manager > Package Manager Settings, select Package Manager Sources and then click the + button.
  • Choose feed Name (i.e. client shared), set the feed URL to the URL mentioned above.

Web App Configuration


You can store the application setting for an Azure Web App at two places: in the web.config and in the Azure Portal (under Configuration). Not being aware of the second option, I used Kudu to look up the web.config file to find out that the appSettings were wrong. So I looked up the release pipeline to see how environment variables were used. In the Deploy Azure App Service task, you can specify the AppSettings under Application and Configuration Settings.

I didn’t specify the Configuration Settings, so I thought I would be able to change the web.config after doing so. Unfortunately that didn’t work. Then I found the following article on docs.microsoft.com that pointed me in the right direction: variable substitution. You can change AppSettings and Connection Strings in the web.config by enabling XML variable substitution in the release pipeline task.

Parameterizing Azure Artifacts

The traditional approach to parameterize logic apps and/or API Management services is to use parameter files. The disadvantage of using parameter files, is that you need developer assistance when you want to change the configuration. That’s no good because changing configuration is typically an operator’s responsibility, not a developer’s responsibility.

As an alternative to parameter files, you can use variable groups in your DevOps release definition. Variable groups can be maintained by operators who have access to your DevOps team project. Variable groups are better than pipeline variables, because variable groups can be reused across release definitions. You can for instance create a variable group to hold the API Management instance name and Application Insights resource for reuse across all API Management service releases. Below, the release definition in Accept is shown first. As you see, the ACC release contains only one step: Azure ResourceGroup Deployment. The setting that sets the variables is named Override Template Parameters. Next the definition of the variable group is shown.

Note that when you use DevOps to release an API Management service, you will have to use named values in addition to variable groups.

Troubleshooting DevOps Release Failures

When you use the DevOps release pipeline, it can sometimes be hard to understand the failure messages. Example:

In that case, you can go to the resource group in the Azure Portal and select menu option Deployments. You will find a line for the same error. The extra information helped me out a few times.

From the failure details you can tell something is wrong with the Application Insights resource connect-acc/authorizationservice/applicationinsights. The error message is: “Logger Id ‘\”cito-connect-test’ does not exist.

In this case the message is still rather cryptic. The issue in this case turned out to be, that I didn’t close the ApplicationInsights variable correctly with a double quote. This happened in task Azure Resource Group Deployment, Override Template Parameters.

-apimServiceName “$(apimServiceName)” -apimServiceName_applicationInsights “$(applicationInsights)

Release versioned APIM Service via VSTS

I received an error when releasing a ARM template for a versioned API Management Service that I created via the APIManagementARMTemplateCreator. To be able to release a versioned API Management service, you will have to add a versionset resource to the ARM template. For example:

"resources": [
    {
      "type": "Microsoft.ApiManagement/service/api-version-sets",
      "name": "[concat(parameters('apimServiceName'), '/', parameters('versionset_name'))]",
      "apiVersion": "2018-06-01-preview",
      "properties": {
        "displayName": "[parameters('api_customerservicecrm_displayname')]",
        "description": "version set",
        "versioningScheme": "Segment",
        "versionQueryName": "api-version",
        "versionHeaderName": "api-version"
      }
    },

Note that the versionnumber is added to the URL path. In that case versioningScheme has to be set to Segment. Other options are Query (for query parameter) or Header. Because you set versioningScheme to Segment, settings versionQueryName and versionHeaderName are not used. Probably they can actually be removed. 

In the Versionset definition a few parameters are used that have to be added to the Parameters section. Note that you have to put square brackets around the parameters in the versionset definition:

"api_customerservicecrm_displayname": {
      "type": "string",
      "defaultValue": "CustomerServiceCRM” 
}

"versionset_name": {
      "type": "string",
      "defaultValue": "versionset" 
}

Finally you will have to add a DependsOn statement at the end of the ARM template. The service depends on the version set, so you will have to add a line.

"dependsOn": [
        //added line below
        "[resourceId('Microsoft.ApiManagement/service/api-version-sets', 
parameters('apimServiceName'), parameters('versionset_name'))]"
      ]
    }
  ],
  "outputs": {}
}  

Release pipeline subscription

I tried to create a release definition. How hard can it be? But then I suddenly found myself in the maze of DevOps security. Further complicated by the fact that I had no admin rights in Azure AD or DevOps, which in fact made me blind to find a solution.

What exactly was the problem? I tried to add an Azure Resource Deployment step to my release pipeline. When doing so, you have to specify a subscription. After choosing the subscription, I have to press [Authorize]. This gives me an error saying that I’m not authorized.

The solution to this problem is to create an Azure Resource Manager service connection. Steps:

  • Go to [client]/visualstudio.com.
  • Open your Team Project.
  • Go to Project Settings.
  • Select service connections. Add a service connection of type Azure Resource Manager. Name the service connection [subscription]-ota-spa. The acronym SPA stands for service principal application.
  • Enter subscription=[subscription]-ota and resourcegroup=[resourcegroup]-test.

Background information can be found at docs.microsoft.com. The service principal will be assigned to the Contributor role and will give API Management access to the selected Azure subscription and resource group. Effectively this means, you can add resources via the release pipeline.

One final designation. In order to be able to select the service principal in the Azure Resource Deployment step you as a user (say: paul.baars@motion10.com) must be assigned to the following DevOps roles: Release Administrators and Project Administrators.