Kosli Capture is experimental. The configuration format may still change between releases. See the tutorial to get started.
config.yaml at the repo root. make validates and converts the file to config.json at build time, so a malformed file fails the deploy rather than shipping.
The file has three top-level sections — naming, scope, and types — plus eks_onboarding and a global include_scaling toggle.
naming
Controls how Kosli environment names are derived for each discovered resource.
Env-name precedence
Env names are resolved through a single precedence chain, used for whole resources and namespace slices alike:
Within the template,
{prefix} itself resolves in this order:
kosli:prefixtag on the resourcetypes.<type>.prefixnaming.prefixaws-{account_id}
{type} in the template — env names are unique per Kosli org, and a bucket could otherwise share a name with a cluster.
scope
Global filters applied to every type, combined with the per-type filters.
How filters combine with per-type blocks:
- include = global
∪per-type pairs; a resource must match all of them (empty = opt-out mode). - exclude = global
∪per-type pairs; matching any pair excludes the resource.
include_scaling
false — Kosli only snapshots on actual software change, not scaling.
types
Every type block accepts the same fields, plus a few type-specific ones. Shorthand <type>: true = enabled with no extra filters.
ecs
grouping for tag-based aggregation (see Grouping).
eks
namespaces for per-namespace scoping (see EKS namespaces).
lambda
Optional
grouping overrides both (see Grouping).
s3
s3 environment fingerprints bucket content (for deployment tracking), not a bucket inventory. types.s3.include_tags must be non-empty; otherwise Kosli Capture records a gap and skips S3.
Grouping (Lambda and ECS)
types.lambda.grouping and types.ecs.grouping map an exact env name to a set of tag pairs. Resources matching all pairs of an entry are reported together in one snapshot call — snapshot lambda --function-names a,b,c or snapshot ecs --clusters a,b,c — to that env.
- Grouping takes precedence — matched resources go to the named env.
- Unmatched resources fall through unchanged (Lambda’s
granularity, ECS’s per-cluster env). - If a resource matches more than one entry, the first entry wins.
- An entry with no tag pairs never matches anything.
EKS namespaces
By default each discovered EKS cluster gets one Kosli environment. Clusters listed undertypes.eks.namespaces (still subject to tag filters) are reported per namespace. "*" sets a default for every cluster; exact cluster names override it.
- List → derived env names (
{name}becomes<cluster>-<ns>). Entries may be regex patterns (kosli --namespacessupports them), which are sanitized for the derived name. - Map → explicit
namespace: env-namepairs. Preferred for regex patterns because the derived name would otherwise be sanitized. Explicit map entries are precedence level 1 — they beat every tag override.
{prefix}-eks-<cluster>-<ns>.
eks_onboarding
Self-onboarding is IAM-fenced with
eks:principalArn / eks:policyArn conditions so Kosli Capture can only grant that one policy to its own role. Clusters must have authentication mode API or API_AND_CONFIG_MAP.
Config sources at runtime
ConfigSource (CloudFormation parameter) decides where the Lambda reads its policy on each run:
All three deliver the same
config.json produced from config.yaml; the only difference is where it lands. make seed-config picks the right target from CONFIG_SOURCE and is a no-op for baked.
Runtime sources fail closed: if a config fetch fails, Kosli Capture reuses the last-known-good config (when the Lambda sandbox is warm) or fails the run. It does not fall back to the baked copy, so a stale policy can never re-include resources you have excluded.