Skip to content

Pipeline Setup for OpenAPI Export and APIM Import

This guide explains how to set up your pipeline to export an OpenAPI schema and import it into Azure API Management (APIM). The provided pipeline templates for Django, FastAPI, and generic container apps all share the same configuration parameters, making setup consistent across frameworks.

Assume you already have an existing product and a pipeline running to publish your backend app.

Common Pipeline Configuration

All pipeline templates use the following key parameters:

ParameterDescription
dockerRegistryServiceConnectionService connection for your Docker registry
containerAppRegistryName of your container app registry
imageRepositoryName of your image repository
containerAppEnvironmentNameName of your container app environment
resourceGroupNameResource group for your backend app
azureResourceManagerServiceConnectionService connection for Azure Resource Manager
apiManagementResourceGroupName(Optional) Resource group where the APIM instance is located (usually API-ApiManagement).
If not provided, it is inferred from apiManagementServiceName:
equation-acceptance -> API-ApiManagement
equation-production -> API-ApiManagement-Production).
apiManagementServiceConnection(Optional) Service connection for your managed identity (e.g. Product-XXX-Acceptance-ManagedIdentity). If provided, used instead of azureResourceManagerServiceConnection for APIM auth.
apiManagementServiceNameName of the APIM instance (e.g. equation-acceptance)
apiServiceIDName of the API onboarded in APIM (usually the api_name from your Terraform file)

You will need to set up the correct service connections for Docker Registry and Azure Resource Manager. The APIM service connection can be automatically scoped and enforced using this guide.

Django Container App Example

yaml
resources:
  repositories:
    - repository: templates
      type: git
      name: Haskoning-Software-Development/pipeline_templates

jobs:
  - template: 'python/build_web_image_publish_django_container_app_task_apim.yml@templates'
    parameters:
      dockerRegistryServiceConnection: $(dockerRegistryServiceConnection)
      containerAppRegistry: $(containerAppRegistry)
      imageRepository: $(imageRepository)
      containerAppEnvironmentName: $(containerAppEnvironmentName)
      resourceGroupName: $(resourceGroupName)
      azureResourceManagerServiceConnection: $(azureResourceManagerServiceConnection)
      apiManagementServiceName: $(apiManagementServiceName)
      apiServiceID: $(apiServiceID)

FastAPI App Example

yaml
resources:
  repositories:
    - repository: templates
      type: git
      name: Haskoning-Software-Development/pipeline_templates

trigger:
  - dev

pool:
  vmImage: "ubuntu-latest"

jobs:
  - job: Deploy
    displayName: Deploy job
    steps:
      - template: python/build_function_task_apim.yml@templates
        parameters:
          serviceConnection: $(serviceConnection)
          storageAccountName: storageaccountname
          appName: $(appName)
          resourceGroupName: $(resourceGroupName)
          apiManagementServiceName: $(apiManagementServiceName)
          apiServiceID: $(apiServiceID)
          schemaGenerator: generate_schema_fastapi.py
          fastapiAppImport: app.main:app

Generic Container App Example

If you use a different framework or need to customize the export process, use the following pipeline example:

yaml
resources:
  repositories:
    - repository: templates
      type: git
      name: Haskoning-Software-Development/pipeline_templates

trigger:
  - dev

pool:
  vmImage: "ubuntu-latest"

jobs:
  - job: Build
    displayName: Build job
    steps:
      - checkout: self
      - bash: |
          set -euo pipefail
          [ -e .env.dist ] && cp .env.dist .env
          printf "\nARTIFACT_PERSONAL_ACCESS_TOKEN=%s" "$(System.AccessToken)" >> .env
          docker compose run --rm web bash -c 'python manage.py migrate && python manage.py export_openapi_schema --output openapi.json'
          docker compose down -v
          shred -u .env || rm -f .env
          test -f openapi.json || { echo "openapi.json not found"; exit 1; }
        displayName: Generate OpenAPI schema
      - template: 'python/build_web_image_publish_container_app_task_apim.yml@templates'
        parameters:
          dockerRegistryServiceConnection: $(dockerRegistryServiceConnection)
          containerAppRegistry: $(containerAppRegistry)
          imageRepository: $(imageRepository)
          containerAppEnvironmentName: $(containerAppEnvironmentName)
          resourceGroupName: $(resourceGroupName)
          azureResourceManagerServiceConnection: $(azureResourceManagerServiceConnection)
          apiManagementServiceName: $(apiManagementServiceName)
          apiServiceID: $(apiServiceID)