kong – 2 services same route

In Kong Gateway, you cannot have two services bound to the exact same route — a route must be unique in terms of its combination of matching rules (such as paths, hosts, methods, etc.).


Why You Can’t Have Duplicate Routes

Kong uses the route’s matching criteria to determine which service should handle a request. If two routes have the same matching rules, Kong can’t disambiguate, which leads to a conflict error when trying to create the second route.

For example:

# Service A
curl -i -X POST http://localhost:8001/services/ --data name=service-a --data url=http://api-a
curl -i -X POST http://localhost:8001/routes --data name=route-a --data service.name=service-a --data paths[]=/api

# Service B
curl -i -X POST http://localhost:8001/services/ --data name=service-b --data url=http://api-b
curl -i -X POST http://localhost:8001/routes --data name=route-b --data service.name=service-b --data paths[]=/api

The second POST /routes will fail with:

HTTP 409 Conflict – duplicate entry


Workarounds / Alternatives

GoalSolution
Blue/Green or Canary DeploymentsUse Kong Plugins (e.g., traffic-split, canary) or upstreams and targets instead of duplicate routes.
Different consumers/users hitting different backendsUse request transformers, ACLs, or Kong Enterprise Route-by-header/Route-by-consumer plugins.
Same path, different method or hostYou can differentiate routes by methods[], hosts[], or headers.

🧪 Example: Two Routes with Same Path, Different Hosts

# Route 1
curl -i -X POST http://localhost:8001/routes \
  --data name=api-v1 \
  --data paths[]=/api \
  --data hosts[]=v1.example.com \
  --data service.name=service-a

# Route 2
curl -i -X POST http://localhost:8001/routes \
  --data name=api-v2 \
  --data paths[]=/api \
  --data hosts[]=v2.example.com \
  --data service.name=service-b

These can coexist because their hosts[] fields are different.


Summary

Route Matching RuleMust Be Unique For
paths[]Same host/methods/headers
hosts[]If combined with same path
methods[], headersCan disambiguate routes with same path

Setting Up a YUM Repository (RHEL/CentOS)

A. Setting Up a YUM Repository (RHEL/CentOS)

1. Install and Configure a Web Server

Most repositories are served via HTTP. In this example, we’ll use Apache (httpd):

  1. Install Apache:bashCopyEditsudo yum install httpd -y
  2. Enable and start Apache:bashCopyEditsudo systemctl enable httpd sudo systemctl start httpd
  3. Verify that Apache is running:
    Open your browser and navigate to http://<your-server-IP>/ to see the Apache welcome page.

2. Create the Repository Directory

  1. Make a directory to hold your repository files:bashCopyEditsudo mkdir -p /var/www/html/myrepo
  2. Copy your RPM packages into this directory:bashCopyEditsudo cp /path/to/your/rpms/*.rpm /var/www/html/myrepo/

3. Generate Repository Metadata

  1. Install the createrepo tool:bashCopyEditsudo yum install createrepo -y
  2. Run createrepo in your repository directory:bashCopyEditsudo createrepo /var/www/html/myrepo This command creates a repodata directory with all the necessary metadata for the repository.

4. Set Proper Permissions

  1. Ensure Apache can read the files:bashCopyEditsudo chmod -R 755 /var/www/html/myrepo
  2. If SELinux is enabled, adjust the file context:bashCopyEditsudo chcon -R -t httpd_sys_content_t /var/www/html/myrepo

5. (Optional) Configure the Firewall

Make sure HTTP traffic is allowed:

  • For firewalld:bashCopyEditsudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --reload

ansible-playbook

---
- name: Delete multiple routes in Kong API Gateway
  hosts: localhost
  gather_facts: false
  tasks:
    - name: Get all routes from Kong
      uri:
        url: "http://localhost:8001/routes"
        method: GET
        return_content: yes
        status_code: 200
      register: kong_routes

    - name: Extract the list of route IDs to delete
      set_fact:
        route_ids: "{{ kong_routes.json.data | map(attribute='id') | list }}"

    - name: Show the route IDs to delete
      debug:
        msg: "Route ID: {{ item }}"
      loop: "{{ route_ids }}"

    - name: Delete each route by its ID
      uri:
        url: "http://localhost:8001/routes/{{ item }}"
        method: DELETE
        status_code: 204
      loop: "{{ route_ids }}"
      when: item is defined
---
- name: Delete multiple services in Kong API Gateway
  hosts: localhost
  gather_facts: false
  tasks:
    - name: Get all services from Kong
      uri:
        url: "http://localhost:8001/services"
        method: GET
        return_content: yes
        status_code: 200
      register: kong_services

    - name: Extract the list of route IDs to delete
      set_fact:
        service_ids: "{{ kong_services.json.data | map(attribute='id') | list }}"

    - name: Show the service IDs to delete
      debug:
        msg: "Service ID: {{ item }}"
      loop: "{{ service_ids }}"

    - name: Delete each service by its ID
      uri:
        url: "http://localhost:8001/services/{{ item }}"
        method: DELETE
        status_code: 204
      loop: "{{ service_ids }}"
      when: item is defined

Kong Service

---
- name: Create Services with Service Paths and Routes in Kong API Gateway
  hosts: localhost
  tasks:

    # Define a list of services, their service paths, and routes
    - name: Define a list of services, service paths, and routes
      set_fact:
        services:
          - { name: service1, service_url: http://example-service1.com:8080/service1, route_name: route1, route_path: /service1 }
          - { name: service2, service_url: http://example-service2.com:8080/service2, route_name: route2, route_path: /service2 }
          - { name: service3, service_url: http://example-service3.com:8080/service3, route_name: route3, route_path: /service3 }

    # Create a Service in Kong for each service defined, including service path
    - name: Create Service in Kong
      uri:
        url: http://localhost:8001/services
        method: POST
        body_format: json
        body:
          name: "{{ item.name }}"
          url: "{{ item.service_url }}"  # Service URL (including the service path)
        status_code: 201
      loop: "{{ services }}"
      register: service_creation

# Create a Route for each Service
    - name: Create Route for the Service
      uri:
        url: http://localhost:8001/routes
        method: POST
        body_format: json
        body:
          service:
            name: "{{ item.name }}"
          name: "{{ item.route_name }}"  # Route name
          paths:
            - "{{ item.route_path }}"  # Route path (external access path)
        status_code: 201
      loop: "{{ services }}"
      when: service_creation is succeeded

    # Optionally verify that services and routes were created
    - name: Verify Service and Route creation
      uri:
        url: http://localhost:8001/services/{{ item.name }}
        method: GET
        status_code: 200
      loop: "{{ services }}"