Skip to content

Add an API to Azure API Management (Product Team)

This guide describes how to onboard your API into the Equation platform. The platform handles authentication, provides access to your API through Excel add-ins and the developer portal, and enables collaboration with other teams' APIs.

INFO

You will only be able to manage your own API and backend. All permissions are automatically scoped and enforced.

  • Authentication handled for you: We manage EntraID authentication automatically
  • Excel integration: Your API becomes available through the Excel add-in
  • Developer portal access: You and others can test your APIs directly in the portal
  • Collaboration: Easily integrate with APIs from other teams I'll help you add a section explaining how to set up the backend API with the resource ID to complete the full flow. Here's the updated section:

Getting Started

Set up a Resource Group

Create a new resource group for your API project according to standard conventions.

Deploy Your Backend Service

Deploy your API backend to Azure (e.g., Azure App Service, Container Apps, or Azure Functions). You'll need:

  1. The backend URL (e.g., https://your-app.azurewebsites.net)
  2. Whitelist the APIM gateway IPs in your backend's network settings to restrict access.
  3. (Optional) The Azure Resource ID (found in the Azure Portal under "Properties" or via Azure CLI) Example Resource ID:
/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/your-rg/providers/Microsoft.Web/sites/your-app

The resource_id here is just to specify that this is the azure resource ID for the Backend. We're using IP Whitelisting to secure the backend.

Create a Managed Identity for API Management

Create a User-Assigned Managed Identity in your resource group. This identity will be used to:

  • Grant you permissions to manage your API in APIM (import OpenAPI specs, update operations, etc.)

WARNING

You may use a personal account for testing, but managed identities are strongly recommended for production.

Step 1: Add Your API Configuration

Create a pull request to the Platform Administrator's infrastructure repository:

Repository: Equation API Management Infrastructure

File to edit: acceptance/terraform.tfvars

Add your API to the apis list in the file:

yaml
# terraform.tfvars
apis = [
  {
    azure_managed_identity_object_id = ["<Managed Identity Object ID>"]
    api_name                         = "suffix"
    api_friendly_name                = "Your App Name"
    backend = {
      name        = "your-backend-name"
      description = "Backend for Your App"
      url         = "https://your-backend-url.azurewebsites.net"
      resource_id = "(optional - for Azure resources)"
    }
    api_description = "Short description of your API."
    policy_content = {
      cors_allowed_origins = [
        "https://your-frontend.azurestaticapps.net"
      ]
    }
    api_contact = {
      email = "your.email@haskoning.com"
      name  = "Your Name"
    }
    products = ["calculation-api"]
    tags     = ["visible"]
  },
  # ...add more APIs as needed...
]
FieldDescription
azure_managed_identity_object_idObject ID(s) of your Managed Identity. We assign the required roles to this identity so you can manage your API details (import OpenAPI, etc.).
api_nameLowercase suffix for your API routes. Your API will be accessible at https://apim.gateway.domain/{api_name}.
api_friendly_nameDisplay name for your API. This is the initial name; you can override this via OpenAPI import.
backend.nameUnique backend name. We use this to connect your API to the correct backend endpoint.
backend.description(Optional) Description of your backend service.
api_description(Optional) Short description of your API. Can be overridden by OpenAPI spec.
policy_content(Optional) If you prefer to modify the default policy, normally you will need policy_content.cors_allowed_origins for your frontend app. Please check policy-apim page for details.
api_contact(Optional) Contact information. Can be overridden by OpenAPI spec.
products(Optional) Products your API belongs to (e.g., calculation-api). This determines who can access your API documentatation. See below for details.
tags(Optional) Tags for your API. Use visible to make it discoverable in the inventory and Excel add-in.

Advanced Policy Configuration

By default, we handle authentication using EntraID. However, you can customize the policy behavior:

Custom JWT authentication:

yaml
policy_content = {
  jwt_openid_config_url = "https://your-idp.com/.well-known/openid-configuration"
  jwt_audiences         = ["api://your-app"]
  jwt_issuers           = ["https://sts.windows.net/your-tenant/"]
}

Additional policy options:

yaml
policy_content = {
  prefix                 = "optional-prefix"           # Add a prefix to all routes
  cors_allowed_origins   = ["https://example.com"]
  cors_allowed_methods   = ["GET", "POST"]
  cors_allowed_headers   = ["Content-Type"]
  cors_expose_headers    = ["X-Custom-Header"]
  cors_allow_credentials = "true"
  jwt_claims             = {
    "role" = ["admin", "user"]
  }
}

Note: If you need full control over policies, you can specify api_policy_file instead of policy_content to provide a custom XML policy file. However, this is not recommended as we handle all standard policies for you.

Step 2: (Optional) Manage Products and User Groups

Understanding Products and Groups

By default, there are three user groups in APIM:

  • Guest: Not recommended. Anyone can see APIs in this group without authentication.
  • Developer: All users with valid Haskoning EntraID credentials are automatically added to this group after first login.
  • Administrator: System administrators only. Not for regular use.

The calculation-api product is visible to the Developer group by default, meaning all authenticated users can see API documentation in this product.

Creating Custom Products

If you need to restrict access to certain APIs, you can create custom products and groups. Edit the products.auto.tfvars file in the infrastructure repository:

yaml
# products.auto.tfvars
api_management_product = [
  {
    display_name   = "Calculation API"
    product_id     = "calculation-api"
    product_policy = "/product_policies/calculation-api.xml.tpl"
    visibility     = ["Developer"]
  },
  {
    display_name = "Special API"
    product_id   = "special-api"
    product_policy = "/product_policies/calculation-api.xml.tpl"
    visibility   = ["G-your-team"]
  }
]

Creating Custom Groups and Adding Users

To create a custom group and assign users, edit the groups_users.auto.tfvars file:

yaml
# groups_users.auto.tfvars
api_management_groups_users = [
  {
    group_name   = "G-your-team"
    display_name = "Your Team Developers"
    description  = "Group for Your Team developers"
    users = [
      "user1@haskoning.com",
      "user2@haskoning.com"
    ]
  }
]

WARNING

Users must sign in to the developer portal at least once before you can add them to a custom group. This creates their user profile in APIM.

Managing Your API

Once your configuration is merged and deployed, the platform automatically creates:

  • Your API in APIM with the specified name and settings
  • A backend connection to your service
  • Default policies for authentication and CORS
  • Access permissions for your managed identity

You can now manage your API definition and operations.

Define Your API Operations

Your API needs to register at least one operation (endpoint) with APIM. If no matching route is found, the API gateway will return a 404 Not Found — even if your backend technically handles it.

There are two approaches to defining operations:

  1. OpenAPI Specification (Recommended): Export an OpenAPI spec from your application and import it into APIM. This automatically registers all your endpoints with proper schemas. See the OpenAPI Handling Guide for details.

  2. Wildcard Operations: Define catch-all routes like GET /* or POST /* to proxy all requests to your backend. This is simpler but less precise and may cause routing issues.

We provide a ready-to-use pipeline template that automatically exports your OpenAPI specification and imports it into APIM. This approach:

  • Ensures all endpoints are registered correctly
  • Provides accurate request/response schemas
  • Enables better API documentation
  • Reduces manual maintenance

See the OpenAPI Handling Guide for framework-specific instructions:

Network Security

Ensure your backend only accepts traffic from the APIM gateway to prevent unauthorized direct access.

APIM Gateway IPs

  • Acceptance: 40.74.41.190
  • Production: 50.85.193.224

Example: IP Restriction in Terraform

hcl
ip_security_restriction {
  name             = "allow-apim-acceptance"
  ip_address_range = "40.74.41.190/32"
  action           = "Allow"
  description      = "Allow Azure APIM Acceptance traffic"
}

INFO

In the Azure Portal, the term Ingress under Networking is specific to services like Container Apps. For App Services or other resources, look for IP Restrictions directly under the Networking section. More details in the IP Whitelisting Guide.

Inventory Visibility

To make your API discoverable in the central API Inventory (and available in Excel), ensure you added the visible tag in your configuration:

yaml
tags = ["visible"]

See Inventory Access for more details.

Advanced: Manual Policy Management

By default, the platform handles all policies for you (authentication, CORS, rate limiting, etc.). If you need custom policy logic, you can optionally manage policies manually using Terraform.

WARNING

Manual policy management is not recommended unless you have specific requirements. The platform handles all standard use cases automatically.

If you need to manage policies manually, you can reference your API in Terraform:

hcl
data "azurerm_api_management_api" "api" {
  resource_group_name = var.api_management_instance.resource_group_name
  api_management_name = var.api_management_instance.name
  name                = var.api_name
  revision            = "1"
}

resource "azurerm_api_management_api_policy" "api_policy" {
  resource_group_name = var.api_management_instance.resource_group_name
  api_management_name = var.api_management_instance.name
  api_name            = data.azurerm_api_management_api.api.name
  xml_content         = file("${path.module}/policies/my-api-policy.xml")
}

Define your policy in XML format. Connect your API to your backend using <set-backend-service backend-id="[backend_name]" />, where [backend_name] matches the name you provided in your configuration.

For more information on policies, see:

Next Steps

Once deployed, your API will be:

  • ✅ Accessible via https://api.equation-acceptance.royalhaskoningdhv.com/{your-api-name}
  • ✅ Protected with EntraID authentication
  • ✅ Available in the Developer Portal if configured to the appropriate group
  • ✅ Discoverable in the Excel add-in (if tagged as visible)
  • ✅ Ready for collaboration with other teams