Introduction
Adding tags for existing services in the Consul catalog is not a straightforward process. Here's a guide on how to do that.
Prerequisites
- Consul
- A registered service that has enable_tag_override set to true
Overview of procedure
Adding tags to an existing Consul service is a two-part process - first, we need to grab some information regarding the service itself and the node that it's running on; and then we will construct an API request and send it to update the information.
Use Case and Mechanics of Consul Services
First of all, let's elaborate on the mechanics of how services are registered.
Every Consul cluster consists of Consul agents - some of which could have a server role, some of which could have a client role.
Each Consul agent maintains its own set of services and is responsible for checking their health and updating their local state.
Services within the context of an agent have a rich set of configuration options available. This is because the agent is responsible for generating information about its services and their state. Therefore, one way of adding tags to a Consul Service would be to target the agent that registers it, and modify the specific service registration to include the new tags; however, this means that the service will need to be re-registered, which is not always an elegant solution.
Moving past service registrations, all Consul agents share the Consul catalog.
Consul's service discovery is backed by a service catalog. This catalog is formed by aggregating information submitted by the agents. The catalog maintains the high-level view of the cluster, including what services are available, which nodes run those services, health information, and more. The catalog is used to expose this information via the various interfaces Consul provides, including DNS and HTTP.
Services within the context of the catalog have a much more limited set of fields when compared with the agent. This is because the catalog is only responsible for recording and returning information about services, nodes, and service health.
With that in mind, if we are to just add tags to an existing Consul Service without having to deregister and reregister it with its Consul agent, we can modify the Consul Catalog directly.
Sample Environment
In this example, we are using both Consul and Nomad running in development mode. The local Consul node name is consul-dev-node
. We have registered a sample job redis-sampleapp
in Nomad and we can observe it is being registered successfully in Consul as a service.
Procedure
Step 1
We list all the services running on our node and pick the one we would like to add tags to:
$ curl http://127.0.0.1:8500/v1/catalog/node-services/consul-dev-node.local
{
"Node": {
"ID": "0424c120-da24-d061-cb36-f4739a30bbc2",
"Node": "consul-dev-node.local",
"Address": "127.0.0.1",
"Datacenter": "dc1",
"TaggedAddresses": {
"lan": "127.0.0.1",
"lan_ipv4": "127.0.0.1",
"wan": "127.0.0.1",
"wan_ipv4": "127.0.0.1"
},
"Meta": {
"consul-network-segment": ""
},
"CreateIndex": 11,
"ModifyIndex": 13
},
"Services": [
[output omitted for brevity]
{
"ID": "_nomad-task-37a9a4c2-7822-8a11-21c0-8622f1da3b15-redis-redis-sampleapp-redis-6379",
"Service": "redis-sampleapp-redis",
"Tags": [
"4",
"37a9a4c2-7822-8a11-21c0-8622f1da3b15"
],
"Address": "172.17.0.6",
"TaggedAddresses": {
"lan_ipv4": {
"Address": "172.17.0.6",
"Port": 6379
},
"wan_ipv4": {
"Address": "172.17.0.6",
"Port": 6379
}
},
"Meta": {
"external-source": "nomad"
},
"Port": 6379,
"Weights": {
"Passing": 1,
"Warning": 1
},
"EnableTagOverride": true,
"Proxy": {
"MeshGateway": {},
"Expose": {}
},
"Connect": {},
"CreateIndex": 936,
"ModifyIndex": 936
},
[output omitted for brevity]
}
]
}
From the above output we can see that the service we have picked to add tags to has currently only two tags - 4
and 37a9a4c2-7822-8a11-21c0-8622f1da3b15
.
Step 2
With the help of the output of the first step, we will create a valid JSON request for the Consul Catalog service register API call with the info from that specific instance. In this case we are going to add two tags to the service - master
and master3
. Here is a sample JSON payload for adding the two tags to the redis-sampleapp-redis
service. All the information needed in this payload can be found in the previous step's output.
service-update.json:
{
"ID": "0424c120-da24-d061-cb36-f4739a30bbc2",
"Node": "consul-dev-node.local",
"Address": "127.0.0.1",
"Datacenter": "dc1",
"TaggedAddresses": {
"lan": "127.0.0.1",
"lan_ipv4": "127.0.0.1",
"wan": "127.0.0.1",
"wan_ipv4": "127.0.0.1"
},
"NodeMeta": {
"consul-network-segment": ""
},
"Service": {
"ID": "_nomad-task-db492081-ffcd-fc2b-f25c-cc48079c5bf1-redis-redis-sampleapp-redis-6379",
"Service": "redis-sampleapp-redis",
"Tags": [
"5",
"db492081-ffcd-fc2b-f25c-cc48079c5bf1",
"master",
"master3"
],
"Address": "127.0.0.1",
"Port": 6379,
"Meta": {
"external-source": "nomad"
},
"EnableTagOverride": true
}
}
Step 3
We run the request towards the specific API endpoint:
$ curl --request PUT --data @service-update.json http://127.0.0.1:8500/v1/catalog/register
true
Let's test if our changes have taken place:
$ curl http://127.0.0.1:8500/v1/catalog/node/consul-dev-node.local
[output omitted for brevity]
"_nomad-task-db492081-ffcd-fc2b-f25c-cc48079c5bf1-redis-redis-sampleapp-redis-6379": {
"ID": "_nomad-task-db492081-ffcd-fc2b-f25c-cc48079c5bf1-redis-redis-sampleapp-redis-6379",
"Service": "redis-sampleapp-redis",
"Tags": [
"5",
"db492081-ffcd-fc2b-f25c-cc48079c5bf1",
"master",
"master3"
],
[output omitted for brevity]
Summary
As outlined by the procedure, there is no direct and easy method of just adding tags to a service in the Consul Catalog. Much of the steps can be automated, and there have been third party tools that did that part. Ultimately, the process boils down to modifying either the Consul Agent's service registration; or the Consul Catalog registration.