Automate your API catalog with Terraform

TL;DR

Create the following resources using Terraform:

  • konnect_api
  • konnect_api_document
  • konnect_api_version
  • konnect_api_implementation
  • konnect_api_publication

Prerequisites

This how-to requires you to install Terraform.

This is a Konnect tutorial and requires a Konnect personal access token.

  1. Create a new personal access token by opening the Konnect PAT page and selecting Generate Token.

  2. Export your token to an environment variable:

     export KONNECT_TOKEN='YOUR_KONNECT_PAT'
  3. Create an auth.tf file that configures the kong/konnect Terraform provider. Change server_url if you are using a region other than us:

    echo '
    terraform {
      required_providers {
        konnect = {
          source  = "kong/konnect"
        }
        konnect-beta = {
          source  = "kong/konnect-beta"
        }
      }
    }
       
    provider "konnect" {
      server_url = "https://us.api.konghq.com"
    }
       
    provider "konnect-beta" {
      server_url            = "https://us.api.konghq.com"
    }
    ' > auth.tf
  4. Next, initialize your project and download the provider:

    terraform init

The provider automatically uses the KONNECT_TOKEN environment variable if it is available. If you would like to use a custom authentication token, set the personal_access_token field alongside server_url in the provider block.

To use this tutorial, you need the following Kong Konnect roles:

  • Portal Creator
  • Content Editor
  • Gateway Service Admin
  • API Creator
  • API Publisher

For this tutorial, you’ll need Kong Gateway entities, like Gateway Services and Routes, pre-configured. These entities are essential for Kong Gateway to function but installing them isn’t the focus of this guide.

  1. Before configuring a Service and a Route, you need to create a Control Plane. If you have an existing Control Plane that you’d like to reuse, you can use the konnect_gateway_control_plane_list data source.
    echo '
    resource "konnect_gateway_control_plane" "my_cp" {
      name         = "Terraform Control Plane"
      description  = "Configured using the demo at developer.konghq.com"
      cluster_type = "CLUSTER_TYPE_CONTROL_PLANE"
    }
    ' > main.tf
  2. Our example Service uses httpbin.org as the upstream, and matches the /anything path which echos the response back to the client.
    echo '
    resource "konnect_gateway_service" "httpbin" {
      name             = "example-service"
      protocol         = "https"
      host             = "httpbin.org"
      port             = 443
      path             = "/"
      control_plane_id = konnect_gateway_control_plane.my_cp.id
    }
    
    resource "konnect_gateway_route" "hello" {
      methods = ["GET"]
      name    = "Anything"
      paths   = ["/anything"]
    
      strip_path = false
    
      control_plane_id = konnect_gateway_control_plane.my_cp.id
      service = {
        id = konnect_gateway_service.httpbin.id
    }
    }
    ' >> main.tf

For this tutorial, you’ll need a Dev Portal pre-configured. These settings are essential for Dev Portal to function, but configuring them isn’t the focus of this guide. If you don’t have these settings already configured, follow these steps to pre-configure them:

  1. Create a Dev Portal and add a page to display your published APIs:

    echo '
    resource "konnect_portal" "my_portal" {
      authentication_enabled               = false
      auto_approve_applications            = false
      auto_approve_developers              = true
      default_api_visibility               = "public"
      default_page_visibility              = "public"
      description                          = "...my_description..."
      display_name                         = "...my_display_name..."
      force_destroy                        = "false"
      name         = "My Portal"
      rbac_enabled = true
    }
    resource "konnect_portal_page" "my_portalpage" {
      portal_id   = konnect_portal.my_portal.id
      title       = "My Page"
      slug        = "/apis"
      description = "A custom page about developer portals"
      visibility  = "public"
      status      = "published"
    
      content = <<-MD
      # Welcome to My Dev Portal
    
      Explore the available APIs below:
    
      ::apis-list
      ---
      persist-page-number: true
      cta-text: "View APIs"
      ---
      MD
    }
    ' >> main.tf
  2. Create all of the defined resources using Terraform:

    terraform apply -auto-approve

Create an API

In this tutorial, you’ll automate your API catalog by creating an API in Catalog along with a document and spec, associating it with a control plane, and finally publishing it to a Dev Portal.

First, create an API:

echo '
resource "konnect_api" "my_api" {
  description = "...my_description..."
  labels = {
    key = "value"
  }
  name         = "MyAPI"
}
' >> main.tf

Create and associate an API spec and version

Create and associate a spec and version with your API:

echo '
resource "konnect_api_version" "my_api_spec" {
  api_id = konnect_api.my_api.id
  spec = {
    content = <<JSON
      {
        "openapi": "3.0.3",
        "info": {
          "title": "Example API",
          "version": "1.0.0"
        },
        "paths": {
          "/example": {
            "get": {
              "summary": "Example endpoint",
              "responses": {
                "200": {
                  "description": "Successful response"
                }
              }
            }
          }
        }
      }
      JSON
  }
  version = "1.0.0"
}
' >> main.tf

