Where Continuous delivery for web applications on Azure is becoming quite popular and common I couldn’t find anything about settting this up for your API definitions in Azure API management. Since i had to set this up at my current customer I thought it was a good idea to share this in a blogpost so everyone can enjoy it. In this blogpost i’ll explain how you can set up Continuous delivery of your API definitions in Azure API management including the actual API implementation in Azure Web apps using VSTS (Visual Studio Team Services)
First let me explain the architecture we use for our API landscape. As explained we use Azure API management for exposing the APIs to the outside world and we use Azure Web Apps for hosting the API implementation. These Web apps (Both .Net Core and Full framework .Net Web APIs) are hosted in an ASE (App Service Environment) so they are not exposed directly to the internet while we can still use all the cool things Azure Web Apps offer. These API web apps then connect to datastores hosted in Azure or connect to the on premise hosted environments through an express route or VPN.
To be able to set up our Continuous Delivery pipeline we have to arrange the following things.
- Build your API implementation so we have a releasable package
- Create infrastructure to host the API implementation
- Deploy the API implementation package to the newly created infrastructure
- Add API definition to Azure API management.
- Repeat above steps for each environment. (DTAP)
Building your App
The first step can be different from my example if you’re not building your APIs using .Net technology. In our landscape we have a mix of APIs made with .Net Core and APIs made with .Net Full Framework because they needed libraries that were not available in .Net Core (yet). I’m not going into details on how to build your API using VSTS because i’ll assume you’re already doing this or you know how to do this. If not here is a link to the official documentation.
One thing to keep in mind is that your API web app does have to expose a API definition so Azure API Management can import this. We use Swashbuckle for this to automatically generate a swagger definition. If you’re using .Net Core you’ll have to use Swashbuckle.AspNetCore
Deploying the API implementation & adding it to Azure API management
For automating the deployments we’re going to the use Release Management feature of VSTS. In our first environment we’ll create steps to do all the things we described above.
The steps in our workflow are the following:
- Create web application infrastructure by rolling out an ARM template
- Set environment specific variables
- deploy the API implementation package
- Use a task group to add the API definition to Azure API management.
Creating the web app infrastructure & deploying the API Implementation package
the first and third steps are the basic steps of deploying a web application to Azure web apps. This is no different for APIs so i’ll just link to an existing blogpost here that explains these if you don’t know what they do.
Setting environment specific variables
the second task is a custom task created by my colleague Pascal Naber. It can help you overwrite specific variables you want to use in your environments by storing these settings as App Settings on your Azure web app. We use this to set the connection strings to backend systems for example a Redis Cache or a database.
Add API to API Management
So if we release the first 3 steps we would have an API that would on it’s own. But the main reason of this blogpost was that we want to have our API exposed through Azure API management so let’s have a look on how we can do that.
Azure API management has Powershell commands to interact with it and we can use this to add API definitions to Azure API management too. Below is a sample piece of Powershell that can import such an API definition from a Swagger file.
The script is built up out of 3 parts: first we retrieve the API management context by using the New-AzureRmApiManagementContext Commandlet. When we’ve gotten a context we can use this to interact with our API management instance. The second part is retrieving the swagger file from our running Web app through wget which is short for doing a GET web request. We’ll download the swagger file to a temporary disk location because in our case our web apps are running in an ASE and therefore are not accessible through the Internet. if your web apps are connected to the internet you can also directly use the URL in the 3rd command to import the Swagger file into Azure API Management. Import-AzureRmApiManagementApi.
So now we have a script that we can use to import the API let’s add it to the VSTS release pipeline we could just add the powershell script to our source control and call the powershell using the build in powershell task. I’d like to make the developers’ life in our dev teams as easy as possible so i’m tried to abstract all Powershell mumbo jumbo away from them so they can focus on their APIs. To do this i’ve created a “Task Group” in VSTS containing this Powershell task so developers can just pick the “Add API to API Management Task” from the list in VSTS and supply the necessary parameters.
When we add this task group to the release we can run our release again and the API should be added to Azure API Management.
Success!! Our initial continuous delivery process is fixed. At my current client we have 4 different API management instances and we also deploy our APIs 4x. A Development, Test, Acceptance and Production instance. The workflow we created deploys the API to our development environment. We’ve set this up to be continuous so every time a build completes on the master branch we create a new release that will deploy a new API instance to Azure and will update our Development Azure API management instance.
We can now clone this environment 3x so we create a pipeline that will move from dev, test to acceptance and production. I always set the trigger to automatically after the previous environment is completed. if we run our release again we’ll have 4 API instances deployed and in all 4 Azure API management instances they corresponding API will be imported.
Now the only thing you have to add is optionally adding integration tests to the environment you prefer and you are ready to roll!
Geert van der Cruijsen
December 11, 2017 at 20:49
I followed your steps, but got this error:
Import-AzureRmApiManagementApi : The requested resource does not support http method ‘PUT’.
Would you know how to solve this, when ‘Enable API Management REST API’ is already checked in APIM portal?
April 27, 2018 at 13:13
Did you ever get this working? i’m seeing the same error:
The requested resource does not support http method ‘PUT’.
May 15, 2018 at 11:03
I am having the same error. Did you manage to fix it, Pinaki?
February 21, 2018 at 18:04
Great explanation, thank you!
It turns out any time the job runs, it flushes the URL of the API backend in the config of the API Management.
So I assumed some parameter of the Import-AzureRmApiManagementApi command was missing. But then in Microsoft doc, it seems like this command doesn’t come with a setting to define the API URL.
February 23, 2018 at 10:30
ok my bad, I was just missing the host properties in my swagger.json. This has been solved with swashbuckle.
March 21, 2018 at 12:45
Sorry for the late reply. It should be in your swagger file right?