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 / reconcileValidation 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) errorDefined 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 webThe 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
- Define the struct alongside other entries in
agent/structs/config_entry_<kind>.go. - Register in
agent/structs/config_entry.go(MakeConfigEntry, kind constant, etc.). - Implement
Normalize,Validate,CanRead,CanWrite. - Update
api/config_entry.gofor the public client. - Add HCL decode rules.
- Update
proto/private/pbconfigentry/and regenerate. - Update
agent/consul/state/config_entry.gofor any cross-kind indices. - Wire it into the discovery chain or proxy config manager if it should affect proxies.
- 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.