Consul is a tool for service discovery and configuration. It provides a way to discover services and manage configurations in a distributed system.

Vault is a service that help us to manage secrets and protect sensitive data. It provides a secure way to store and access secrets like API keys, passwords, certificates, etc.

Both are similar tools provided by HashiCorp Where we can access the services using the HTTP API.

Let’s see how we can connect to Consul and Vault using Golang.


  • Consul & Vault server running

docker compose file to run

    image: hashicorp/vault
    container_name: vault
      - 8200:8200 # Expose Vault's UI and API port
      - VAULT_DEV_ROOT_TOKEN_ID=myroot
      - IPC_LOCK # Required for Vault to lock memory
      - ./vault-data:/vault/file # Persist Vault data
    image: hashicorp/consul
    container_name: consul
      - 8500:8500 # Expose Consul's UI and API port

Create some values in Consul

docker exec -it consul_container consul kv put config/myapp '{"host": "http://localhost"}'

Create some secrets in Vault

docker exec -it -e VAULT_ADDR= -e VAULT_TOKEN=myroot vault_container vault kv put secret/myapp username=admin password=admin123

Connecting to Consul and Vault using Golang

We need to install the client package to connect to Consul and Vault.

go get
go get

Here is an example code to connect to Vault using Golang.

package main

import (

	consul ""
	vault ""

func vaultRead() {
	config := vault.DefaultConfig()

	config.Address = ""

	client, err := vault.NewClient(config)
	if err != nil {
		log.Fatalf("unable to initialize Vault client: %v", err)

	// Authenticate

	ctx := context.Background()

	// Read a secret
	secret, err := client.KVv2("secret").Get(ctx, "myapp")
	if err != nil {
		log.Fatalf("unable to read secret: %v", err)

	value, ok := secret.Data["username"].(string)
	if !ok {
		log.Fatalf("unable to read username: %v", err)

	log.Println("Username:", value)
    // Username: admin

type ConsulConfig struct {
	Host string `json:"host"`

func consulRead() {
    // Connect to Consul
	config := consul.DefaultConfig()

	config.Address = ""

    // Create a new client
	client, err := consul.NewClient(config)
	if err != nil {
		log.Fatalf("unable to initialize Vault client: %v", err)

    // Read a value
	pair, _, err := client.KV().Get("config/myapp", nil)
	if err != nil {
		log.Fatalf("unable to read secret: %v", err)

	log.Println("Host:", string(pair.Value))

	var consulConfig ConsulConfig
	if err := json.Unmarshal(pair.Value, &consulConfig); err != nil {
		log.Fatalf("unable to unmarshal Consul config: %v", err)

	log.Println("Host:", consulConfig.Host)
    // Host: http://localhost

func main() {

It’s pretty simple to connect to Consul and Vault using Golang. We can use the client packages provided by HashiCorp to connect to the services.

The http api by Consul and Vault is simple to use and we can easily connect to the services using Golang clients provided by HashiCorp.

That’s it. We have seen how to connect to Consul and Vault using Golang.