feat: Filter Consul services by metadata or tags
- 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:
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
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