Best way to get peer node information in a job specification

Seems I found a solution (after many intense hours…)

Use a template block with consul service lookup, with env set to true (check the docs on that) .

E.g.

      template {
        env = true
        change_mode = "noop"
        destination = "docker_env"
        data = <<EOF
KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=
  {{- range $i, $e := service "kafka-broker" -}}
    {{- if eq $i 0 -}}
      {{$i}}@{{ .Address }}:{{ .Port }}
    {{- else -}}
      ,{{$i}}@{{ .Address }}:{{ .Port }}
    {{- end -}}
  {{- end}}
        EOF
      }

Posting my entire job specification for reference (this creates a Kafka cluster with three nodes):

job "kafka" {
  datacenters = ["dc1"]

  group "kafka" {
    count = 3

    network {
      port "kafka" {
        to = 9092
      }
      port "kafka-broker" {
        to = 9093
      }
    }

    ephemeral_disk {
      size    = 5000
    }

    service {
      name = "kafka"
      provider = "consul"
      address = "${attr.unique.network.ip-address}"
      port = "kafka"
    }

    service {
      name = "kafka-broker"
      provider = "consul"
      address = "${attr.unique.network.ip-address}"
      port = "kafka-broker"
    }

    task "kafka" {
      driver = "docker"

      config {
        image = "bitnami/kafka:latest"
        ports = ["kafka", "kafka-broker"]
      }

      env {
        KAFKA_CFG_ADVERTISED_LISTENERS = "PLAINTEXT://${attr.unique.network.ip-address}:${NOMAD_HOST_PORT_kafka}"
        KAFKA_CFG_CONTROLLER_QUORUM_VOTERS = "${KAFKA_CFG_CONTROLLER_QUORUM_VOTERS}"
        KAFKA_BROKER_ID = "${KAFKA_BROKER_ID}"
        BITNAMI_DEBUG = "yes"
        KAFKA_ENABLE_KRAFT = "yes"
        KAFKA_KRAFT_CLUSTER_ID = "NjZiYzNkYzViZjI2NDM1NT"
        KAFKA_CFG_PROCESS_ROLES = "broker,controller"
        KAFKA_CFG_CONTROLLER_LISTENER_NAMES = "CONTROLLER"
        KAFKA_CFG_LISTENERS = "PLAINTEXT://:9092,CONTROLLER://:9093"
        KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP = "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT"
        ALLOW_PLAINTEXT_LISTENER = "yes"
      }

      template {
        env = true
        destination = "docker_env"
        data = <<EOF
KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=
  {{- range $i, $e := service "kafka-broker" -}}
    {{- if eq $i 0 -}}
      {{$i}}@{{ .Address }}:{{ .Port }}
    {{- else -}}
      ,{{$i}}@{{ .Address }}:{{ .Port }}
    {{- end -}}
  {{- end}}

KAFKA_BROKER_ID={{- range $i, $e := service "kafka-broker" -}}
  {{- if and (eq .Address (env "attr.unique.network.ip-address")) (eq .Port (env "NOMAD_HOST_PORT_kafka_broker" | parseInt)) -}}
    {{$i}}
  {{- end -}}
{{- end}}
        EOF
      }
      resources {
        memory = 1024
        memory_max = 4096
      }
    }
  }
}

This is my first working version - improvement suggestions welcome.

3 Likes