Reputation: 2108
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.
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
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