API Management CI/CD using ARM Templates – Unversioned API

This is the thirth post in my series around setting up CI/CD for Azure API Management using Azure Resource Manager templates. In the first post we created our API Management instance, and have set up our build and release pipelines, while in the second post we added the products, users and groups for Contoso. In this post we will create an unversioned API , and expose it through the product from the previous post.

image

The posts in this series are the following, this list will be updated as the posts are being published.

Scenario

Although API Management has support for versioning on APIs, currently many APIs we expose don’t support versioning themselves, so it might not really make sense to version them in API Management. This blog post will show how we can create a simple API without versioning, and for this we will use the API from APIs.guru, which can be used without authentication and is therefor perfect for a quick PoC.

GIT Repository

We will set up another GIT repository for the ARM template of this post, which will be called Unversioned API.

Create GIT repository

ARM Template

Once the repository has been created, we check it out to our local machine and create a file in it called unversioned-api.json. Add the following ARM template to the file.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "APIManagementInstanceName": {
          "type": "string",
          "defaultValue": "MyAPIManagementInstance"
        }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.ApiManagement/service/apis",
            "name": "[concat(parameters('APIManagementInstanceName'), '/unversioned-api')]",
            "apiVersion": "2017-03-01",
            "scale": null,
            "properties": {
                "displayName": "Unversioned API",
                "apiRevision": "1",
                "description": "Wikipedia for Web APIs.  Repository of API specs in OpenAPI(fka Swagger) 2.0 format.\n\n**Warning**: If you want to be notified about changes in advance please subscribe to our [Gitter channel](https://gitter.im/APIs-guru/api-models).\n\nClient sample: [[Demo]](https://apis.guru/simple-ui) [[Repo]](https://github.com/APIs-guru/simple-ui)\n",
                "serviceUrl": "https://api.apis.guru/v2/",
                "path": "unversioned-api",
                "protocols": [
                    "https"
                ]
            },
            "dependsOn": []
        },
        {
            "type": "Microsoft.ApiManagement/service/apis/operations",
            "name": "[concat(parameters('APIManagementInstanceName'), '/unversioned-api/getMetrics')]",
            "apiVersion": "2017-03-01",
            "scale": null,
            "properties": {
                "displayName": "Get basic metrics",
                "method": "GET",
                "urlTemplate": "/metrics",
                "templateParameters": [],
                "description": "Some basic metrics for the entire directory.\nJust stunning numbers to put on a front page and are intended purely for WoW effect :)\n",
                "responses": [
                    {
                        "statusCode": 200,
                        "description": "OK",
                        "representations": [
                            {
                                "contentType": "application/json; charset=utf-8",
                                "sample": null,
                                "typeName": "Metrics"
                            },
                            {
                                "contentType": "application/json",
                                "sample": null,
                                "typeName": "Metrics"
                            }
                        ],
                        "headers": []
                    }
                ],
                "policies": null
            },
            "dependsOn": [
                "[resourceId('Microsoft.ApiManagement/service/apis', parameters('APIManagementInstanceName'), 'unversioned-api')]"
            ]
        },
        {
            "type": "Microsoft.ApiManagement/service/apis/operations",
            "name": "[concat(parameters('APIManagementInstanceName'), '/unversioned-api/listAPIs')]",
            "apiVersion": "2017-03-01",
            "scale": null,
            "properties": {
                "displayName": "List all APIs",
                "method": "GET",
                "urlTemplate": "/list",
                "templateParameters": [],
                "description": "List all APIs in the directory.\nReturns links to OpenAPI specification for each API in the directory.\nIf API exist in multiple versions `preferred` one is explicitly marked.\n\nSome basic info from OpenAPI spec is cached inside each object.\nThis allows to generate some simple views without need to fetch OpenAPI spec for each API.\n",
                "responses": [
                    {
                        "statusCode": 200,
                        "description": "OK",
                        "representations": [
                            {
                                "contentType": "application/json; charset=utf-8",
                                "sample": null,
                                "typeName": "APIs"
                            },
                            {
                                "contentType": "application/json",
                                "sample": null,
                                "typeName": "APIs"
                            }
                        ],
                        "headers": []
                    }
                ],
                "policies": null
            },
            "dependsOn": [
                "[resourceId('Microsoft.ApiManagement/service/apis', parameters('APIManagementInstanceName'), 'unversioned-api')]"
            ]
        },
        {
            "type": "Microsoft.ApiManagement/service/apis/operations/policies",
            "name": "[concat(parameters('APIManagementInstanceName'), '/unversioned-api/getMetrics/policy')]",
            "apiVersion": "2017-03-01",
            "scale": null,
            "properties": {
                "policyContent": "[concat('<!--\r\n    IMPORTANT:\r\n    - Policy elements can appear only within the <inbound>, <outbound>, <backend> section elements.\r\n    - Only the <forward-request> policy element can appear within the <backend> section element.\r\n    - To apply a policy to the incoming request (before it is forwarded to the backend service), place a corresponding policy element within the <inbound> section element.\r\n    - To apply a policy to the outgoing response (before it is sent back to the caller), place a corresponding policy element within the <outbound> section element.\r\n    - To add a policy position the cursor at the desired insertion point and click on the round button associated with the policy.\r\n    - To remove a policy, delete the corresponding policy statement from the policy document.\r\n    - Position the <base> element within a section element to inherit all policies from the corresponding section element in the enclosing scope.\r\n    - Remove the <base> element to prevent inheriting policies from the corresponding section element in the enclosing scope.\r\n    - Policies are applied in the order of their appearance, from the top down.\r\n-->\r\n<policies>\r\n  <inbound>\r\n    <base />\r\n    <rewrite-uri template=\"/metrics.json\" />\r\n  </inbound>\r\n  <backend>\r\n    <base />\r\n  </backend>\r\n  <outbound>\r\n    <base />\r\n  </outbound>\r\n  <on-error>\r\n    <base />\r\n  </on-error>\r\n</policies>')]"
            },
            "dependsOn": [
                "[resourceId('Microsoft.ApiManagement/service/apis', parameters('APIManagementInstanceName'), 'unversioned-api')]",
                "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('APIManagementInstanceName'), 'unversioned-api', 'getMetrics')]"
            ]
        },
        {
            "type": "Microsoft.ApiManagement/service/apis/operations/policies",
            "name": "[concat(parameters('APIManagementInstanceName'), '/unversioned-api/listAPIs/policy')]",
            "apiVersion": "2017-03-01",
            "scale": null,
            "properties": {
                "policyContent": "[concat('<!--\r\n    IMPORTANT:\r\n    - Policy elements can appear only within the <inbound>, <outbound>, <backend> section elements.\r\n    - Only the <forward-request> policy element can appear within the <backend> section element.\r\n    - To apply a policy to the incoming request (before it is forwarded to the backend service), place a corresponding policy element within the <inbound> section element.\r\n    - To apply a policy to the outgoing response (before it is sent back to the caller), place a corresponding policy element within the <outbound> section element.\r\n    - To add a policy position the cursor at the desired insertion point and click on the round button associated with the policy.\r\n    - To remove a policy, delete the corresponding policy statement from the policy document.\r\n    - Position the <base> element within a section element to inherit all policies from the corresponding section element in the enclosing scope.\r\n    - Remove the <base> element to prevent inheriting policies from the corresponding section element in the enclosing scope.\r\n    - Policies are applied in the order of their appearance, from the top down.\r\n-->\r\n<policies>\r\n  <inbound>\r\n    <base />\r\n    <rewrite-uri template=\"/list.json\" />\r\n  </inbound>\r\n  <backend>\r\n    <base />\r\n  </backend>\r\n  <outbound>\r\n    <base />\r\n  </outbound>\r\n  <on-error>\r\n    <base />\r\n  </on-error>\r\n</policies>')]"
            },
            "dependsOn": [
                "[resourceId('Microsoft.ApiManagement/service/apis', parameters('APIManagementInstanceName'), 'unversioned-api')]",
                "[resourceId('Microsoft.ApiManagement/service/apis/operations', parameters('APIManagementInstanceName'), 'unversioned-api', 'listAPIs')]"
            ]
        },
        {
            "type": "Microsoft.ApiManagement/service/products/apis",
            "name": "[concat(parameters('APIManagementInstanceName'), '/contosoproduct/unversioned-api')]",
            "apiVersion": "2017-03-01",
            "scale": null,
            "properties": {},
            "dependsOn": [
                "[resourceId('Microsoft.ApiManagement/service/apis', parameters('APIManagementInstanceName'), 'unversioned-api')]"
            ]
        }
    ]
}

