Deploy services in KONG

To export a Kong service with its route(s) and plugin(s) and re-deploy it via Ansible, follow this structured approach:


Step 1: Export Kong Configuration (Service + Route + Plugins)

Use Kong’s Admin API or deck (Kong’s declarative configuration tool).

Option A: Use deck

deck dump –select-tag my-service-tag –output-file exported.yaml

🔹 Tagging helps isolate what to export (tag services, routes, plugins with my-service-tag beforehand).
🔹 You can also export the full config with deck dump.

Option B: Use cURL (for manual/scripted extraction)

# Get service

curl -s http://<KONG_ADMIN&gt;:8001/services/my-service > service.json

# Get route(s) for the service

curl -s http://<KONG_ADMIN&gt;:8001/services/my-service/routes > routes.json

# Get plugins for the service

curl -s http://<KONG_ADMIN&gt;:8001/services/my-service/plugins > plugins.json


 Step 2: Transform into Ansible-compatible format

Create a folder structure:

kong/

├── files/

│   └── exported.yaml  # if using deck

├── templates/

│   └── service.json.j2

│   └── routes.json.j2

│   └── plugins.json.j2

└── tasks/

    └── deploy-kong.yml


✅ Step 3: Create Ansible Playbook

If using deck:

# tasks/deploy-kong.yml

– name: Deploy config to Kong via deck

  ansible.builtin.command:

    cmd: “deck sync –state exported.yaml”

  args:

    chdir: “{{ playbook_dir }}/files”

If using cURL approach (raw API):

- name: Create service in Kong
  uri:
    url: "http://{{ kong_admin_host }}:8001/services"
    method: POST
    body: "{{ lookup('file', 'templates/service.json.j2') | from_json }}"
    body_format: json
    status_code: [201, 409]  # 409 = already exists
    headers:
      Content-Type: "application/json"

- name: Create route for the service
  uri:
    url: "http://{{ kong_admin_host }}:8001/services/{{ service_name }}/routes"
    method: POST
    body: "{{ lookup('file', 'templates/routes.json.j2') | from_json }}"
    body_format: json
    status_code: [201, 409]
    headers:
      Content-Type: "application/json"

- name: Add plugins to service
  uri:
    url: "http://{{ kong_admin_host }}:8001/services/{{ service_name }}/plugins"
    method: POST
    body: "{{ lookup('file', 'templates/plugins.json.j2') | from_json }}"
    body_format: json
    status_code: [201, 409]
    headers:
      Content-Type: "application/json"

   

Step 4: Run Playbook

ansible-playbook deploy-kong.yml -e “kong_admin_host=your.kong.gateway”


 Optional: Use Tags to Scope with deck

Tag services during creation to support selective dumps later:

curl -X PATCH http://localhost:8001/services/my-service \

  –data “tags=my-service-tag”

example of j2

{
  "name": "my-service",
  "host": "example.internal",
  "port": 8080,
  "protocol": "http",
  "path": "/api",
  "connect_timeout": 60000,
  "write_timeout": 60000,
  "read_timeout": 60000,
  "retries": 5,
  "tags": ["exported", "my-tag"]
}

Full ansible playbook 

---
- name: Deploy Kong service with routes and plugins
  hosts: kong
  gather_facts: no
  vars:
    kong_admin_url: "{{ kong_admin_host | default('http://localhost:8001') }}"
  tasks:

    - name: Load service JSON
      set_fact:
        service_payload: "{{ lookup('file', 'templates/service.json.j2') | from_json }}"

    - name: Create service
      uri:
        url: "{{ kong_admin_url }}/services"
        method: POST
        body: "{{ service_payload }}"
        body_format: json
        status_code: [201, 409]
        headers:
          Content-Type: "application/json"

    - name: Load routes JSON (could be a single or multiple routes)
      set_fact:
        routes_payload: "{{ lookup('file', 'templates/routes.json.j2') | from_json }}"

    - name: Create route(s) for the service
      uri:
        url: "{{ kong_admin_url }}/services/{{ service_payload.name }}/routes"
        method: POST
        body: "{{ item }}"
        body_format: json
        status_code: [201, 409]
        headers:
          Content-Type: "application/json"
      loop: "{{ routes_payload | type_debug == 'list' | ternary(routes_payload, [routes_payload]) }}"

    - name: Load plugins JSON
      set_fact:
        plugins_payload: "{{ lookup('file', 'templates/plugins.json.j2') | from_json }}"

    - name: Add plugin(s) to the service
      uri:
        url: "{{ kong_admin_url }}/services/{{ service_payload.name }}/plugins"
        method: POST
        body: "{{ item }}"
        body_format: json
        status_code: [201, 409]
        headers:
          Content-Type: "application/json"
      loop: "{{ plugins_payload }}"

Leave a comment