Open-Source Wikis

/

Consul

/

Features

/

Config entries

hashicorp/consul

Config entries

Config entries are cluster-wide pieces of configuration written to the Raft log. They sit between "agent config" (per-node, in HCL files) and "service registrations" (per-instance). Anything that affects routing, mesh policy, gateways, or rate limits ships as a config entry.

Pieces

Piece Where
Struct definitions agent/structs/config_entry*.go (~30 files)
Discovery chain compiler agent/consul/discoverychain/
RPC endpoint agent/consul/config_endpoint.go
HTTP endpoint agent/config_endpoint.go
State store agent/consul/state/config_entry.go (70 KB)
Streaming events agent/consul/state/config_entry_events.go
Generated wire format proto/private/pbconfigentry/config_entry.pb.go (349 KB; the largest file)
Public Go client api/config_entry*.go
CLI command/config/

Catalog of kinds

Each kind is declared in agent/structs/config_entry.go and registered in the MakeConfigEntry switch. A non-exhaustive map:

Kind Purpose Defining file
service-defaults Per-service defaults: protocol, mesh gateway mode, expose paths, locality, envoy extensions agent/structs/config_entry.go (struct alongside others)
proxy-defaults Cluster-wide proxy settings (the global instance) agent/structs/config_entry.go
service-router L7 HTTP routing for a destination agent/structs/config_entry_routes.go
service-resolver Subset selection, failover, redirects agent/structs/config_entry_discoverychain.go
service-splitter Weighted traffic splitting (canary) agent/structs/config_entry_discoverychain.go
service-intentions Mesh authorization rules agent/structs/config_entry_intentions.go
mesh Cluster-wide mesh settings agent/structs/config_entry_mesh.go
exported-services Which services are visible across peers/partitions agent/structs/config_entry_exports.go
sameness-group Define a sameness group for cross-cluster failover agent/structs/config_entry_sameness_group.go
ingress-gateway Ingress gateway listener config agent/structs/config_entry_gateways.go
terminating-gateway Terminating gateway service list agent/structs/config_entry_gateways.go
api-gateway API gateway listener + protocol agent/structs/config_entry_gateways.go
bound-api-gateway The reconciled state of an api-gateway (controller-managed) agent/structs/config_entry_gateways.go
http-route HTTP routing rules attached to api-gateway listeners agent/structs/config_entry_routes.go
tcp-route TCP routing rules attached to api-gateway listeners agent/structs/config_entry_routes.go
inline-certificate Inline TLS material referenced by api-gateway agent/structs/config_entry_inline_certificate.go
file-system-certificate File-system TLS material referenced by api-gateway agent/structs/config_entry_file_system_certificate.go
jwt-provider JWT provider used by intentions / api-gateway agent/structs/config_entry_jwt_provider.go
control-plane-request-limit Cluster-wide RPC rate limit agent/structs/config_entry_global_rate_limit.go, agent/structs/config_entry_rate_limit_ip.go
partition-exports (Enterprise) Partition-specific export rules agent/structs/config_entry_exports.go

The full enum sits in agent/structs/config_entry.go::ConfigEntryKind* constants.

Lifecycle

sequenceDiagram
    participant Op as Operator
    participant HTTP as agent/config_endpoint.go
    participant Server as agent/consul/config_endpoint.go
    participant FSM as fsm.commands_ce.go
    participant State as state/config_entry.go
    participant Events as config_entry_events.go
    participant Subscribers as proxycfg, gateways controller, ...

    Op->>HTTP: PUT /v1/config (HCL or JSON)
    HTTP->>HTTP: decode, identify Kind
    HTTP->>Server: ConfigEntry.Apply
    Server->>Server: Validate + Authorize + raise raftApply
    Server->>FSM: raftApply(ConfigEntryRequestType, entry)
    FSM->>State: EnsureConfigEntry(...)
    State->>Events: publish ConfigEntryUpsertEvent
    Events-->>Subscribers: streaming subscribe
    Subscribers-->>Subscribers: rebuild snapshots / reconcile

Validation and normalization

Each kind implements:

func (e *Entry) Normalize() error  // fill defaults
func (e *Entry) Validate() error    // enforce invariants
func (e *Entry) CanRead(authz acl.Authorizer) error
func (e *Entry) CanWrite(authz acl.Authorizer) error

Defined alongside the struct. The shared dispatcher in agent/structs/config_entry.go calls these polymorphically. Specific kinds also have helpers like GetEnterpriseMeta, GetRaftIndex, DeepCopy (generated).

Discovery chain compilation

Routes + resolvers + splitters compose into a per-service discovery chain:

service-router(web) ─┬─→ service-splitter(web)─┬─ 50% v1
                     │                          └─ 50% v2
                     └─ /admin → service-resolver(admin)→ admin DC2 (failover)

The compiler in agent/consul/discoverychain/compile.go walks the entries and produces a CompiledDiscoveryChain (in agent/structs/config_entry_discoverychain.go). Compilation is recomputed on any config-entry change that touches the chain.

Storage shape

Config entries live in a single MemDB table keyed by (Kind, Name, Partition, Namespace). The schema and indices are defined in agent/consul/state/config_entry_schema.go. Per-kind helpers exist for cross-kind queries (e.g., "all routers that target service X").

Streaming and propagation

config_entry_events.go publishes events on insert/update/delete. The proxy config manager and the gateways controller subscribe so changes flow to xDS within seconds.

Operator workflow

# Apply
consul config write router.hcl

# Read
consul config read -kind service-router -name web

# List
consul config list -kind service-router

# Delete
consul config delete -kind service-router -name web

The HCL ↔ struct decode lives in agent/structs/config_entry.go::DecodeConfigEntry.

Generated wire format

Config entries also exist as protobuf for the V2 storage and gRPC paths. The auto-generated proto/private/pbconfigentry/ is huge (349 KB just for the message types). The corresponding .gen.go translator (agent/structs/-side) is generated by mog. Operators rarely touch the proto files directly.

Adding a new config-entry kind

  1. Define the struct alongside other entries in agent/structs/config_entry_<kind>.go.
  2. Register in agent/structs/config_entry.go (MakeConfigEntry, kind constant, etc.).
  3. Implement Normalize, Validate, CanRead, CanWrite.
  4. Update api/config_entry.go for the public client.
  5. Add HCL decode rules.
  6. Update proto/private/pbconfigentry/ and regenerate.
  7. Update agent/consul/state/config_entry.go for any cross-kind indices.
  8. Wire it into the discovery chain or proxy config manager if it should affect proxies.
  9. Tests in agent/structs/config_entry_<kind>_test.go.

The full checklist: docs/contributing/checklist-adding-config-entry.md.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Config entries – Consul wiki | Factory