I'm trying to get a simple index that I can append to output of a Go template snippet using consul-template. Looked around a bit and couldn't figure out the simple solution. Basically, given this input
backend web_back
balance roundrobin
{{range service "web-busybox" "passing"}}
server {{ .Name }} {{ .Address }}:80 check
{{ end }}
I would like to see web-busybox-n 10.1.1.1:80 check
Where n is the current index in the range loop. Is this possible with range and maps?
There is no iteration number when ranging over maps (only a value and an optional key). You can achieve what you want with custom functions.
One possible solution that uses an inc()
function to increment an index variable in each iteration:
func main() {
t := template.Must(template.New("").Funcs(template.FuncMap{
"inc": func(i int) int { return i + 1 },
}).Parse(src))
m := map[string]string{
"one": "first",
"two": "second",
"three": "third",
}
fmt.Println(t.Execute(os.Stdout, m))
}
const src = `{{$idx := 0}}
{{range $key, $value := .}}
index: {{$idx}} key: {{ $key }} value: {{ $value }}
{{$idx = (inc $idx)}}
{{end}}`
This outputs (try it on the Go Payground) (compacted output):
index: 0 key: one value: first
index: 1 key: three value: third
index: 2 key: two value: second
See similar / related questions:
Go template remove the last comma in range loop
The example below looks for all servers providing the pmm service, but will only create the command to register with the first pmm server one found (when $index == 0)
{{- range $index, $service := service "pmm" -}}
{{- if eq $index 0 -}}
sudo pmm-admin config --server {{ $service.Address }}
{{- end -}}
{{- end -}}