by DotNetNerd
13. February 2023 09:12
A nice and simple way to expose static files is through Azure blob storage. If you are already using API Management you might want to have requests to through there, in order to ensure you can move it to somewhere else in the future. It requires a few steps to get it to work though.
First of all Managed Identities should be enabled in API management and Access Control (IAM) should be configured for the container to allow API management to access the file. In API management the endpoint is added with authentication-managed-identity policy to allow authentication is passes through. After that a number of headers should be removed and the x-ms-version, which is required to do AD authentication, should be set when forwarding the request from API Management to the blob storage endpoint.
In my case I also wanted to avoid the .json extension in the endpoint, so the configuration ended up looking something like this.
<policies>
<inbound>
<set-header name="Ocp-Apim-Subscription-Key" exists-action="delete" />
<set-header name="Sec-Fetch-Site" exists-action="delete" />
<set-header name="Sec-Fetch-Mode" exists-action="delete" />
<set-header name="Sec-Fetch-Dest" exists-action="delete" />
<set-header name="Accept" exists-action="delete" />
<set-header name="Accept-Encoding" exists-action="delete" />
<set-header name="Referer" exists-action="delete" />
<set-header name="X-Forwarded-For" exists-action="delete" />
<set-header name="x-ms-version" exists-action="override">
<value>@{string version = "2017-11-09"; return version;}</value>
</set-header>
<rewrite-uri template="/settings.json" copy-unmatched-params="true" />
<authentication-managed-identity resource="https://storage.azure.com/" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
by DotNetNerd
14. December 2022 12:32
Recently I needed to update Azure Management API based on the swagger specifications when our services were deployed. It seems like a pretty standard thing that there would be a task for, but it turned out to require a bit of Powershell - it i still fairly simple though.
A general function to acccomplish it could look like this bit of code.
[CmdletBinding()]
Param(
[string] [Parameter(Mandatory=$true)] $ResourceGroupName,
[string] [Parameter(Mandatory=$true)] $ServiceName,
[string] [Parameter(Mandatory=$true)] $ApiName,
[string] [Parameter(Mandatory=$true)] $SpecificationFilePath
)
$apiMgmtContext = New-AzApiManagementContext -ResourceGroupName $ResourceGroupName -ServiceName $ServiceName
$api = Get-AzApiManagementApi -Context $apiMgmtContext -ApiId $ApiName
if ($null -eq $api) {
Write-Error "Failed to get API with name $ApiName"
exit(1)
}
$apiVersionSetId = $api.ApiVersionSetId.Substring($api.ApiVersionSetId.LastIndexOf("/")+1)
$apiVersionSet = Get-AzApiManagementApiVersionSet -Context $apiMgmtContext -ApiVersionSetId $apiVersionSetId
Import-AzApiManagementApi -Context $apiMgmtContext `
-SpecificationUrl $SpecificationFilePath `
-SpecificationFormat 'OpenApi' `
-Path $api.Path `
-ApiId $api.ApiId `
-ServiceUrl $api.ServiceUrl`
-ApiVersionSetId $apiVersionSet.Id
This can of course be used locally, but to run it from a release pipeline, the cleanest way I have found, is to add it to a separate repository, and include it as an artifact. From there we just need a Azure Powershell build step, configured as shown by the YAML below.
variables:
swaggerUrl: 'https://my_appservice.azurewebsites.net/swagger/1.0.0/swagger.json'
steps:
- task: AzurePowerShell@5
displayName: 'Azure PowerShell script: Update API Management'
inputs:
azureSubscription: 'xxx'
ScriptPath: '$(System.DefaultWorkingDirectory)/_MyCompany.BuildScripts/UpdateApiManagement.ps1'
ScriptArguments: '-ResourceGroupName "resource_group_name" -ServiceName "management_api_service_name" -ApiName "unique_api_id" -SpecificationFilePath $(swaggerUrl)'
azurePowerShellVersion: LatestVersion
And that is all that is required, to automate it and make it update along with the build. Nice and easy.