The Azure API Management (APIM) Developer Portal is shipped with the default theme. Many customers change it to reflect the corporate branding and present the APIs in a custom way.
Technically the portal is based on the Paperbits framework which allows to redesign of the portal within the browser. The whole content is stored in a JSON file and the images are hosted on the internal blog storage of API Management.
In the real world, we often have multiple APIM environments which raises the question of how to migrate the portal from one to another environment. In this article, we’ll show how to migrate the APIM Developer Portal from one environment to another with Azure DevOps.
This article will show you how to create an Azure DevOps (YAML) pipeline and use the APIM Developer Portal tools to migrate the portal content.
Azure APIM Developer Portal is an open-source project that along with the portal files contains also the migration tools. Currently, there are two versions of the tools (v2 and v3) but in the article, we’ll use the last version which is located in the “scripts.v3” folder. The folder contains several Node.js scripts and batch files for the migration.
Note that in the folder you can find migrate.js and migrate.bat files that enable to migrate of the portal with only one command. It worked well when I did the migration locally where my Azure account had enough permissions to proceed with the migration. However, in my Azure DevOps environment, I had only Service connections for the source and destination (target) subscriptions so the migration had to be done in another way. Instead of one migrate command we’ll use multiple commands that allow us to proceed with the migration step-by-step.
The commands we’ll need to execute in the order are:
Fair enough, let’s create an Azure DevOps pipeline with those commands to proceed with the migration.
Now let’s see how to create the YAML pipeline. As mentioned we need to execute three commands – capture, cleanup and generate. The pipeline has to capture the data from the source APIM Developer Portal, clean up the destination (portal) and generate content for the destination APIM Developer Portal. Recently a new option (–publish true) has been added to the generate command. With this option we can publish the portal right after the content is generated.
The source code below contains the Azure DevOps pipeline (YAML). It will execute all the tasks necessary for the migration of the Azure API Management Developer portal from one APIM instance to another. I’ll explain all the pipeline variables later in the article.
name: APIM_DeveloperPortalMigration trigger: none variables: location: northeurope sourceServiceConnection: <source_service_connection> destServiceConnection: <destination_service_connection> sourceSubscriptionId: <source_subscription_id> destSubscriptionId: <destination_subscription_id> sourceResourceGroupName: <source_apim_instance_resource_group> destResourceGroupName: <destination_apim_instnace_resource_group> sourceServiceName: <source_apim_instance_name> destServiceName: <destination_apim_instance_name> jobs: # All tasks on APIM Developer portal pipeline - job: Deploy_APIM_Developer_Portal displayName: Deploy APIM Developer portal from one APIM instance to another APIM instance Migration pool: vmImage: ubuntu-latest timeoutInMinutes: 90 steps: - task: Npm@1 displayName: Npm Install command inputs: command: "install" workingDir: 'portal/scripts.v3' - task: AzureCLI@2 displayName: Capturing source portal inputs: azureSubscription: $(sourceServiceConnection) scriptType: 'pscore' workingDirectory: 'portal/scripts.v3' scriptLocation: 'inlineScript' inlineScript: 'node ./capture --subscriptionId $(sourceSubscriptionId) --resourceGroupName $(sourceResourceGroupName) --serviceName $(sourceServiceName)' - task: AzureCLI@2 displayName: Cleaning up destination portal inputs: azureSubscription: $(destServiceConnection) scriptType: 'pscore' workingDirectory: 'portal/scripts.v3' scriptLocation: 'inlineScript' inlineScript: 'node ./cleanup --subscriptionId $(destSubscriptionId) --resourceGroupName $(destResourceGroupName) --serviceName $(destServiceName)' - task: AzureCLI@2 displayName: Generating destination portal inputs: azureSubscription: $(destServiceConnection) scriptType: 'pscore' workingDirectory: 'portal/scripts.v3' scriptLocation: 'inlineScript' inlineScript: 'node ./generate --publish true --subscriptionId $(destSubscriptionId) --resourceGroupName $(destResourceGroupName) --serviceName $(destServiceName)'
To migrate the APIM Developer Portal from source to destination APIM instance the following parameters (in angle brackets) should be specified:
<source_service_connection> – service connection in Azure DevOps allows accessing resources in the source subscription
<destination_service_connection> – service connection in Azure DevOps allowing to access resources in the destination subscription
<source_subscription_id> – subscription id of the source APIM instance
<destination_subscription_id> – subscription id of the destination APIM instance
<source_apim_instance_resource_group> – resource group name of the source APIM instance
<destination_apim_instnace_resource_group> – resource group name of the destination APIM instance
<source_apim_instance_name> – name of the source APIM instance
<destination_apim_instance_name> – name of the destination APIM instance
Let’s prepare a workspace in the Azure DevOps repository. Firstly I’ve created a “portal” folder where we’ll keep all portal-related files and migration tools. I’ve cloned the APIM Developer portal GitHub repository to my local disk and the then I’ve copied the folder “scripts.v3” folder. After I’ve created my Azure DevOps YAML pipeline and pushed it to the portal folder. In the end, we will commit and push the files to the Azure DevOps repository so the structure on the Azure DevOps repository looks something like this:
After the files are in the Azure DevOps repository all you need to find the YAML pipeline file in the Azure DevOps and execute it. If everything is configured correctly and the service connections have sufficient permissions, the portal content will be migrated between the Azure APIM instances.
It might happen that the destination portal should use the different URLs (custom domains) that are attributed by default to the APIM instance. In that case, we can add our pipeline one more task and call updatecontenturl command:
- task: AzureCLI@2 displayName: Updating destination urls inputs: azureSubscription: $(destServiceConnection) scriptType: 'pscore' workingDirectory: 'portal/scripts.v3' scriptLocation: 'inlineScript' inlineScript: 'node ./updatecontenturl --subscriptionId $(destSubscriptionId) --resourceGroupName $(destResourceGroupName) --serviceName $(destServiceName) --existingEnvUrls $(existingEnvUrls) --destEnvUrls $(destEnvUrls)'
You’ll need to add two new variables to the variable list:
If multiple URLs are specified the number and order of URLs must match the existing destination list.
That’s it. The last version of the tools has made migration easier. The migration commands are well documented in their source files so do not hesitate the check them.