How to deploy automatically an Azure API management?
Asked Answered
T

7

6

Within API management, I created an API that enables to call a serverless function app. Now I would like to deploy automatically this functionnality. Here are the possibilities I saw on internet :

  • Create and configure the api management through the portal (this is not what I call an automatic deployment)
  • Use Powershell command (unfortunally I am working with linux)
  • ARM (Azure Resource Manager): this is not easy and I did find how to create an API with Azure function app
  • Terraform: same as ARM, it is not clear for me how to create an API with Azure function app

If someone has an experience, links or ideas I would be very thankful.

Regards,

Teagan answered 1/12, 2018 at 10:51 Comment(3)
You can visit aka.ms/apimdevops for guidance on automating your deployments. At this moment, import of a Function App is not available through API. You can open the developer tools in your browsers and trace the calls that API Management makes in Azure portal to create an API from Function App, and then redo these calls from your own script.Eudoxia
Thanks, it is now clear for me.Teagan
Deployment of Azure API management remains a complete travesty. Honestly it's the worst part about it. CI/CD is really an afterthought and the ARM template story is hugely complicated, and there's a lot to think about it doesn't address. All that said, once you've done the work to automate, it pays off. Completely agree with the recommendation to use terraform out of the options presented above. I did try the dotnet-apim tool, looks interesting and has progressed since I last looked.Marella
T
5

We are currently using Terraform for all our Azure infrastructure including API Management and I would strongly recommend it.

It is creating and updating everything we want, including api policies and has a relativity small learning curve.

You can start learning here:

https://learn.hashicorp.com/terraform?track=azure#azure

The docs for APIM are here:

https://www.terraform.io/docs/providers/azurerm/r/api_management.html

Once the initial learning curve is done the rest is easy and the benefits are many.

Tapetum answered 12/11, 2019 at 8:16 Comment(1)
Do you have real examples of using Terraform with APIM? The documentation looks like it would make a great reference for somebody who already knows what they're doing. I find myself copying/pasting from the documentation, editing to match the resources I'm trying to create, then debugging error after error after error when I do terraform apply.Receivable
C
3

Azure Powershell is 100% cross platform now, so that's an option. Here are some samples: https://learn.microsoft.com/en-us/azure/api-management/powershell-samples

You can also use ARM Templates to spin it up. Configuring it is a lot harder. You can map any of these calls to the ARM Template.

Terraform - i think its still in the works. https://github.com/terraform-providers/terraform-provider-azurerm/issues/1177. But I wouldnt go that way.

Calyces answered 1/12, 2018 at 12:15 Comment(0)
H
1

ARM is the way to go.

You can combine it with:

Hyman answered 1/12, 2018 at 17:52 Comment(0)
S
0

Have a look at the Azure API Management DevOps Resource Kit:

https://github.com/Azure/azure-api-management-devops-resource-kit

Surreptitious answered 19/6, 2019 at 11:30 Comment(0)
A
0

I believe the most convenient way for automating the deployment of Azure APIM is dotnet-apim. It's a cross-platform solution that you can easily use on your dev machine or ci/cd pipeline.

  1. Make sure you have .NET Core installed.
  2. Install dotnet-apim tool.
  3. In a yaml file, you define the list of APIVersionSets, APIs, Products, Backends, Tags, etc. This YAML file defines what you want to deploy to APIM. You can have it on your source control to take the history of changes. The following YAML file defines 2 Sets, APIs, and Products along with their policies.
version: 0.0.1   # Required
apimServiceName: $(apimServiceName)   # Required, must match name of an apim service deployed in the specified resource group

apiVersionSets:

    - name: Set1
      displayName: API Set 1 
      description: Contains Set 1 APIs.
      versioningScheme: Segment 

    - name: Set2
      displayName: API Set 2
      description: Contains Set 2 APIs.
      versioningScheme: Segment 

apis:

    - name: API1
      displayName: API v1
      openApiSpec: $(apimBasePath)\Apis\OpenApi.json    # Required, can be url or local file
      policy: $(apimBasePath)\Apis\ApiPolicy.xml
      path: api/sample1
      apiVersion: v1
      apiVersionSetId: Set1
      apiRevision: 1
      products: AutomationTests, SystemMonitoring
      protocols: https
      subscriptionRequired: true
      isCurrent: true
      operations:
          customer_get: # it's operation id
              policy: $(apimBasePath)\Apis\HealthCheck\HealthCheckPolicy.xml:::BackendUrl=$(attachmentServiceUrl)
      subscriptionKeyParameterNames: 
         header: ProviderKey
         query: ProviderKey 


    - name: API2
      displayName: API2 v1 [Staging]
      openApiSpec: $(apimBasePath)\Apis\OpenApi.json    # Required, can be url or local file
      policy: $(apimBasePath)\Apis\ApiPolicy.xml
      path: api/sample2
      apiVersion: v1
      apiVersionSetId: Set2
      apiRevision: 1
      products: AutomationTests, SystemMonitoring
      protocols: https
      subscriptionRequired: true
      isCurrent: true  
      subscriptionKeyParameterNames: 
         header: ProviderKey
         query: ProviderKey   

