Skip to content

Latest commit

 

History

History
971 lines (720 loc) · 28.1 KB

File metadata and controls

971 lines (720 loc) · 28.1 KB

Declarative Configuration

This page covers what you need to know for managing Kong Konnect resources using the kongctl declarative configuration approach. For supported resource types and field-level resource definitions see the Declarative Resource Reference.

Table of Contents

Overview

kongctl's declarative management feature enables you to manage your Kong Konnect resources with simple YAML declaration files and a simple state free CLI tool.

Key Principles

  1. Configuration manifests: Configuration is expressed as simple YAML files that describe the desired state of your Konnect resources. Configuration files can be split into multiple files and directories for modularity and reuse.
  2. Plan-Based: Plans are objects that represent required changes to move a set of resources from one state to another, desired, state. In kongctl, plan artifacts are first class concepts that can be created, stored, reviewed, and applied. Plans are represented as JSON objects and can be generated and stored as files for later application. When running declarative commands, if plans are not provided they are generated implicitly and executed immediately.
  3. State-Free: kongctl does not use a state file or database to store the current state. The system relies on querying of the online Konnect state in order to calculate plans and apply changes.
  4. Namespace Support: Namespaces provide a way to isolate resources between teams and environments. Each resource can be assigned to a specific namespace, and resources in different namespaces are not considered when calculating plans or applying changes. Namespaces can be set at the resource level or inherited from file-level defaults.

Quick Start

Prerequisites

  1. Kong Konnect Account: Sign up for free
  2. kongctl installed: See installation instructions
  3. Authenticated with Konnect: Run kongctl login

Create Your First Configuration

Create a working directory:

mkdir kong-portal && cd kong-portal

Create a file named portal.yaml:

portals:
  - ref: my-portal
    name: "my-developer-portal"
    display_name: "My Developer Portal"
    description: "API documentation for developers"
    authentication_enabled: false
    default_api_visibility: "public"
    default_page_visibility: "public"

apis:
  - ref: users-api
    name: "Users API"
    description: "API for user management"

    publications:
      - ref: users-api-publication
        portal_id: my-portal

Preview changes:

kongctl diff -f portal.yaml

Apply configuration:

kongctl apply -f portal.yaml

Verify resources with kongctl get commands:

kongctl get portals
kongctl get apis

Your developer portal and API are now live! Visit the Konnect Console to see your developer portal with the published API.

Core Concepts

Resource Identity

Resources have multiple identifiers:

  • ref: Required field for each reference in declarative configuration. ref must be unique across any loaded set of configuration files.
  • id: Most Konnect resources have an id field which is a Konnect assigned UUID. This field is not represented in declarative configuration files.
  • name: Many Konnect resources have a name field which may or may not be unique within an organization for that resource type.
application_auth_strategies:
  - ref: oauth-strategy              # ref identifies a resource within a configuration
    name: "OAuth 2.0 Strategy"       # Identifies an auth strategy within Konnect

portals:
  - ref: developer-portal
    name: "Developer Portal"
    default_application_auth_strategy: oauth-strategy  # References the auth strategy by it's ref value

Plan Artifacts

Plans are central to how kongctl manages resources. Plans are objects which define the required steps to move a set of resources from their current state to a desired state. Plans can be created, stored, reviewed, and applied at a later time and are stored as JSON files. Plans are not required to be used, but can enable advanced workflows.

How Planning Works

Both apply and sync commands use the planning engine internally:

Implicit Planning (direct execution):

# Internally generates plan and executes it
kongctl apply -f config.yaml

Explicit Planning (two-phase execution):

# Phase 1: Generate plan artifact
kongctl plan -f config.yaml --output-file plan.json

# Phase 2: Execute plan artifact (can be done later)
kongctl apply --plan plan.json

Why Use Plan Artifacts?

Plan artifacts enable more advanced workflows:

  • Audit Trail: Store plans in version control alongside configurations
  • Review Process: Share plans with team members before execution
  • Deferred Execution: Generate plans in CI, apply them after approval
  • Rollback Safety: Keep previously applied plans for rollback
  • Compliance: Document exactly what changes were planned

Supported Resource Types

kongctl aims to support all of the Kong Konnect resource types but each resource requires specific handling and coding changes. The following lists the currently supported resources and their relationships.

Parent vs Child Resources

Parent Resources (support kongctl metadata):

  • APIs
  • Catalog Services
  • Portals
  • Application Auth Strategies
  • Control Planes (including Control Plane Groups)
  • Event Gateways

