go-hiera documentation¶
A pure-Go (CGO-free) reimplementation of Puppet's Hiera 5 hierarchical data-lookup engine.
go-hiera/hiera loads a Hiera 5 configuration (hiera.yaml), walks the
configured hierarchy of data sources, and resolves a key to a typed value —
honouring Hiera's merge behaviours (first / unique / hash / deep),
per-key lookup_options, dotted-key digging into structured data, and the full
%{...} interpolation grammar, with interpolation-loop detection. The module
path is github.com/go-hiera/hiera.
The engine is standalone and reusable: it has no hard dependency on any
particular fact source. The caller injects a Scope (a variable
provider), so a facts engine such as go-facter,
or the Ruby binding go-ruby-hiera that maps
Ruby's Hiera API and Puppet's lookup() onto it, plugs its own facts in.
Status: v0.1 shipped — faithful to Hiera 5
hiera.yaml v5 loader; yaml_data (via the pure-Go
go-ruby-yaml Psych backend) and
json_data backends; the four merge behaviours with knockout_prefix /
merge_hash_arrays / sort_merged_arrays; per-key and ^regex
lookup_options; dotted-key dig; and the complete %{...} grammar
(scope / lookup / hiera / alias / literal) with loop detection.
100% test coverage including every error branch, gofmt + go vet
clean, green across the six 64-bit Go targets (amd64, arm64, riscv64,
loong64, ppc64le, s390x).
What it is — and isn't¶
Resolving a hierarchy of YAML/JSON data with merge and interpolation is fully
deterministic and needs no Ruby interpreter, so it lives here as pure Go.
The Ruby-facing Hiera / lookup() surface and Puppet's automatic-data-binding
wiring stay in the consumer (go-ruby-hiera /
rbgo).
This library resolves data; the host presents the Ruby API.
The engine also does not resolve fact/variable references itself. %{facts.os.name},
%{trusted.certname} and %{scope('x')} are resolved against the injected
Scope — the seam a facts source plugs into.
Install¶
Quick taste¶
package main
import (
"fmt"
"log"
"github.com/go-hiera/hiera"
)
func main() {
// The caller supplies the variable/fact scope %{...} resolves against.
scope := hiera.MapScope{
"facts": map[string]any{"os": map[string]any{"family": "Debian"}},
"trusted": map[string]any{"certname": "web01.example.com"},
}
h, err := hiera.Load("hiera.yaml", scope)
if err != nil {
log.Fatal(err)
}
// First-found lookup.
v, found, err := h.Lookup("ntp::servers", nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(v, found)
// Force a merge strategy for this call.
deep := &hiera.MergeStrategy{Kind: hiera.MergeDeep, KnockoutPrefix: "--"}
merged, _, _ := h.Lookup("profile::settings", &hiera.Options{Merge: deep})
fmt.Println(merged)
// Dotted key: dig into structured data after the merge.
port, _, _ := h.Lookup("profile.ntp.port", nil)
fmt.Println(port)
}
Value model¶
Data files decode to a small, fixed set of Go types, so a host can map results onto its own object graph:
| Hiera / YAML | Go |
|---|---|
| Hash | map[string]any |
| Array | []any |
| String | string |
| Integer | int64 |
| Float | float64 |
| Boolean | bool |
| Null | nil |
YAML is decoded through go-ruby-yaml (the ecosystem's Ruby-faithful, pure-Go Psych backend, matching the YAML semantics Puppet relies on); JSON through the standard library.
Repositories¶
| Repo | What it is |
|---|---|
hiera |
the engine — hiera.yaml loader, backends, merge, interpolation, the Load / New / Lookup API |
docs |
this documentation site (MkDocs Material, versioned with mike) |
go-hiera.github.io |
the organization landing page (Hugo) |
brand |
logo and brand assets |
Principles¶
- Pure Go,
CGO_ENABLED=0— trivial cross-compilation, a single static binary, no C toolchain. - Faithful to Hiera 5. Merge,
lookup_options, interpolation and dig match Hiera's documented semantics so the engine can back Puppet'slookup(). - Standalone & reusable. No hard dependency on any fact source; the caller
injects a
Scope. - 100% test coverage is the target, enforced as a CI gate.
Where to go next¶
- Configuration — the
hiera.yamlv5 schema:version,defaults, and thehierarchylevels. - Backends —
yaml_data,json_data, andRegisterDataHash. - Merge behaviours —
first/unique/hash/deepandlookup_options. - Interpolation — the
%{...}grammar and its functions. - Dotted-key dig — digging into structured data after merge.
- Go API —
Load,New,Lookup,Options,MergeStrategy. - The Scope seam — how go-facter and go-ruby-hiera feed facts in.
- Roadmap — what is done and what is next.
Source lives at github.com/go-hiera/hiera.