1

I have a powershell script that runs within my Azure Devops Release Pipepline for my API which uses the swagger doc from my API to automatically push changes into APIM.

The missing step is that once I have made the revisions, I need to update the developer portal with the latest schema and specifications. I can't have a developer going out and clicking the publish button every time we do a release.

According to this post I can get a token with a user id (not sure what userid it wants, I'm using a service principal) and do a post, but I was hoping there was an available utility in a module like I have been using for the rest of my script.

param([string]$subscriptionId = "", [string]$resourceGroup = "", [string]$apimName = "", [string]$apiId = "", [string]$swaggerJsonPath = "", [string]$apiPath = "", [string]$baseApiUrl = "", [string]$version = "")

$ErrorActionPreference = 'Stop'

# Install-Module -Name Az -AllowClobber -Scope CurrentUser
Import-Module Az

$ctx = Get-AzContext

if ($subscriptionId -eq '')
{
    $subscriptionId = $ctx.Subscription.Id
}

#fix version - this will come in as a build number with periods, which are not allowed
#use dashes instead
$version = $version.Replace('.', '-')

Write-Output "Resource Group: ${resourceGroup}"
Write-Output "APIM Name: ${apimName}"
Write-Output "Api Id: ${apiId}"
Write-Output "Swagger Path: ${swaggerJsonPath}"
Write-Output "Api Path: ${apiPath}"
Write-Output "Base Api Url: ${baseApiUrl}"
Write-Output "Version: ${version}"

# Set the context to the subscription Id
Select-AzSubscription -SubscriptionId $subscriptionId

Write-Output "Subscription loaded: ${subscriptionId}"

# load the API management gateway context 
$apimContext = New-AzApiManagementContext -ResourceGroupName $resourceGroup -ServiceName $apimName

Write-Output "APIM Context"
Write-Output $apimContext

# create a new revision with the supplied version (this should be the release number)
$apiRevision = New-AzApiManagementApiRevision -Context $apimContext -ApiId $apiId -ApiRevision $version

Write-Output "API Revision"
Write-Output $apiRevision

try
{
    Write-Output "Begin API Import from Swagger"

    # import the swagger as open id spec - this will fail if the name of the api in swagger does not match the name of the api in the gateway
    $importResult = Import-AzApiManagementApi -Context $apimContext -SpecificationUrl $swaggerJsonPath -SpecificationFormat OpenApi -ApiId $apiId -Path $apiPath -ServiceUrl $baseApiUrl -ApiRevision $apiRevision.ApiRevision -ApiVersion $apiRevision.ApiVersion

    Write-Output "Api refreshed from swagger [${swaggerJsonPath}]"
    Write-Output $importResult
}
catch
{
    Write-Output 'Api Import Failure'
    Write-Output $_.Exception

    Write-Output 'Beginning Cleanup'

    #clean up the revision we made
    Remove-AzApiManagementApiRevision -Context $apimContext -ApiId $apiId -ApiRevision $version

    Write-Output "Revision ${$apiRevision.ApiRevision} removed"

    exit 10
}

# set the revision as current (release it to the public)
$apiRelease = New-AzApiManagementApiRelease -Context $apimContext -ApiId $apiId -ApiRevision $version

Write-Output "API Release"
Write-Output $apiRelease

# TODO: Publish dev portal

If there's not an already provided module, can I get a sas token using my service principal?

Josh
  • 16,286
  • 25
  • 113
  • 158

1 Answers1

3

There is no built-in command in azure powershell to publish the dev portal, your option is to get the sas token with your service principal and invoke the api via powershell.

First, Make sure the setting Enable Management REST API is Yes in the azure portal.

enter image description here

Then use the commands below.

$resourceGroup = "xxxxxx"
$apimName = "xxxxxx"
$apimContext = New-AzApiManagementContext -ResourceGroupName $resourceGroup -ServiceName $apimName
$Access = Get-AzApiManagementTenantAccess -Context $apimContext
$token = (New-AzApiManagementUserToken -Context $apimContext -UserId $Access.Id).UserToken

$header = @{
    'Authorization' = 'SharedAccessSignature ' + $token
}

Invoke-RestMethod -Method Post -Uri "https://$apimName.developer.azure-api.net/publish" -Headers $header

enter image description here

After a while, check it in the portal, it works fine.

enter image description here

Joy Wang
  • 39,905
  • 3
  • 30
  • 54
  • Trying your URL, I get an error: Invoke-RestMethod : The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. – Josh Apr 21 '21 at 14:58
  • Then I tried the management API url in the screen where you enable the management API: https://${apimName}.management.azure-api.net/publish This resulted in an error about placing the api version in the querystring. So, then I added the QS value, and now it wants me to use a fully qualified path /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ApiManagement/service/{serviceName} – Josh Apr 21 '21 at 15:03
  • Okay, I figured it out. We have a custom domain on our gateway. The url we have to use is ourcustomdevportaldoman.com/publish – Josh Apr 21 '21 at 15:11