feat(iaci): {profile} placeholder in secrets_inventory paths (#65)#66
Merged
Conversation
A `secrets_inventory` path may now contain `{profile}`, substituted with
the active profile name at the contract-resolution step — so ONE
environment can layer `<site>-test` per selected profile:
profiles:
london: { inventory: [labs/london], secrets_inventory: [../infra-secrets/london] }
environments:
test:
secrets_inventory:
- ../infra-secrets/{profile}-test # → ../infra-secrets/london-test
Applies to both `environments.<n>.secrets_inventory` (the core ask) and
`profiles.<n>.secrets_inventory` (self-name substitution, for symmetry/DRY).
`defaults.secrets_inventory` is intentionally NOT supported — "the profile"
is ambiguous there.
Design decisions:
- Syntax `{profile}` (per the issue's primary suggestion), a contract-time
meta-token. Deliberately NOT `{{var}}` Templar syntax — only `{profile}`
is special, so contract paths can't be accidentally templated.
- `{profile}` with no profile selected is a clear error (the operator asked
for a per-profile overlay but named no profile), not a silent empty subst.
- Because `{`/`}` are YAML flow indicators, a `{profile}` path needs quoting
in flow style (`["../sec/{profile}-test"]`) or block style
(` - ../sec/{profile}-test`) — same rule as `{{var}}` everywhere else.
Tests: placeholder resolves to the active profile (and lands in the real
load list); placeholder-without-profile errors clearly; a profile's own
`{profile}` self-substitutes. The downstream load→later-wins→template
chain is already covered by the env-axis composition tests (#60) and
loading.rs regressions, so no redundant full-load e2e.
Co-Authored-By: Claude <noreply@anthropic.com>
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 #65.
What
secrets_inventorypaths may contain{profile}, substituted with the active profile name at contract-resolution — so onetestenvironment layers<site>-testper selected profile (london/nyc/seattle) instead of needing a per-site env.Applies to
environments.<n>.secrets_inventory(core) andprofiles.<n>.secrets_inventory(self-name, symmetry/DRY).defaults.secrets_inventoryis intentionally not supported (ambiguous which profile).Decisions
{profile}(issue's primary lean) — a contract-time meta-token, deliberately not{{var}}Templar syntax, so only{profile}is special and contract paths can't be accidentally templated.{profile}→ clear error (not silent empty substitution).{/}are flow indicators, so quote in flow style (["../sec/{profile}-test"]) or use block style — same rule as{{var}}everywhere else.Tests (3 new, all green; 431 total pass, 0 fail, no new warnings)
environment_secrets_profile_placeholder_resolves_to_active_profile— resolves and lands in the real load list.environment_secrets_profile_placeholder_without_profile_errors— clear error naming the placeholder + cause.profile_secrets_profile_placeholder_self_substitutes— a profile's own{profile}→ its name.The downstream load → later-wins → template chain is already covered by the #60 env-axis composition tests + loading.rs regressions, so no redundant full-load e2e.
🤖 Generated with Claude Code