Automate services and nodes relation

Hi community,

I am a bit confused by the consul documentation and training materials.
I also browsed this category for an answer without success.

I basically would like to register a prometeus service having two nodes automatically at the end of the consul cluster setup.

I followed the instructions of the https://learn.hashicorp.com/consul/getting-started/services leaning material.

cat /tmp/prometheus.json 
{
"services": [
  {
    "address": "10.0.0.42",
    "name": "prometheus",
    "tags": ["prometheus"],
    "port": 443,
    "id": "prometheus-dev-0"
  },
  {
    "address": "10.0.0.43",
    "name": "prometheus",
    "tags": ["prometheus"],
    "port": 443,
    "id": "prometheus-dev-1"
  }]
}

registering over the consul cli:

consul services register /tmp/prometheus.json
Registered service: prometheus
Registered service: prometheus

testing it out with ping also works fine balancing between 42 and 43 ips.
Yet the consul catalog nodes does not have appropriate nodes assigned, not prometheus-dev-0 neither prometheus-dev-1 are registered.

Searching about a way to then automate the node registration, I did not find anything in the consul cli.

After some more digging I found out that for registering external nodes, the following API documents it, https://www.consul.io/api/catalog.html#register-entity

cat /tmp/node0.json /tmp/node1.json 
{
  "Node": "prometheus-dev-0", 
  "Address": "10.0.0.42"
}
{
  "Node": "prometheus-dev-1", 
  "Address": "10.0.0.43"
}

# note we cannot register 2 nodes at the same time within one node.json file ?!
curl --header "X-Consul-Token: $CONSUL_HTTP_TOKEN" --request PUT --data @/tmp/node0.json https://localhost:8501/v1/catalog/register
curl --header "X-Consul-Token: $CONSUL_HTTP_TOKEN" --request PUT --data @/tmp/node1.json https://localhost:8501/v1/catalog/register

then I now can ping the nodes using the prometheus-dev-0.node.

Still when I dump the catalog configuration:

curl -sq https://consul.service.<fqdn>:8501/v1/catalog/service/prometheus | jq

I can see that the first section where the nodes are defined are holding the consul node ip not any external node ip related to the prometheus service:

[
  {
    "ID": "b9...",
    "Node": "consul-dev-1",
    "Address": "10.0.0.23",
    "Datacenter": "infra-dev",
    "TaggedAddresses": {
      "lan": "10.0.0.23",
      "wan": "10.0.0.23"
    },
    "NodeMeta": {
      "consul-network-segment": ""
    },
    "ServiceKind": "",
    "ServiceID": "prometheus-dev-0",
    "ServiceName": "prometheus",
    "ServiceTags": [
      "prometheus"
    ],
    "ServiceAddress": "10.0.0.42",
    "ServiceWeights": {
      "Passing": 1,
      "Warning": 1
    },
    "ServiceMeta": {},
    "ServicePort": 443,
    "ServiceEnableTagOverride": false,
    "ServiceProxy": {
      "MeshGateway": {}
    },
    "ServiceConnect": {},
    "CreateIndex": 5211,
    "ModifyIndex": 5211
  },
  {
    "ID": "b9...",
    "Node": "consul-dev-1",
    "Address": "10.0.0.23",
    "Datacenter": "infra-dev",
    "TaggedAddresses": {
      "lan": "10.0.0.23",
      "wan": "10.0.0.23"
    },
    "NodeMeta": {
      "consul-network-segment": ""
    },
    "ServiceKind": "",
    "ServiceID": "prometheus-dev-1",
    "ServiceName": "prometheus",
    "ServiceTags": [
      "prometheus"
    ],
    "ServiceAddress": "10.0.0.43",
    "ServiceWeights": {
      "Passing": 1,
      "Warning": 1
    },
    "ServiceMeta": {},
    "ServicePort": 443,
    "ServiceEnableTagOverride": false,
    "ServiceProxy": {
      "MeshGateway": {}
    },
    "ServiceConnect": {},
    "CreateIndex": 5212,
    "ModifyIndex": 5212
  }
]

In the ui the same the Node is the one consul agent.

inverting the order first registering the nodes and then the services does not change anything. What did I miss?

Concerning the automation, is there a way to register nodes and services within one json file, like importing the previously json output of https://consul.service.<fqdn>:8501/v1/catalog/service/prometheus in a nodes-services.json file and fire up:

curl --header "X-Consul-Token: $CONSUL_HTTP_TOKEN" --request PUT --data @nodes-services.json https://localhost:8501/v1/catalog/register

If possible would these json be part of the /etc/consul.d/ configuration directory?

I mean installing vault on top of the consul cluster seems to do some magic are the nodes and the services correspond, how can this be achieved?

I am glad for any help?

If I’m understanding correctly, you are registering two services on nodes that do not have Consul clients. If that is correct, we have a guide specifically for this common use case. You should be able to register the node and service in the same file at the same time.

1 Like

Thanks for pointing out this documentation, I was now able to add some external nodes and assign them to services.
Still I had to separate them into two separate calls:

cat /etc/consul.d/prometheus-dev-0.json
{
  "Node": "prometheus-dev-0",
  "Address": "10.0.0.42",
  "NodeMeta": {
    "external-node": "true",
    "external-probe": "true"
  },
  "Service": {
    "ID": "prometheus-dev-0",
    "Service": "prometheus",
    "Port": 443
  },
  "Checks": [
    {
      "Name": "http-check",
      "status": "passing",
      "Definition": {
        "http": "https://prometheus-dev-0.node.infra-dev.consul",
        "interval": "30s"
      }
    }
  ]
}

executing curl:

curl --header "X-Consul-Token:$CONSUL_HTTP_TOKEN" --request PUT --data @/etc/consul.d/prometheus-dev-0.json https://localhost:8501/v1/catalog/register'
curl --header "X-Consul-Token:$CONSUL_HTTP_TOKEN" --request PUT --data @/etc/consul.d/prometheus-dev-1.json https://localhost:8501/v1/catalog/register'

resulted in the service declared accordingly in the ui

Note that the Address field seems to be incomplete as it just has the port definition, maybe it’s a “ServiceAddress” parameter missing in the definition…

Thanks for the help.