Kong & Deck. CI/CD

DECK

Deck is a tool that helps you manage your Kong configuration in a declarative way. This configuration can be conveniently stored in the code repository. Deck is responsible for synchronizing the Kong configuration in the code repository with the running Kong instance. It was created mainly to make it easy to automate Kong configuration management in CI/CD processes.

null

Deck functions:

  • exports current Kong configuration to a yaml configuration file. Useful for making backups
  • importing a configuration file that we have created ourselves or previously exported to supply the database that Kong uses
  • analysis of differences between the configuration contained in the file and the Kong database
  • synchronization of changes between the configuration in the configuration file and the Kong database
  • configuration validation. Useful for quickly identifying configuration errors
  • splitting the configuration into several files, folders with files

Basic Deck commands:

  • deck ping - checking the connection between the deck and the running Kong instance
  • deck diff - examining the differences between the configuration in the file and the current Kong instance
  • deck validate - configuration validation
  • deck sync - configuration synchronization

More information about the Deck incl. installation available here.

CI/CD

In this post, I will present CI/CD mechanisms using Deck and Github Actions.

Requirements:

  • access is Github
  • Kong instance running
  • access to Kong from the level of Github (very often our instance of Kong will operate inside an organization to which we will not have access from the level of Github. For this purpose, you can use Github's self-hosted runners. In the above post I used this approach)
  • Docker tool installed
  • decK tool installed (you can also use a ready-made Docker image)

PREPARING THE PROJECT

Creating folders for storing configuration:

mkdir -p kong-deck-actions/kong
cd kong-deck-actions/kong/

Then we export the current Kong configuration to the configuration file - kong.yaml. Command: (I have the decK utility installed on the host server, and the deck is running locally):

deck dump –kong-addr http://localhost:8001

In my case, the contents of the configuration file are as follows:

_format_version: „1.1”

The next step is to publish the prepared configuration to the remote Github repository.

GITHUB ACTIONS CONFIGURATION

Next, we should configure Github Actions to automate the Kong configuration deployment process. For this, we need to prepare several files in the same Git repository that we created in the previous step.

First, you need to create a file called actions.yaml, which contains the basic action to be performed, based on the docker image and a set of parameters to be performed.

The contents of the action.yaml file:

name: 'decK action'
description: 'Declarative Configuration management for Kong'
inputs:
  command:
    description: 'A decK ping command'
    required: true
    default: 'ping'
  kong_workspaces:
     description: 'Kong workspaces where config yaml file is located'
     required: true
     default: 'kong'
  options:
    description: 'Option parameters for a decK command'
    required: false
  runs:
    using: 'docker'
    image: 'Dockerfile'
  args:
     ${{ inputs.command }}
     ${{ inputs.kong_workspaces }}
     ${{ inputs.options }}

We prepare the Dockerfile file used by the above-defined action.yaml file. Dockerfile Contents:

FROM kong/deck
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT [ „/entrypoint.sh” ]

Next, we create entrypoint.sh referenced in Dockerfile. The contents of entrypoint.sh:

#!/bin/sh -l
set -e -o pipefail
main (){
  cmd=$1
  dir=$2
  ops=$3
  if [ ! -e ${dir} ]; then
    echo${dir}: No such file or directory exists”;
    exit 1;
  fi
  echo „Executing: deck $cmd $ops -s $dir”
  deck $cmd $ops -s $dir
}

case $1 in
  „ping”) deck $1 $3;;
  „validate”|”diff”|”sync”) main $1 $2$3” ;;
  * ) echo „deck $1 is not supported.” && exit 1 ;;
esac

Warning! It is important to give this file execute permission:

chmod +x entrypoint.sh

WORKFLOW

In the next stage, we should prepare workflow files that will be responsible for launching our action. Workflow files should be defined under the path: ".github/workflow/". The first file named CI.yaml will be responsible for executing the action on the Pull request Event, while the second - SYNC.yaml will be responsible for executing the action if we merge to the master branch.

The content of CI.yaml:

name: CI
on:
  pull_request:
    branches: [ master ]
jobs:
  build:
    runs-on: self-hosted
    steps:
     uses: actions/checkout@v2
      name: „checkout”
     name: decK ping
      id: decK_ping
      uses: ./
      with:
        command: „ping”
        options: „–kong-addr ${{ secrets.KONG_ADDR }}”
       name: decK validate
        id: decK_validate
        uses: ./
      with:
        command: „validate”
        options: „–kong-addr ${{ secrets.KONG_ADDR }}”
        kong_workspaces: „kong”
       name: decK diff
        id: decK_diff
        uses: ./
        with:
          command: „diff”
          options: „–kong-addr ${{ secrets.KONG_ADDR }}”
          kong_workspaces: „kong”

This flow is responsible for the execution of 4 actions:

  • source code download
  • execution of the deck ping command to confirm the connection with Kong
  • execution of the deck validate command to confirm the correctness of the configuration
  • executing the deck diff command to see the differences between the configuration in the file and the contents of the Kong database

There is a variable in the file: secrets.KONG_ADDR, which we can define as a secret in Github (Settings -> Secrets):

Communication between decK and Kong takes place between the containers defined in the default bridge network, so in this case, I set the IP address of the Docker container on which the Kong instance is running.

null

The last step of this stage is to prepare the workflow responsible for synchronizing the configuration if we merge any changes to the master branch.

The content of SYNC.yaml:

name: Sync
on:
  push:
    branches: [ master ]
jobs:
  build:
   runs-on: self-hosted
  steps:
    uses: actions/checkout@v2
     name: „checkout”
    name: decK ping
     id: decK_ping
     uses: ./
     with:
      command: „ping”
      options: „–kong-addr ${{ secrets.KONG_ADDR }}”
     name: decK validate
      id: decK_validate
      uses: ./
      with:
        command: „validate”
        options: „–kong-addr ${{ secrets.KONG_ADDR }}”
        kong_workspaces: „kong”
     name: decK sync
      id: decK_sync
      uses: ./
      with:
        command: „sync”
        options: „–kong-addr ${{ secrets.KONG_ADDR }}”
        kong_workspaces: „kong”

We publish the prepared files to a remote repository.

TESTING

Finally, we can test the created CI/CD mechanisms. To do this, create a new branch, e.g. git branch -b feature / addService and then change the kong.yaml file:

_format_version: „1.1”
services:
 connect_timeout: 60000
  host: mockbin.org
  name: test_service
  port: 80
  protocol: http
  read_timeout: 50000
  retries: 5
  write_timeout: 50000
  routes:
   name: mocking
    paths:
   /mock
  path_handling: v0
  preserve_host: false
  protocols:
   http
   https
  regex_priority: 0
  strip_path: true
  https_redirect_status_code: 426

Then, from the level of Github, open a pull request to the branch master. The tasks defined in the CI.yaml file should run.

null

As you can see, the deck has completed certain steps and we have a transparent preview of the configuration we want to change.

The last step is to merge the changes.

null

SUMMARY

The article presents an example of the implementation of the CI/CD process using the deck and GitHub tools. Of course, this is just an example and the choice of tools is free. A similar result can also be obtained with the use of technologies such as Github, Jenkins and Ansible.