feat(iaci): environment axis — env-scoped overlay orthogonal to profile (#60)#61
Merged
Conversation
Schema foundation for an env-scoped overlay orthogonal to `profile`:
- `defaults.environment` (default env name) + `environments:` map of named
overlays on `JetpackFileConfig`, paralleling `profiles:`.
- New `JetpackEnvironment { secrets_inventory }` — `Some(vec![])` clears,
`None` inherits, mirroring `JetpackProfile`.
- `EffectiveDefaults.environment` surfaced by `effective()`.
Parse-only this commit: selection (`--environment`) and the overlay-append
application land in the parser next. Three schema tests cover the default-env
field, the environments map, and the empty-vec-vs-absent distinction.
Co-Authored-By: Claude <noreply@anthropic.com>
The selection + application half of the environment axis, orthogonal to profile: - CLI: `--environment` / `-E` flag (fields `environment`/`active_environment`, mirroring `--profile`), surfaced in the verbose resolution summary. - Application: a selected environment APPENDS its `secrets_inventory` to the load list (loaded last → later-wins) on top of whatever profile/defaults selected. Precedence is CLI `--environment` > `defaults.environment`. It affects secrets only, so `--no-secrets` skips it entirely; an unknown environment is a clear error. Six tests cover: overlay-appended-last, `-E` alias, default-env, orthogonality with `--profile`, unknown-env error, and `--no-secrets` skip. Verified on the real binary: `-v` shows `sec/base` alone without `--environment`, and `sec/base, sec/envtest` + an `Environment | test` row with `-E test`. The overlay-merge (env var shadows base) relies on loading.rs's existing later-wins multi-path behavior; the templated-`play.groups` e2e from the issue depends on #52 (unmerged), so lands with that integration. Co-Authored-By: Claude <noreply@anthropic.com>
…60) Stitches the real layers the runtime chains — `load_inventory` → `resolve_target_groups` → `get_play_hosts` — with no mocks: an environment's `secrets_inventory` overlay (loaded last → later-wins) pins `target` in `group_vars/all`, where templated `play.groups` reads it, so one playbook fans out to the env-specific cluster. A causality test confirms the var genuinely comes from the overlay (Strict templating errors without it). This owns the previously- untested seam between the environment axis (#60) and templated groups (#52); the `--environment`→append step is covered by the parser's own tests. Co-Authored-By: Claude <noreply@anthropic.com>
This was referenced Jun 25, 2026
Zorlin
added a commit
that referenced
this pull request
Jun 26, 2026
style(playbooks): cargo fmt — unbreak main's Format check (#61)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements #60.
What
A native
environmentaxis, orthogonal toprofile:profile= location/site/context → selectsinventory+secrets_inventory(unchanged).environment= env-within (prod/test/staging) → layers an env-scoped secrets overlay on top of whatever the profile selected, selected independently.Selecting an env appends its overlay to the secrets load list (loaded last → later-wins), so an env can pin any per-env var without touching the site inventory.
--no-secretsskips it; an unknown env is a clear error.How (mirrors
--profileend-to-end)config_file.rs):defaults.environment+environments:map +JetpackEnvironment { secrets_inventory }(Some(vec![])clears,Noneinherits), surfaced inEffectiveDefaults.parser.rs):--environment/-E, fields + summary row.parser.rs): env overlay appended after profile resolution;--no-secretsskips it; unknown-env errors.Tests & verification
-Ealias, default-env, orthogonality with--profile, unknown-env error,--no-secretsskip, empty-vec-vs-absent). 389 total green;cargo clippyclean for the new code.-vshowssec/basealone without--environment;sec/base, sec/envtest+ anEnvironment | testrow with-E test.Deferred (with reasons)
loading.rs's existing later-wins multi-path behavior, which the appended-overlay test already exercises at the parser level.play.groupse2e from the issue (groups: ["{{ k3s_group_prefix }}-bootstrap"]): depends on Templateplay.groups— parameterize a playbook's target groups from vars #52 (unmerged) — lands with that integration.🤖 Generated with Claude Code