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>:8001/services/my-service > service.json
# Get route(s) for the service
curl -s http://<KONG_ADMIN>:8001/services/my-service/routes > routes.json
# Get plugins for the service
curl -s http://<KONG_ADMIN>: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 }}"