feat: add !unset YAML function to delete keys from configuration @osterman (#1521)
## what - Add new `!unset` YAML function that completely removes keys from configuration during inheritance and merging - Implement processing in both stack merging (`yaml_func_utils.go`) and config loading (`process_yaml.go`) - Add comprehensive unit tests for all functionality - Create documentation with examples and use cases - Update YAML functions index documentationwhy
- Users need a way to explicitly remove inherited configuration values, not just override them with
null - Current workarounds require physically removing or commenting out keys in parent configurations
- This addresses GitHub issue #227: "A YAML way of undefining a value without removing the key"
- Provides fine-grained control over configuration inheritance in complex stack hierarchies
Key Features
- Complete removal: Unlike setting to
null,!unsetcompletely removes the key from configuration - Inheritance control: Child configurations can remove values inherited from parents
- Works everywhere: Functions in all Atmos configuration sections (vars, settings, env, metadata, etc.)
- Type-safe: Operates after YAML parsing, ensuring no syntax breakage
- Respects skip list: Can be disabled via skip list if needed
Examples
Basic Usage
# parent.yaml
components:
terraform:
vpc:
vars:
enable_nat_gateway: true
enable_vpn_gateway: true
# child.yaml
import:
- parent
components:
terraform:
vpc:
vars:
enable_vpn_gateway: !unset # Completely removes this keyRemoving Nested Values
config:
database:
host: "prod.db.example.com"
backup_enabled: true
# Override:
config:
database:
backup_enabled: !unset # Remove backup config
host: "dev.db.example.com"Testing
All tests pass:
- ✅ Unit tests for config processing
- ✅ Unit tests for stack processing
- ✅ Integration tests with other YAML functions
- ✅ Skip list functionality tests
- ✅ Inheritance scenario tests
references
🤖 Generated with Claude Code
Summary by CodeRabbit
- New Features
- Added a YAML !unset function to remove keys or list items during config processing and inheritance. Works at any depth, supports multiple unsets, and coexists with other YAML functions.
- Tests
- Introduced comprehensive tests covering flat and nested structures, arrays, multiple/nested unsets, inheritance scenarios, and edge cases.
- Documentation
- Added dedicated docs and examples for !unset, including usage in stack manifests, nested removals, list handling, and guidance on expected behavior.
feat(imports): cache remote stack-import clones (dedup + opt-in TTL) @osterman (#2571)
## what- Clone each remote (Git) stack-import source repository at most once per Atmos invocation instead of once per import — all subdir imports of the same repo now resolve from a single shared clone (within-run dedup, spanning both
describe affectedpasses). - Add an opt-in
ttlto reuse the cloned source across runs until it expires: per-import (ttl:in the import map form) and a globalimports.ttldefault inatmos.yaml. With nottl, the source refreshes once per run so mutable refs like?ref=mainstay fresh. - Wire the default git-subdir resolve path through the existing
ensureSourceDir, add per-session fetch tracking + TTL freshness (timestamp persisted in the.atmos-source-readymarker), and extract a sharedduration.IsExpired/IsZeroTTLthat the source provisioner now reuses. - Update JSON schemas, add unit tests, document "Caching Remote Imports" in
stacks/imports.mdx, add a changelog blog post, and add a roadmap milestone.
why
- For hub-and-spoke repos pulling a shared catalog via remote imports,
atmos describe affectedwas re-cloning the hub repo once per import (~68–87×/run, ~7–11 min total), and a warmactions/cacheof~/.cache/atmos/stack-imports/was ignored because the subdir path re-cloned unconditionally. - Within-run dedup collapses those clones to one per repo (the ~80% win, no staleness risk); the opt-in
ttllets CI reuse the clone across runs (warm cache skips the clone entirely) while keeping mutable refs fresh by default. Shallow clones (depth=1) were already in use — the win is not re-cloning the same repo repeatedly.
references
- Cached sources live under the XDG cache dir (
~/.cache/atmos/stack-imports/, honoringXDG_CACHE_HOME). - Builds on the source-provisioning TTL mechanism (
pkg/duration,pkg/provisioner/source). - Changelog:
website/blog/2026-06-05-faster-remote-stack-imports.mdx
Summary by CodeRabbit
-
New Features
- Per-import
ttland globalimports.ttlfor optional cross-run caching of remote stack imports. - Each unique remote Git source is cloned at most once per invocation and shared across nested imports.
- Improved cache freshness semantics, including explicit zero-ttl behavior.
- Per-import
-
Documentation
- Added caching guide, TTL examples, XDG cache guidance, and a blog post.
-
Tests
- Added tests for TTL parsing/expiration and remote import caching behavior.