Child Resources (do NOT support kongctl metadata):

  • API Versions
  • API Publications
  • API Implementations
  • API Documents
  • Portal Pages
  • Portal Snippets
  • Portal Customizations
  • Portal Custom Domains
  • Portal Email Configs
  • Portal Email Templates
  • Gateway Services

Note: Portal email domains are currently imperative-only because the Konnect API exposes them at the organization level without labels or namespace scoping. Use kongctl get portal email-domains to inspect them; declarative management will be added when Konnect supports namespacing or labels for these resources.

Portal email templates are customizable per portal. Apply mode creates/updates templates but will not delete any that already exist in Konnect; sync mode plans deletions for customized templates that are absent from the declarative configuration.

Configuration Structure

Basic Structure

# Optional defaults section
_defaults:
  kongctl: # kongctl metadata defaults
    namespace: production
    protected: false

portals: # List of portal resources
  - ref: developer-portal # ref is required on all resources
    name: "developer-portal"
    display_name: "Developer Portal"
    description: "API documentation hub"
    kongctl: # kongctl metadata defined explicitly on resource
      namespace: platform-prod
      protected: true

Root vs hierarchical configuration

Parents are defined at the root of a configuration while children can be expressed both nested under their parent and at the root with a parent reference field.

Hierarchical Configuration:

apis:
  - ref: users-api
    name: "Users API"
    versions:
      - ref: v1
        name: "v1.0.0"
        spec: !file ./specs/users-v1.yaml
    publications:
      - ref: public
        portal: main-portal
        visibility: public

Separate Configuration:

apis:
  - ref: users-api
    name: "Users API"

api_versions:
  - ref: v1
    api: users-api
    name: "v1.0.0"
    spec: !file ./specs/users-v1.yaml

api_publications:
  - ref: public
    api: users-api
    portal: main-portal

Control Plane Groups

Control planes can represent Konnect control plane groups by setting their cluster type to "CLUSTER_TYPE_CONTROL_PLANE_GROUP". Group entries manage membership through the members array. Each member must resolve to the Konnect ID of a non-group control plane, so you can provide literal UUIDs or reference other declarative control planes with !ref.

control_planes:
  - ref: shared-group
    name: "shared-group"
    cluster_type: "CLUSTER_TYPE_CONTROL_PLANE_GROUP"
    members:
      - id: !ref prod-us-runtime#id
      - id: !ref prod-eu-runtime#id

When you apply or sync this configuration, kongctl replaces the entire membership list in Konnect to match the declarative members block.

Kongctl Metadata

The kongctl section provides metadata for resource management. This metadata is stored in Kong Konnect labels and labels are only provided on parent resources. Thus, kongctl metadata is only supported on parent resources.

Protected Resources

The protected field prevents accidental deletion of critical resources:

portals:
  - ref: production-portal
    name: "Production Portal"
    kongctl:
      protected: true  # Cannot be deleted until protection is removed

Namespace Management

The namespace field enables multi-team resource isolation:

apis:
  - ref: billing-api
    name: "Billing API"
    kongctl:
      namespace: finance-team  # Owned by finance team
      protected: false

File-Level Defaults

Use _defaults to set default values for all resources in a file:

_defaults:
  kongctl:
    namespace: platform-team
    protected: true

portals:
  - ref: api-portal
    name: "API Portal"
    # Inherits namespace: platform-team and protected: true

  - ref: test-portal
    name: "Test Portal"
    kongctl:
      namespace: qa-team
      protected: false
    # Overrides both defaults

Namespace and Protected Field Behavior

kongctl provides some default behavior depending on how metadata fields are specified or omitted. The following tables summarize the behavior.

namespace Field Behavior

File Default Resource Value Final Result Notes
Not set Not set "default" System default
Not set "team-a" "team-a" Resource explicit
Not set "" (empty) ERROR Empty namespace not allowed
"team-b" Not set "team-b" Inherits default
"team-b" "team-a" "team-a" Resource overrides
"team-b" "" (empty) ERROR Empty namespace not allowed
"" (empty) Any value ERROR Empty default not allowed

protected Field Behavior

File Default Resource Value Final Result Notes
Not set Not set false System default
Not set true true Resource explicit
Not set false false Explicit false
true Not set true Inherits default
true false false Resource overrides
false true true Resource overrides

Child resources automatically inherit the namespace of their parent resource:

External Resources and Namespaces

