Use go-sockaddr template to define IP address inside Consul configuration.

Play with go-sockaddr

Install the Go programming language.

$ sudo apt install golang-go

Install go-sockaddr.

$ go install github.com/hashicorp/go-sockaddr/cmd/sockaddr@latest
go: downloading github.com/hashicorp/go-sockaddr v1.0.2
go: downloading github.com/mitchellh/cli v1.0.0
go: downloading github.com/hashicorp/errwrap v1.0.0
go: downloading github.com/mitchellh/go-wordwrap v1.0.0
go: downloading github.com/ryanuber/columnize v2.1.0+incompatible
go: downloading github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310
go: downloading github.com/bgentry/speakeasy v0.1.0
go: downloading github.com/fatih/color v1.7.0
go: downloading github.com/mattn/go-isatty v0.0.3
go: downloading github.com/posener/complete v1.1.1
go: downloading github.com/mattn/go-colorable v0.0.9
go: downloading github.com/hashicorp/go-multierror v1.0.0

Extend PATH to include additional go binaries.

$ export PATH="${PATH}:~/go/bin"

Inspect evaluation information.

$ sockaddr eval 
Usage: sockaddr eval [options] [template ...]

  Parse the sockaddr template and evaluates the output.
  
  The `sockaddr` library has the potential to be very complex,
  which is why the `sockaddr` command supports an `eval`
  subcommand in order to test configurations from the command
  line.  The `eval` subcommand automatically wraps its input
  with the `{{` and `}}` template delimiters unless the `-r`
  command is specified, in which case `eval` parses the raw
  input.  If the `template` argument passed to `eval` is a
  dash (`-`), then `sockaddr eval` will read from stdin and
  automatically sets the `-r` flag.

Options:

  -d  Debug output
  -n  Suppress newlines between args
  -r  Suppress wrapping the input with {{ }} delimiters

Get all interfaces.

$ sockaddr eval -r "{{ GetAllInterfaces }}"
[127.0.0.1/8 {1 65536 lo  up|loopback} ::1 {1 65536 lo  up|loopback} 172.16.148.7/21 {2 1500 ens18 5e:f7:3a:6a:b3:4e up|broadcast|multicast} fe80::5cf7:3aff:fe6a:b34e/64 {2 1500 ens18 5e:f7:3a:6a:b3:4e up|broadcast|multicast}]

Get private interfaces.

$ sockaddr eval -r "{{ GetPrivateInterfaces }}"
[172.16.148.7/21 {2 1500 ens18 5e:f7:3a:6a:b3:4e up|broadcast|multicast}]

Get address for every private interfaces.

$ sockaddr eval -r "{{ GetPrivateInterfaces | attr \"address\" }}"
172.16.148.7

Get name for every private interfaces (see RFC 6890).

$ sockaddr eval -r "{{ GetPrivateInterfaces | attr \"name\" }}"
ens18

Get address for specific interface.

$ sockaddr eval -r "{{ GetInterfaceIP \"ens18\" }}"
172.16.148.7

Get interface attached to a default route.

$ sockaddr eval -r "{{ GetDefaultInterfaces }}"
[172.16.148.7/21 {2 1500 ens18 5e:f7:3a:6a:b3:4e up|broadcast|multicast} fe80::5cf7:3aff:fe6a:b34e/64 {2 1500 ens18 5e:f7:3a:6a:b3:4e up|broadcast|multicast}]

Get address for interface attached to a default route.

$ sockaddr eval -r "{{ GetDefaultInterfaces | attr \"address\" }}"
172.16.148.7

Use go-sockaddr template inside Consul configuration

Use go-sockaddr template inside Consul configuration to define IP address.

$ sudo -u consul tee /etc/consul.d/bind.hcl << EOF
# bind address
bind_addr =  "{{ GetInterfaceIP \"ens18\" }}"
EOF
# bind address
bind_addr =  "{{ GetInterfaceIP \"ens18\" }}"

Simple as that and it also works for other HashiCorp products.