hashicorp / hashicorp/consul

service-router and service-splitter config entries should allow targeting a datacenter

Open
#7,688 0 comments 1 reaction 0 assignees View on GitHub
theme/connect theme/operator-usability type/enhancement
Dominant language
Go
Stars
30.1k
Forks
4.6k
Avg merge
2d 6h
Merged PRs (30d)
43

Description

When `service-router`, `service-splitter` and `service-resolver` were all introduced in Consul 1.6 they all were written to work together when compiling the [discovery chain](https://www.consul.io/docs/internals/discovery-chain.html). For each route on a `service-router` or each split on a `service-splitter` you can point to the next logical service name for that respective traffic adjustment. One deliberate omission is the ability to explicitly point to a service _in a datacenter_ directly in that section of the config entry. For that you must end up making a named "virtual service" and pointing to that like:

```
{
kind = "service-defaults"
name = "web"
protocol = "http"
}
{
kind = "service-defaults"
name = "web-dc1"
protocol = "http"
}
{
kind = "service-defaults"
name = "web-dc2"
protocol = "http"
}
{
kind = "service-splitter"
name = "web"
splits = [
{
weight = 50,
service = "web-dc1",
},
{ weight = 50,
service = "web-dc2",
},
]
}
{
kind = "service-resolver"
name = "web-dc1"
redirect {
service = "web"
datacenter = "dc1"
}
}
{
kind = "service-resolver"
name = "web-dc2"
redirect {
service = "web"
datacenter = "dc2"
}
}
```

Most of the original justification for this design choice of disallowing `datacenter` from being specified in a route/split is likely not as valid given how some details of the implementation ended up working out in practice. The only definitely remaining justification is to avoid "having two ways of configuring the same thing" since there's nothing stopping you from doing redirect-based virtual services anyway if this feature exists.

But from an end-user ergonomics perspective we might want to make the whole virtual service thing easier to use in this example by just doing all of that as a discovery chain compile-time implicit creation rather than an actual config entry that the user must create and manage. During compilation we could just go through the same compilation motions we would as if the redirect were present, but without actually making it (so not a whole lot of new logic would be needed). The end result should make it so that the user could just do this to achieve the same thing as above:

```
{
kind = "service-defaults"
name = "web"
protocol = "http"
}
{
kind = "service-splitter"
name = "web"
splits = [
{
weight = 50,
datacenter = "dc1", // implicitly acts like you had a virtual service defined
},
{ weight = 50,
datacenter = "dc2", // implicitly acts like you had a virtual service defined
},
]
}
```

As a bonus, you also wouldn't need to create `service-defaults` for the virtual services just to upgrade them to a L7-aware protocol.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.