products:

    - name: AutomationTests
      displayName: AutomationTests
      description: Product for automation tests
      subscriptionRequired: true
      approvalRequired: true
      subscriptionsLimit: 1
      state: published
      policy: $(apimBasePath)\Products\AutomationTests\policy.xml

    - name: SystemMonitoring
      displayName: SystemMonitoring
      description: Product for system monitoring
      subscriptionRequired: true
      approvalRequired: true
      subscriptionsLimit: 1
      state: published
      policy: $(apimBasePath)\Products\SystemMonitoring\policy.xml


outputLocation: $(apimBasePath)\output
linkedTemplatesBaseUrl : $(linkedTemplatesBaseUrl)  # Required if 'linked' property is set to true
  1. the $(variableName) is a syntax for defining variables inside the YAML file which makes customization easier in ci/cd scenarios.

  2. The next step is to transform the YAML file to ARM which Azure can understand.

dotnet-apim --yamlConfig "c:/apim/definition.yml" 
  1. Then you have to deploy the generated ARM templates to Azure which is explained here.
Arsonist answered 7/11, 2019 at 23:28 Comment(0)
R
0

Using the test-api (if you do the microsoft demo for API Mgmt, you should recognize it), here's a snippet of terraform that does work. does not include the resource group (thisrg)

resource "azurerm_api_management" "apimgmtinstance" {
  name                = "${var.base_apimgmt_name}-${var.env_name}-apim"
  location            = azurerm_resource_group.thisrg.location
  resource_group_name = azurerm_resource_group.thisrg.name
  publisher_name      = "Marc Pub"
  publisher_email     = "[email protected]"

  sku_name = var.apimgmt_size

 /* policy {
    xml_content = <<XML
    <policies>
      <inbound />
      <backend />
      <outbound />
      <on-error />
    </policies>
XML

  } */
}

resource "azurerm_api_management_product" "apiMgmtProductContoso" {
  product_id    = "contoso-marc"
  display_name  = "Contoso Marc"
  description   = "this is a test"
  subscription_required = true
  approval_required = true
  api_management_name = azurerm_api_management.apimgmtinstance.name
  resource_group_name = azurerm_resource_group.thisrg.name
  published = true
  subscriptions_limit = 2
  terms = "you better accept this or else... ;-)"
}


resource "azurerm_api_management_api" "testapi" {
  description = "this is a mock test"
  display_name = "Test API"
  name = "test-api"
  protocols =  ["https"]
  api_management_name = azurerm_api_management.apimgmtinstance.name
  resource_group_name = azurerm_resource_group.thisrg.name
  // version = "0.0.1"
  revision = "1"
  path = ""
  subscription_required = true

} 

data "azurerm_api_management_api" "testapi_data" {
  name = azurerm_api_management_api.testapi.name
  api_management_name = azurerm_api_management.apimgmtinstance.name
  resource_group_name = azurerm_resource_group.thisrg.name
  revision  = "1"
}

resource "azurerm_api_management_api_operation" "testapi_getop" {
  operation_id = "test-call"
  api_name = data.azurerm_api_management_api.testapi_data.name
  api_management_name = data.azurerm_api_management_api.testapi_data.api_management_name
  resource_group_name = data.azurerm_api_management_api.testapi_data.resource_group_name
  display_name = "Test call"
  method = "GET"
  url_template = "/test"
  description = "test of call"
  response {
    status_code = 200
    description = ""
    representation {
      content_type = "application/json"
      sample = "{\"sampleField\": \"test\"}"
    }
  }
}

resource "azurerm_api_management_api_operation_policy" "testapi_getop_policy" {
  api_name            = azurerm_api_management_api_operation.testapi_getop.api_name
  api_management_name = azurerm_api_management_api_operation.testapi_getop.api_management_name
  resource_group_name = azurerm_api_management_api_operation.testapi_getop.resource_group_name
  operation_id        = azurerm_api_management_api_operation.testapi_getop.operation_id
  xml_content = <<XML
                <policies>
                  <inbound>
                    <mock-response status-code="200" content-type="application/json"/>
                  </inbound>
                </policies>
                XML
}
Roper answered 12/2, 2021 at 15:58 Comment(2)
this is wrong, doesn't answer the original question (azure function import). I think this is me!Roper
I might have an answer though, depending on if your azure function has swagger or openapi. If so, and you can invoke your azure function via (assuming powershell) curl.exe -H "Content-type: application/json" -H "x-functions-key: <your app key value>" <url>, then you could then try the appropriate url when doing your terraform api import using something like 'https://yourfunction.azurewebsites.net/api/OpenAPI?format=json&code=<your app key value>Roper
R
-1

terraform now mostly supports azure api management. I've been implementing most of an existing azure api management into terraform using a combination of the https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management along with terraform import (just do it in a separate folder, terraform import imports into a terraform.tfstate file, and if you mix up the resource you are importing along with the tf file(s) you are creating as a result's terraform.tfstate file (generated via terraform plan/apply), you could accidently delete the resource you are importing from. yay...

It mostly does it, except for an API where you modified for 'All operations". I can do it for specific operations (get blah, or post blahblah), but for all operations... I don't yet know.

Roper answered 12/2, 2021 at 14:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.