Inheritance of configurations
1) Why do I need configuration inheritance?
In mature products, the number of configuration parameters grows faster than the number of services. Inheritance allows:- Reuse common values (logging, retrays, timeouts).
- Share responsibility: the platform sets basic policies, service commands - only deviations.
- Avoid duplication and reduce the risk of misalignment.
- Speed up releases: Changes are broadcast down the tree by default.
- Support multi-environments and multi-tenancy with a single approach.
2) Inheritance patterns
2. 1 Hierarchical (parent → child)
Base (global) → environment (prod/stage/dev) → region/cluster → service → instance.
Simple and transparent, but can lead to deep chaining and complex debugging.
2. 2 Layered (base/overlays)
Base layer + overlay set (feature-x, region-eu, security-hardening).
Works well with GitOps and Kustomize; overlays are independent and compositional.
2. 3 Composite (modules/packages)
The configuration is assembled from modules: 'logging @ v2', 'metrics @ v1', 'http @ v3'.
Module versioning, semantic compatibility, explicit dependencies.
2. 4 Policy-as-Code
Basic "limiters" and invariants (OPA/Rego, Kyverno, Conftest).
The values themselves are not inherited, but the rules for their admissibility.
3) Merger algorithms and priorities
The key issue is the procedure for resolving conflicts. It is recommended to fix in the specification:1. Order of sources: from left to right (base ← env ← region ← service ← instance).
2. Rules for types:- Scalar: "last-write-wins."
- Object: recursive merge on keys.
- `append`/`prepend`
- 'uniqueBy (key) '(set by key)
- 'patch '(find item by'name' and partial merge).
- 3. Reserved keys (for example, '_ merge: replace '/' _ merge: deep' at the node level).
- Startup flags/ENV variables> runtime secrets> files on disk> default values in code.
Example of YAML merge
yaml base. yaml http:
port: 8080 timeouts:
read: 2s write: 2s features:
- name: audit enabled: false
prod. yaml http:
timeouts:
read: 1s features:
- name: audit enabled: true
- name: billing enabled: true
Result (under policy: object = deep merge, array = uniqueBy (name) + patch)
http:
port: 8080 timeouts:
read: 1s write: 2s features:
- name: audit enabled: true
- name: billing enabled: true
4) Schemes and validation
The presence of a schema is a prerequisite for safe inheritance.
JSON Schema/OpenAPI: types, required fields, enum, patterns, constraints ('minimum', 'format', 'patternProperties').
Schema versioning (semver): major - breaking, minor - new fields, patch - fixes.
Pre-merge and Post-merge checks: validate both fragments and the result.
Defaults: set at the schema level (draft-07 + supports' default ').
5) Environments and deployment matrix
Typical matrix:- env: dev, test, stage, prod region: eu-central-1, us-east-1 tier: batch, realtime, internal tenant: A/B/C (white-label, B2B)
- The combinations form the overlay tree; avoid excessive depth (3-4 levels are sufficient).
6) Multi-tenancy
Approaches:- Hard split: separate files/folders per tenant.
- Parameterization: one template + values per tenant.
- Inherited policies: resource/quota limits, SLO, log retention.
- Important: security boundaries (secrets/keys) should not flow between tenants.
7) Secrets and security
Don't inherit secrets explicitly. Inherited references: 'secretRef', 'vaultPath'.
KMS/Vault/SOPS: store encrypted values in Git, keys - out.
Share responsibility: the platform manages paths and policies, the service team - what you really need.
Policies: prohibit'plaintext 'secrets in CI checks.
Rotation: do not "overwrite down" - use alias/abstractions ('db/primary/password @ 2025-Q4').
Vault Link Example
yaml db:
host: postgres. service user: app passwordFrom:
vaultPath: "kv/prod/app-db"
key: "password" # secret is taken at the deploy stage, not stored in files
8) Versioning and migrations
Configuration module versions: 'logging @ 2. 3. 1`.
Changelog for schemas: migrations using jsonnet/ytt/custom scripts.
Up/down migrations for safe rollback.
Long branches: avoid drift; regularly skewer overlays to base.
9) Tools and practices
9. 1 Kubernetes
Kustomize (overlays): natural inheritance model through 'bases '/' resources', 'patchesStrategicMerge '/' patchesJSON6902'.
Helm (values): hierarchy'values. yaml '+' --set '(but be careful with overrides in CI).
Kyverno/OPA: Politicians as "safety nets."
Kustomize example:yaml overlays/prod/kustomization. yaml resources:
-../../base patchesStrategicMerge:
- patch-resources. yaml commonLabels:
env: prod
9. 2 Terraform
+ 'variables modules. tf 'as a contract.
'locals' for computed values, 'override'no files - use directory layers and workspaces ('workspaces').
Source order: defaults to <tfvars-files <'-var '/' -var-file'.
hcl module "svc" {
source = "./modules/svc"
replicas = var. env == "prod"? 4: 2 logging = local. logging_base
}
9. 3 Ansible
A clear hierarchy of variables (in ascending priority): role defaults <inventory group_vars <host_vars <extra vars.
For inheritance - the structure 'group _ vars/{ env }/{ region} .yml'.
9. 4 Jsonnet / ytt
Rich composition, functions and "key-intentions" ('overlay. replace`, `overlay. merge`).
10) Contracts and Battery Limits
Platform team-Defines the schema, policies, base values, and merge logic.
Product teams: only overlays within the contract.
SRE/Security: audit, validation, signatures, enforcement.
11) CI/CD и GitOps
Pipeline from stages:1. Lint (format, prohibition of unknown keys).
2. Validate (JSON Schema/OpenAPI).
3. Dry-run/Render (helm template/kustomize build).
4. Policy check (OPA/Kyverno/Conftest).
5. Diff versus target cluster (kubectl diff/ArgoCD diff).
6. Progressive delivery: canary overlays with limited traffic.
7. Signature of artifacts (Cosign, SLSA attestation).
12) Observability and debugging
Provenance trace: who contributed the field and when, from which layer the final value came.
Merge visualization: a report of the "winning" keys.
Runtime-export of the active configuration (endpoint '/config 'with secret masking).
Drift alerts: discrepancies between declared and actual.
13) Anti-patterns
"Magic" without explicit precedence rules.
Deep chains (> 4-5 layers): increase cognitive load.
Secrets in inherited files.
Hidden overrides via '--set' in CI.
Lack of schema and rendering tests.
14) Implementation checklist
- Define the model (hierarchy/layers/composition).
- Fix the merge order and strategies by type.
- Publish the schema and versioning.
- Share secrets (links/refs only).
- Add policy-checks and artifact signatures.
- Enable dry-run, diffuses, and origin visualization.
- Export the active configuration in runtime.
- Configure progressive releases for config changes.
15) FAQ
Q: How to understand that the layer is too deep?
A: If you need to open> 3 files and "scroll"> 2 levels of abstraction to change the parameter, revise the structure.
Q: What to do with conflicting arrays?
A: Enter explicit strategies: 'replace', 'append', 'uniqueBy (key)', 'patchBy (name)' - and fix them in the documentation.
Q: Can secrets be inherited?
A: No. Only links (URI/refs) to secret stores and access policies are inherited.
Q: How to test inheritance?
A: Shoot "slices" for key overlay combinations and check with golden files; race rendering in CI per PR.
Appendix A: Mini Speck Merge
`scalars`: last-write-wins
'objects': deep-merge by key
`arrays`:- default'replace'
- `append`
- `uniqueBy(key)`
- 'patchBy (key) 'with recursive element merge
- `_merge: replace|deep`
- `_strategy. array: replace|append|uniqueBy(name)|patchBy(name)`
Appendix B: Examples
B.1 Helm values (prod over base)
yaml values. base. yaml replicas: 2 resources:
requests:
cpu: "100m"
memory: "128Mi"
logging:
level: info
values. prod. yaml replicas: 4 logging:
level: warn
Rendering command:
helm template svc chart/ -f values. base. yaml -f values. prod. yaml
The priority of the last file is'values. prod. yaml`.
B.2 Kustomize overlays
yaml base/deployment. yaml apiVersion: apps/v1 kind: Deployment metadata:
name: app spec:
replicas: 2
overlays/prod/patch. yaml apiVersion: apps/v1 kind: Deployment metadata:
name: app spec:
replicas: 4
B.3 Ansible vars
group_vars/prod. yml # values of prod host_vars/prod-eu-1. yml # clarifications for extra vars host in CLI have highest priority
Summary
Configuration inheritance is a contract + merge algorithm + security policy, not just "many YAML files." Success is defined by:1. clear model and priorities,
2. validation schemes and independent overlays,
3. refusal to inherit secrets,
4. GitOps-pipeline with dry-run, policy-checks and diffuses,
5. observability of the origin of the final values.
By following these principles, you get predictable, scalable, and secure configurations for all environments and topologies.