We recommend that APIs have API documents or specs, and APIs can have both. If neither are specified, Konnect can’t render documentation.

Create and associate an API document

An API document is Markdown documentation for your API that displays in the Dev Portal. You can link multiple API Documents to each other with a parent document and child documents.

Create and associate an API document:

echo '
resource "konnect_api_document" "my_apidocument" {
  api_id  = konnect_api.my_api.id
  content = "# API Document Header"
  slug               = "api-document"
  status             = "published"
  title              = "API Document"
}
' >> main.tf

Associate the API with a control plane

By associating an API with a control plane, this allows developers to generate credentials or API keys for your API.

Associate the API with a control plane:

echo '
resource "konnect_api_implementation" "my_api_implementation" {
  api_id = konnect_api.my_api.id
  control_plane_reference = {
    control_plane = {
      id = konnect_gateway_control_plane.my_cp.id
    }
  }
  depends_on = [
    konnect_api.my_api,
    konnect_api_version.my_api_spec,
    konnect_gateway_control_plane.my_cp,
    konnect_gateway_plugin_ace.my_ace
  ]
}
' >> main.tf

Apply the ACE plugin

The Access Control Enforcement plugin manages developer access control for APIs published in Dev Portal. ACE applies at the control plane level rather than to a single Gateway Service, so it covers all traffic on the control plane. The ACE plugin is recommended for declarative configuration.

The match_policy setting controls how ACE handles requests that don’t match a defined API operation. This example uses required, which rejects any request that doesn’t match a published operation with a 404. If you have existing traffic on the control plane that isn’t published through Dev Portal, use if_present instead. See the ACE plugin examples for all available configurations.

echo '
resource "konnect_gateway_plugin_ace" "my_ace" {
  enabled = true
  config = {
    match_policy = "required"
  }
  tags = []
  control_plane_id = konnect_gateway_control_plane.my_cp.id
}
' >> main.tf

Publish the API to Dev Portal

Now you can publish the API to a Dev Portal:

echo '
resource "konnect_api_publication" "my_apipublication" {
  api_id = konnect_api.my_api.id
  portal_id                  = konnect_portal.my_portal.id
  visibility                 = "public"

  depends_on = [
    konnect_api_implementation.my_api_implementation,
    konnect_api_document.my_apidocument
  ]
}
' >> main.tf

Create the resources

Create all of the defined resources using Terraform:

terraform apply -auto-approve

You will see five resources created:

Apply complete! Resources: 5 added, 0 changed, 0 destroyed.

Validate

To validate that your API was successfully published, you must navigate to your Dev Portal URL and verify that you can see the API.

First, fetch the Dev Portal URL from the Terraform state:

PORTAL_URL=$(terraform show -json | jq -r '
  .values.root_module.resources[]
  | select(.address == "konnect_portal.my_portal")
  | .values.default_domain')

This exports your Dev Portal URL as an environment variable.

To validate that the API was created and published in your Dev Portal, navigate to your Dev Portal:

open https://$PORTAL_URL/apis

You should see MyAPI in the list of APIs. If an API is published as private, you must enable Dev Portal RBAC and developers must sign in to see APIs.

FAQs

If you recently viewed the related content, your browser might be serving a cached version of the page. To fix this, you can clear your browser cache and refresh the page.

Use the /apis/{apiId}/versions endpoint to publish multiple versions of an API. Developers can then select which API version to view in the Dev Portal spec renderer. Each version reflects how the endpoints were documented at a specific time. It doesn’t reflect the actual implementation, which will usually align with the latest version. Changing the version in the dropdown only changes the specs you see. It does not change the requests made with application credentials or app registration.

There are two exceptions when the underlying implementation should match the selected version:

  • With Dev Portal app registration: If non-current versions have Route configurations that allow requests to specify the version in some way, each version must document how to modify the request to access the given version (for example, using a header).
  • Without Dev Portal app registration: If the version can be accessed separately from other versions of the same API, each version must document how to modify the request to access the given version.

When you link an API to a Gateway, you have two options:

These plugins are responsible for applying authentication and authorization on the Gateway Service or control plane. The authentication strategy that you select for the API defines how clients authenticate.

The following table can help you decide which option to pick:

Option

KAA plugin

ACE plugin

Scope Linked to a single Gateway Service Linked to an entire control plane
Plugin applied… Automatically on the Gateway Service linked to the API Manually
Managed by… Konnect. You can only modify it by configuring JSON in the advanced configuration for your application auth strategy. You, by manually configuring the plugin.
Kong Gateway version 3.6 or later 3.13 or later
Can be used with declarative configuration No, because the plugin is applied automatically Yes, because you must configure the plugin
Can be used with API packages No Yes

Do not configure the KAA and ACE plugins on the same control plane because their overlapping interactions can be unpredictable.

Help us make these docs great!

Kong Developer docs are open source. If you find these useful and want to make them better, contribute today!