External resources (_external blocks) are references to Konnect objects that are managed elsewhere. Because kongctl does not own those objects:

  • External resources cannot declare kongctl metadata. Supplying kongctl.namespace or kongctl.protected on an external resource results in a parsing error. File-level defaults are ignored for externals.
  • External references do not add their namespaces to sync planning. Only namespaces from managed parent resources are considered when sync mode calculates deletes.
  • Child resources (portal pages, customizations, etc.) are still planned by resolving the external parent's Konnect ID. Ensure the owning team labels the parent (for example via kongctl adopt) so the ID can be resolved, but you do not need to (and cannot) assign a namespace to the external definition itself.

Resources managed by decK

Deck integration is configured on control planes via the _deck pseudo-resource. kongctl runs deck once per control plane that declares _deck, then resolves external gateway services by selector name. _external.requires.deck is not supported.

control_planes:
  - ref: prod-cp
    name: "prod-cp"
    _deck:
      files:
        - "kong.yaml"
      flags:
        - "--select-tag=kongctl"

    gateway_services:
      - ref: billing-gw
        _external:
          selector:
            matchFields:
              name: "billing-service"

Notes:

  • _deck is allowed only on control planes and only one _deck config is allowed per control plane.
  • _deck.files must include at least one state file.
  • _deck.flags can include additional deck flags (but not Konnect auth or output flags).
  • _external.selector.matchFields.name is required for external gateway services and must be the only selector field.
  • kongctl runs exactly one deck gateway apply or deck gateway sync per control plane that declares _deck.
  • Deck state files should include _info.select_tags and matching tags on entities so sync does not delete resources owned by other deck files. kongctl does not inject select tags for you.
  • Relative deck file paths are resolved relative to the declarative config file and must remain within the --base-dir boundary (default: the config file directory).
  • Plan files store deck base directories relative to the plan file location. When emitting a plan to stdout, the base directory is made relative to the current working directory (use --output-file for portable plans). Applying a plan resolves them from the plan file directory (or the current working directory when using --plan -).
  • kongctl plan/diff runs deck gateway diff to decide whether an external tool change is needed. kongctl apply runs deck gateway apply and kongctl sync runs deck gateway sync. For apply mode, deletes reported by deck diff are ignored.
  • If the control plane is being created in the same plan (or the ID is not available), kongctl skips deck diff and includes the external tool step.
  • For gateway steps, kongctl injects Konnect auth flags and output flags (--json-output --no-color); do not supply --konnect-token, --konnect-control-plane-name, --konnect-addr, or output flags yourself.
  • Plans represent deck resolution targets explicitly via post_resolution_targets on the _deck change entry, including control plane identifiers and the gateway service selector.

Namespace Enforcement Flags

The kongctl plan command provides built-in namespace guardrails:

  • --require-any-namespace forces every managed resource to declare a namespace via kongctl.namespace or _defaults.kongctl.namespace.
  • --require-namespace=<ns> restricts planning to the provided namespaces (repeat or comma-separate the flag to allow multiple values).

These flags help prevent accidentally operating on unexpected namespaces, especially when running in sync mode.

YAML Tags

YAML tags are like preprocessors for YAML file data. They allow you to load content from external files, reference across resources and extract specific values from structured data. Over time more tags may be added to support various functions and use cases.

Loading File Content to YAML Fields

Load the entire content of a file as a string:

apis:
  - ref: users-api
    name: "Users API"
    description: !file ./docs/api-description.md

Supported file types: Any text file (.txt, .md, .yaml, .json, etc.)

Value Extraction

