apache / apache/apisix

feat: Filter Consul services by metadata or tags

Open
#13,184 2 comments 0 reactions 0 assignees View on GitHub
feature-request
Dominant language
Lua
Stars
17.1k
Forks
2.9k
Avg merge
3d 16h
Merged PRs (30d)
63

Description

### Description

Hello,

I try to configure APISIX to implement canary deployment on microservices registered to Consul.

Basically,
- I register multiple service instances sharing the same logical "service name" on Consul
- I tag every instance (using tags or metadata) to differentiate "_stable_" instances from "_canary_" instances.

See below an example of Consul registration:

```
# Register stable my_service instance
curl -X PUT http://localhost:8500/v1/agent/service/register -H "Content-Type: application/json" \
-d '{
"ID": "my_service_stable",
"Name": "my_service",
"Address": "192.xxx",
"Tags": ["stable"],
"Meta": {
"version": "stable"
}
}'

# Register canary my_service instance
curl -X PUT http://localhost:8500/v1/agent/service/register -H "Content-Type: application/json" \
-d '{
"ID": "my_service_canary",
"Name": "my_service",
"Address": "192.xxx",
"Tags": ["canary"],
"Meta": {
"version": "canary"
}
}'
```

On Consul, it looks like:

Image

Then, on APISIX, I would like to split my traffic according to these tags or metadata values.

Something like:
(_metadata_match_ is here for illustration only; it's the purpose of this issue)
```
curl -H "X-API-KEY: $APISIX_ADMIN_KEY" -X PUT http://localhost:9180/apisix/admin/routes/route_my_service \
-d '{
"uri": "/my_service",
"plugins": {
"traffic-split": {
"rules": [
{
"weighted_upstreams": [
{
"weight": 80,
"upstream": {
{
"type": "roundrobin",
"service_name": "dummy",
"discovery_type": "consul",
"discovery_args": {
"metadata_match": { "version": ["stable"] }
}
}
}
},
{
"weight": 20,
"upstream": {
{
"type": "roundrobin",
"service_name": "dummy",
"discovery_type": "consul",
"discovery_args": {
"metadata_match": { "version": ["canary"] }
}
}
}
},

]
}
]
}
}
}'
```

Unfortunately, filtering/matching seems not to be supported now; am I right?

So currently, the only way I found so far is to create separate services on Consul (one named _stable_ and one named _canary_) but it's a workaround (Consul service registry is made to group all service instances into a common logical service).

In the APISIX git history, I found [this commit](https://github.com/apache/apisix/blob/b61504bb4199f7683ad3f7bc6a1fabfc7d0ea30a/t/discovery/consul.t#L855-L997) that was illustrating what I wish by a test; is this feature already coded? planned?

Thank you for your great work.
Best regards

Contributor guide

Open the contributing guide

Research direction

Start by reading the Consul discovery test in t/discovery/consul.t, especially lines 855-997 and the linked historical commit. Check whether the existing discovery arguments support service tags or metadata matching, then trace the related Consul discovery entry points. Done means stable and canary instances of one logical service can be selected separately through the proposed metadata or tag filters, with tests covering both forms.

Written by the indexing model from the issue text.

Assessment

Tech stack
lua
Domain
api, backend, distributed-systems
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.