Yassir S
Yassir S

Reputation: 1042

How to deploy automatically an Azure API management?

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 :

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

Regards,

Upvotes: 6

Views: 5091

Answers (7)

user3622356
user3622356

Reputation: 105

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
}

Upvotes: 0

user3622356
user3622356

Reputation: 105

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.

Upvotes: -1

Mark W
Mark W

Reputation: 705

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.

Upvotes: 5

Ehsan Mirsaeedi
Ehsan Mirsaeedi

Reputation: 7592

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.

Upvotes: 0

Leon Africa
Leon Africa

Reputation: 599

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

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

Upvotes: 0

discy
discy

Reputation: 430

ARM is the way to go.

You can combine it with:

Upvotes: 1

4c74356b41
4c74356b41

Reputation: 72161

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.

Upvotes: 3

Related Questions