You can extract specific values from structured data loaded from the file tag with this hash (#) notation:

apis:
  - ref: users-api
    name: !file ./specs/openapi.yaml#info.title # loads info.title field from the openapi.yaml file
    description: !file ./specs/openapi.yaml#info.description
    version: !file ./specs/openapi.yaml#info.version

    versions:
      - ref: v1
        spec: !file ./specs/openapi.yaml

Alternatively values can be extracted using this map format:

apis:
  - ref: products-api
    name: !file
      path: ./specs/products.yaml
      extract: info.title
    labels:
      contact: !file
        path: ./specs/products.yaml
        extract: info.contact.email

Path Resolution

All file paths are resolved relative to the directory containing the configuration file:

project/
├── config.yaml          # Main config file
├── specs/
│   ├── users-api.yaml
│   └── products-api.yaml
└── docs/
    └── descriptions.txt

In config.yaml:

apis:
  - ref: users-api
    name: !file ./specs/users-api.yaml#info.title
    description: !file ./docs/descriptions.txt

Security Features

Path Traversal Prevention: Absolute paths are blocked. Relative paths may include .., but the resolved path must stay within the base directory boundary. By default, the boundary is the root of each -f source (file: its parent dir, dir: the directory itself). For stdin, the boundary defaults to the current working directory. Set the base directory with --base-dir or konnect.declarative.base-dir (KONGCTL_<PROFILE>_KONNECT_DECLARATIVE_BASE_DIR, for example KONGCTL_DEFAULT_KONNECT_DECLARATIVE_BASE_DIR).

# ❌ These will fail with security errors
description: !file /etc/passwd

# ❌ This will fail if it resolves outside the base directory
config: !file ../../../sensitive/file.yaml

# ✅ These are allowed (if they stay within the base directory)
description: !file ../docs/description.txt
config: !file ./config/settings.yaml

File Size Limits: Files are limited to 10MB.

Performance Features

File Caching: Files are cached during a single execution to improve performance:

apis:
  - ref: api-1
    name: !file ./common.yaml#api.name        # File loaded and cached
    description: !file ./common.yaml#api.desc # Uses cached version
  - ref: api-2
    team: !file ./common.yaml#team.name       # Uses cached version

Commands Reference

The following are high level descriptions of commands for declarative configuration management. See the command usage text for details on command usage, flags and options.

plan

Create a plan - a JSON file containing the set of planned changes to a set of resources. Plans are generated with either --mode apply or --mode sync which determines whether resources missing from the input configuration are planned for deletion or not.

Generate an apply plan and output to STDOUT:

kongctl plan -f config.yaml --mode apply

Generate a sync plan and output to STDOUT:

kongctl plan -f config.yaml --mode sync

apply

Applying a configuration will create or update resources to match the desired state and will not delete resources. Because apply does not delete resources, it can be used for incremental application of resource configurations. For example, you could apply a portal in one command and then later apply apis in a separate command. With the sync command, this process is not possible as missing resources will be deleted.

Apply directly from config:

kongctl apply -f config.yaml

Apply from saved plan:

kongctl apply --plan plan.json

Preview changes without applying:

kongctl apply -f config.yaml --dry-run

sync

sync applies a set of configurations including deleting resources missing from the input configuration data.

Preview sync changes:

kongctl sync -f config.yaml --dry-run

Sync configuration with a prompt confirmation:

kongctl sync -f team-config.yaml

Skip confirmation prompt (caution!):

kongctl sync -f config.yaml --auto-approve

Sync from a plan artifact:

kongctl sync --plan plan.json

diff

Display preview of changes between current and desired state:

Preview changes in apply mode (CREATE and UPDATE only):

kongctl diff -f config.yaml --mode apply

Preview changes in sync mode (CREATE, UPDATE, and DELETE):

kongctl diff -f config.yaml --mode sync

Preview targeted deletions in delete mode (DELETE only for matching resources):

kongctl diff -f config.yaml --mode delete

Preview changes from a plan artifact:

kongctl diff --plan plan.json

Note: --mode cannot be used with --plan because mode is stored in the plan artifact metadata.

For UPDATE actions, text diff shows only the fields that would be changed. JSON and YAML outputs expose the same detail in each change's changed_fields object while keeping fields as the execution payload.

adopt

kongctl declarative configuration engine will only consider resources that are part of the list of kongctl.namespace values given to it during planning and execution of changes. There may be cases where you want to bring an existing Konnect resource into configuration that was created outside of the configuration management process. The adopt command enables you to add the proper namespace label to an existing Konnect resources without modifying any other fields. Once you adopt a resource, you need to add the configuration for it to your configuration set to ensure it is managed going forward.

Adopt a portal by name:

kongctl adopt portal my-portal --namespace team-alpha

Adopt a control plane by ID:

kongctl adopt control-plane 22cd8a0b-72e7-4212-9099-0764f8e9c5ac \
  --namespace platform

If the resource already has a KONGCTL-namespace label, the command fails without making changes.

dump

Export current Konnect resource state to various formats.

# Export all APIs with their child resources and include debug logging
# to tf-import format
kongctl dump tf-import --resources=api --include-child-resources
# Export all portal and api resources to 
# kongctl declarative configuration with format and the team-alpha namespace
kongctl dump declarative --resources=portal,api --default-namespace=team-alpha

CI/CD Integration

Key principles for CI/CD integration:

  1. Plan on PR: Generate and review plans in pull requests
  2. Apply on Merge: Apply reviewed plans when merged to target branch
  3. Environment Separation: Different configs for dev/staging/prod
  4. Approval Gates: Require human approval for production

Best Practices

Multi-Team Setup

Each team manages their own namespace:

# team-alpha/config.yaml
_defaults:
  kongctl:
    namespace: team-alpha

apis:
  - ref: frontend-api
    name: "Frontend API"
    # Automatically in team-alpha namespace

Environment Management

Use configuration profiles for different environments:

# Development environment
kongctl apply -f config.yaml --profile dev

# Production environment
kongctl apply -f config.yaml --profile prod

Security Best Practices

  1. Protect production resources:

    apis:
      - ref: payment-api
        kongctl:
          namespace: production
          protected: true
  2. Use namespaces for isolation:

    • One namespace per team
    • Separate namespaces for environments
    • Clear namespace ownership documentation
  3. Version control everything:

    • Configuration files
    • OpenAPI specifications
    • Documentation
  4. Review plans before applying:

    • Use plan in production
    • Save plans for audit trail
    • Implement approval workflows

Plan Artifact Workflows

Basic Plan Review Workflow

Developer creates plan:

kongctl plan -f config.yaml --output-file proposed-changes.json

Review changes visually:

kongctl diff --plan proposed-changes.json

Share plan for review (commit to git, attach to PR, etc.):

git add proposed-changes.json
git commit -m "Plan for adding new API endpoints"

After approval, apply the plan:

kongctl apply --plan proposed-changes.json

Production Deployment with Approval

# CI/CD Pipeline Stage 1: Plan Generation
kongctl plan -f production-config.yaml \
  --output-file plan-$(date +%Y%m%d-%H%M%S).json

# Stage 2: Manual approval gate
# - Plan artifact is stored as build artifact
# - Team reviews plan details
# - Approval triggers next stage

# Stage 3: Plan Execution
kongctl apply --plan plan-20240115-142530.json --auto-approve

Emergency Rollback Using Previous Plan

List recent plans (assuming you store them):

ls -la plans/

Review what the previous state included:

kongctl diff --plan plans/last-known-good.json

Revert to previous state:

kongctl sync --plan plans/last-known-good.json --auto-approve

Common Mistakes to Avoid

Setting kongctl on child resources:

# WRONG
apis:
  - ref: my-api
    kongctl:
      namespace: team-a
    versions:
      - ref: v1
        kongctl:  # ERROR - not supported on child resources
          protected: true

Correct approach:

# RIGHT
apis:
  - ref: my-api
    kongctl:
      namespace: team-a
      protected: true
    versions:
      - ref: v1

Using name as identifier:

# WRONG - using display name
api_publications:
  - ref: pub1
    api: "Users API"

Use ref for references:

# RIGHT - using ref
api_publications:
  - ref: pub1
    api: users-api

Field Validation

Kongctl uses strict YAML validation to catch configuration errors early:

# This will cause an error
portals:
  - ref: my-portal
    name: "My Portal"
    lables:  # ❌ ERROR: Unknown field 'lables'. Did you mean 'labels'?
      team: platform

Common field name errors:

  • lableslabels
  • descriptindescription
  • displaynamedisplay_name
  • strategytypestrategy_type

Troubleshooting

Common Issues

Authentication Failures:

  • Verify PAT is not expired
  • Check authentication: kongctl get me
  • Ensure proper credential storage

Plan Generation Failures:

  • Validate YAML syntax
  • Check file paths are correct
  • Verify network connectivity

Apply Failures:

  • Review plan for conflicts
  • Check for protected resources
  • Verify dependencies exist

File Loading Errors:

Error: failed to process file tag: file not found: ./specs/missing.yaml
  • Verify the file path is correct
  • Check that the file exists
  • Ensure proper relative path from config file location

Debug Mode

Enable verbose logging:

kongctl apply -f config.yaml --log-level debug

Enable trace logging for HTTP requests:

kongctl apply -f config.yaml --log-level trace

For more troubleshooting help, see the Troubleshooting Guide.

Examples

Browse the examples directory

Related Documentation

Resource Notes

Portal Custom Domains

  • kongctl plan / apply diff the live Konnect state before deciding what action to schedule. The portal custom domain API only returns a subset of fields (hostname, enabled, verification method, CNAME status, skip_ca_check, timestamps). The raw certificate and private key are never returned.
  • Because the UpdatePortalCustomDomain endpoint only patches the enabled flag, the planner emits an UPDATE change when the desired enabled value differs. Every other drift (hostname, verification method, skip_ca_check) is treated as an in-place replace: DELETE followed by CREATE.
  • Pure certificate rotations that keep the same verification method and skip_ca_check setting are invisible to the diff because Konnect does not echo those values. To force a replacement, temporarily change a detectable field (e.g., toggle skip_ca_check or switch verification method), or remove the domain from configuration, apply, and then reintroduce it with the new certificate material.