In this template we create the API in API Management, including the operations and their policies, and link it to the product for Contoso. That’s it for our ARM template, so commit and push it to our VSTS repository.

Build pipeline

Now that our ARM template has been created, lets go and set up the build pipeline which does the validation of the template. For details on how to set up the pipeline you can have a look at the first post in this series. The build template should be called API Management CI-CD ARM-CI – Unversioned API and use the repository we just created.

Use Unversioned API repository

Do make sure to enable the continous deployment trigger so the build is triggered every time we push changes to our repository.

Create validation built pipeline

When done save and queue the build template.

Deployment pipeline

Next create the deployment pipeline called , if you need details on how to do this you can again reference the first post in this series. This pipeline should be triggered whenever an artifact is published from the build pipeline, and deployment to production should only be done after approval.

 Create deployment pipeline

Testing

To test our process we can now simply make a change to our local ARM template and check it in to the repository. This will trigger our build and release pipeline, and finally deploy the API into our API Management instance.

Unversioned API has been deployed

 

 

3 thoughts on “API Management CI/CD using ARM Templates – Unversioned API

  1. Pingback: API Management CI/CD using ARM Templates – Products, users and groups | Wonderful world of Microsoft integration

  2. Pingback: API Management CI/CD using ARM Templates – Unversioned API - BizTalkGurus

  3. Pingback: API Management CI/CD using ARM Templates – Linked template | Wonderful world of Microsoft integration

Leave a Reply

Your email address will not be published. Required fields are marked *