Ben
Ben

Reputation: 2108

Import function definition into API Management as part of CI process

We're looking to automate the process of importing a function definition into our CD process with every deployment of our azure functions. Within the azure portal, there is a very straightforward way to import a function definition through the UI, but their doesn't appear to be any api/cli/powershell library to automate this process.

Azure Portal Function app import

We have managed to create a workaround which involves keeping our function app definitions up to date using the C# OpenApi library and then using the az apim import cli command as part of our deployment pipeline but it feels like extra work keeping the OpenApi definition up to date and accurate on every endpoint of our function and it would be preferable to automate what the portal is doing under the hood when you import a function app (this does not require an openapi definition being kept up to date in source code). Any help would be greatly appreciated.

We are using Azure Devops for our CI/CD pipelines and releases.

Upvotes: 6

Views: 861

Answers (1)

Chase
Chase

Reputation: 2304

You've got a few options for this. You didn't specify if you already have some existing infrastructure CI tools, but I'm most familiar with doing this in terraform.

Tutorial on how to setup terraform into your pipeline.

Once you have terraform integrated you can easily add API definitions into your APIM instance. And link that up to your function backend.

Article and some code samples from it:

resource "azurerm_api_management_backend" "example" {
  name                = "example-backend"
  resource_group_name = data.azurerm_resource_group.example.name
  api_management_name = data.azurerm_api_management.example.name
  protocol            = "http"
  url                 = "https://${azurerm_function_app.example.name}.azurewebsites.net/api/"

  credentials {
    header = {
      "x-functions-key" = "${data.azurerm_function_app_host_keys.example.default_function_key}"
    }
  }
}

resource "azurerm_api_management_api" "example" {
  name                = "example-api"
  resource_group_name = data.azurerm_resource_group.example.name
  api_management_name = data.azurerm_api_management.example.name
  revision            = "1"
  display_name        = "Example API"
  path                = "example"
  protocols           = ["https"]

  import {
    content_format = "openapi"
    content_value  = file("${path.module}/FuncOpenAPI3.yml")
  }
}

resource "azurerm_api_management_api_policy" "example" {
  api_name            = azurerm_api_management_api.example.name
  api_management_name = azurerm_api_management_api.example.api_management_name
  resource_group_name = azurerm_api_management_api.example.resource_group_name

  xml_content = <<XML
<policies>
  <inbound>
    <base/>
    <set-backend-service backend-id="example-backend" />
  </inbound>
</policies>
XML
}

Now as you can see in this article it talks about importing an OpenApi file to define the actual api. There isn't a great way to do this automatically, but there is a way using swagger's built in tofile tool:

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="dotnet tool restore" />
    <Exec Command="dotnet swagger tofile --output swagger.json $(OutputPath)\$(AssemblyName).dll v1 " />
</Target>

When you run your build in your pipeline this file will be generated and then you can reference it in your infrastructure stage to use that OpenAPI file to automatically generate that API in APIM.

Upvotes: 1

Related Questions