Consul’s default proxy behavior isn’t what you’d expect; it’s not about setting a global proxy.config but about configuring the upstream proxy settings for each service.

Let’s see consul connect proxy in action. Imagine you have a service web that needs to talk to a user-db service. Normally, web would directly connect to user-db’s registered address. But with Consul Connect, web makes a proxy-to-proxy connection: web’s sidecar proxy connects to user-db’s sidecar proxy.

Here’s how you’d typically define the upstream proxy settings for web in its service definition:

{
  "service": {
    "name": "web",
    "port": 8080,
    "connect": {
      "sidecar_service": {
        "proxy": {
          "upstreams": [
            {
              "destination_name": "user-db",
              "destination_type": "service",
              "local_bind_port": 15432
            }
          ]
        }
      }
    }
  }
}

In this setup, when the web service wants to talk to user-db, it sends its traffic to localhost:15432. The web sidecar proxy intercepts this, looks up the user-db service in Consul, establishes a secure connection to the user-db sidecar proxy, and forwards the traffic. The user-db sidecar proxy then forwards it to the actual user-db instance.

The "global default" you’re looking for isn’t a single config file. Instead, Consul provides a way to set default proxy configuration for all sidecars registered with a specific Consul agent. This is done via the consul agent command-line flags or within the agent’s configuration file.

Specifically, you can use the --config-file option when starting your Consul agent to point to a configuration file that sets these defaults.

Here’s an example consul.json file for an agent:

{
  "acl_defaults": {
    "default_policy": "deny"
  },
  "ports": {
    "dns": 8600,
    "http": 8500,
    "rpc": 8400,
    "serf_lan": 8301,
    "serf_wan": 8302,
    "server": 8300,
    "client": 8300
  },
  "retry_join": [
    "provider=aws tag_key=Consul tag_value=Prod region=us-east-1"
  ],
  "service_config": {
    "proxy": {
      "config": {
        "bind_addr": "127.0.0.1",
        "bind_port": 8081,
        "upstreams": [
          {
            "destination_name": "default-upstream-service",
            "destination_type": "service",
            "local_bind_port": 9090
          }
        ]
      }
    }
  }
}

When you start the Consul agent with this configuration, any service that registers with this agent and doesn’t explicitly define its own proxy.upstreams in its service definition will inherit these defaults.

Let’s break down the service_config.proxy.config section:

  • bind_addr: The IP address the sidecar proxy will bind to for incoming connections from the service. 127.0.0.1 is common.
  • bind_port: The port the sidecar proxy will listen on for incoming connections from the service. This is what your application will connect to. 8081 in this example.
  • upstreams: This is where you define default upstream connections.
    • destination_name: The name of the service you want to connect to by default.
    • destination_type: Usually "service".
    • local_bind_port: The port your application will connect to in order to reach this default upstream. 9090 in this example.

So, if your web service definition didn’t have an upstreams block, and it tried to connect to user-db, it would first connect to localhost:8081. The sidecar proxy would then look for a default upstream. If user-db matched default-upstream-service (or if there was a more general rule), it would proceed. However, the more common use of these agent-level defaults is to set global proxy settings rather than specific upstreams.

For instance, you might want to set a default config.bind_addr and config.bind_port for all sidecars on that agent.

{
  "service_config": {
    "proxy": {
      "config": {
        "bind_addr": "127.0.0.1",
        "bind_port": 8081
      }
    }
  }
}

This means that by default, the sidecar proxy for any service registered with this agent will listen on localhost:8081 for traffic from its application. If the service definition doesn’t specify a proxy.sidecar_service.proxy.bind_port, it will use 8081.

The truly counterintuitive part is that these service_config settings on the agent don’t globally define upstreams for all services. They only act as defaults for services registered with that specific agent if those services don’t have their own explicit connect.sidecar_service.proxy.upstreams defined. Consul prioritizes service-specific configurations over agent-level defaults. Therefore, you’re still defining upstream connections at the service level, but the agent config provides a fallback or a way to set common proxy listener ports.

The next step you’ll likely encounter is configuring TLS encryption between your services using Consul Connect, which involves setting up CA certificates and configuring the proxies to use them.

Want structured learning?

Take the full Consul course →