Add Validation, Scaffolding, and Emulators cards to landing grid @osterman (#2974)
what
- Add three feature cards to the homepage "Batteries included" grid: Validation, Scaffolding, and Emulators.
- Each card follows the existing schema (icon, title, description, tag line, doc link) and slots next to its closest existing sibling card (Validation next to Vendoring, Scaffolding next to Toolchain, Emulators next to Workflows & Automation) so the grid still fills to full rows of 4.
- Link targets (
/validation/validating,/cli/commands/scaffold/usage,/cli/commands/emulator/usage) were verified against how other docs pages already link to these same destinations internally, not guessed.
why
- These three capabilities already ship in Atmos and have full docs, but weren't represented anywhere on the landing page, understating what the runtime includes out of the box.
- Kept to three additions (not four) so the grid still lands on a clean multiple of 4 cards per row instead of leaving a new single orphaned card in the last row.
references
- N/A
Summary by CodeRabbit
- New Features
- Added Validation, Scaffolding, and Emulators to the landing page’s battery features.
- Updated workflow messaging to highlight 35+ step types and revised emulator wording.
- Bug Fixes
- Improved retries for transient Sigstore trust-root CDN errors while excluding unrelated certificate-fetch failures.
- Documentation
- Explained how custom commands and workflows can work together as a task runner replacement.
- Clarified custom command configuration, optional usage, wrapped commands, and examples.
- Updated the custom commands link to point to the expanded documentation.
fix(container): resolve build/mount paths via base_path, add JIT source support @osterman (#2979)
what
- Container components (
components.container) now resolvebuild.context,build.dockerfile, andrun.mounts[].sourcethe same way Terraform/Helmfile/Kubernetes/Helm components resolve theirs: relative tocomponents.container.base_pathjoined with the component's own name, via a new precomputedContainerDirAbsolutePathand a"container"case in the shared component-path resolver. components.container.base_pathis promoted from an ad hoc, silently-ignored config value into a real, typedComponents.Container.BasePathfield.- Container components gain the same just-in-time
source:provisioning as Terraform/Helmfile/Kubernetes/Helm — a component declaring a source is auto-vendored into a workdir, which then anchors build/mount paths instead of the static base path. - Removed the now-redundant bespoke
container.Config/DefaultConfig()/parseConfig(), and fixed a hardcoded"components/container"literal indescribe_stacks.gothat ignored any configured override. - Regenerated the
atmos.yamlJSON schema, updated the container CLI docs and theatmos-containeragent skill, and added a changelog post + roadmap milestone.
why
build.context/build.dockerfilewere passed todocker build/podman buildcompletely unanchored, so they silently resolved against whatever directoryatmoshappened to be invoked from instead of the project — working by accident only when run from the repo root.run.mounts[].sourceanchored to the bare project root rather than the component itself, andcomponents.container.base_pathhad no effect anywhere despite being accepted as valid config.- Every other component type already has a consistent, CWD-independent path-resolution mechanism (
base_path+component:/metadata.component) plus JIT source provisioning; containers were the one component kind never wired into it.
references
- N/A
Summary by CodeRabbit
-
New Features
- Added configurable container component base paths, defaulting to
components/container. - Relative build contexts and mount sources now resolve from the component directory; Dockerfiles resolve from the build context.
- Added automatic provisioning for container components using
source:when needed.
- Added configurable container component base paths, defaulting to
-
Documentation
- Added guidance on path resolution, configuration, migration, and source provisioning.
- Updated the product roadmap to reflect the shipped functionality.
fix(ci): scope test-required aliases to their own OS's shard results @osterman (#2976)
what
test-required (the legacy compatibility shim that aliases the sharded test matrix under the three historical required-check names) checked needs.test.result, which is a single aggregated verdict across the entire test matrix (3 OSes × 10 shards). A failure in any one shard on any one OS flipped that aggregate to failure, so all three aliases (Acceptance Tests (linux/macos/windows)) failed together even when only one OS actually had a failing shard.
This PR rewrites test-required to query the run's actual per-job results via gh api .../actions/runs/.../jobs, filtered by OS, so each alias only fails when a shard belonging to its own OS failed. It also stops gating the macos alias on terraform-registry-cache (whose matrix only has linux/windows legs and has no macos job to report on), which had the same cross-OS aggregation bug.
why
Observed on #2972: windows shard 2/10 failed after 57s, and Acceptance Tests (linux), (macos), and (windows) all failed within 3-4s as sympathetic failures with no real linux/macos test failures, forcing unnecessary re-runs/investigation of unaffected OSes.
references
- Observed on #2972
perf(lint): move golangci-lint cache/tmp out of worktrees @osterman (#2988)
what
- Relocate the default golangci-lint cache and tmp directories from inside each worktree (
.golangci-cache/,.golangci-tmp/) to the OS user cache directory:<user-cache>/atmos-lint/<worktree-hash>/{cache,tmp}(~/Library/Caches/atmos-lint/...on macOS). - The
<worktree-hash>(first 12 hex chars of SHA-256 of the absolute worktree path) preserves #2701's per-worktree isolation of golangci-lint's single-instance lock — the dirs just no longer live under the worktree tree. ATMOS_LINT_SHARED_CACHE=1opt-out and explicitGOLANGCI_LINT_CACHEoverrides behave exactly as before.- Tests updated/added: new-location assertions, hash determinism + cross-worktree non-collision, user-cache-dir failure propagation.
- Adds
docs/fixes/2026-08-24-fsmonitor-worktree-saturation.mdwith the full measured diagnosis.
why
#2701 put a 156MB / ~37k-file cache that churns on every lint run inside each worktree — directly under any filesystem watcher observing that tree (git fsmonitor, Conductor's watchexec). At multi-worktree scale this saturated macOS FSEvents: git status measured 2.9s–timeout (>2min) with fsmonitor vs 0.04–0.15s without, and every pre-commit run pays that tax dozens of times, stretching commits to minutes. Moving the churn outside the watched tree makes this impossible to re-trigger on any machine, regardless of watcher configuration.
Measured after the fix: cold lint:precommit 9.1s, warm 1.5s, no cache dirs created in the worktree; a full commit through all pre-commit hooks + signing completes in ~5s.
references
- #2701 (
perf(lint): isolate golangci-lint cache and lock per worktree) — introduced the in-worktree location this PR relocates; its lock-isolation intent is preserved docs/fixes/2026-08-24-fsmonitor-worktree-saturation.md— full diagnosis, timeline, and machine-level remediation notes
Summary by CodeRabbit
-
Bug Fixes
- Improved linting in Git worktrees by storing cache and temporary files in isolated user-cache locations.
- Reduced unnecessary file-monitor activity caused by lint-related file churn.
- Preserved support for shared caches and explicitly configured cache locations.
- Improved error handling when cache locations cannot be resolved or created.
- Added safeguards to keep cache data separated between worktrees.
-
Documentation
- Added troubleshooting guidance for worktree file-monitor saturation and remediation steps.
fix(devcontainer): disable moby so docker feature installs on Debian trixie @aknysh (#2975)
what
- Set
"moby": falseon thedocker-outside-of-dockerdevcontainer feature in.devcontainer/devcontainer.json.
why
The Codespaces Prebuilds workflow (prebuild) fails on every push to main. Example failed run: https://github.com/cloudposse/atmos/actions/runs/32431458655/job/96623702606
The base image mcr.microsoft.com/vscode/devcontainers/base:debian now resolves to Debian 13 (trixie), which does not package moby-cli. The docker-outside-of-docker feature defaults to moby: true and errors out during the prebuild image build:
(!) The 'moby' option is not supported on debian 'trixie' because 'moby-cli'
and related system packages are not available in that distribution.
(!) To continue, either set the feature option '"moby": false' or use a
different base image (for example: 'debian:bookworm' or 'ubuntu-24.04').
ERROR: Feature "Docker (docker-outside-of-docker)" failed to install!
Setting moby: false makes the feature install Docker CE instead. This is safe and non-redundant: the devcontainer Dockerfile already configures Docker's official apt repo and installs docker-ce/docker-ce-cli, so no moby packages were ever needed — the feature only wires up the forwarded host Docker socket.
references
- Failed run: https://github.com/cloudposse/atmos/actions/runs/32431458655/job/96623702606
- Feature docs: https://github.com/devcontainers/features/tree/main/src/docker-outside-of-docker
Summary by CodeRabbit
- Chores
- Updated the development container configuration to install Docker CE instead of Moby on Debian 13.
fix(ci): bump docker-build-push to v3.2.1 to fix release job summary crash @aknysh (#2973)
what
- Bump the
Docker Buildstep in.github/workflows/build.ymlfromcloudposse/github-action-docker-build-pushv3.1.0 (02993d67) to v3.2.1 (ff59bd5).
why
- The
release / Build and push Docker image for Atmos CLIjob has been failing on the post-build Docker Inspect summary step withjq: error (at inspect.json:79): Cannot iterate over null (null)→ exit code 5, even though the image builds and pushes fine. - Root cause was in the action itself: its summary step fed
docker inspectfields (.Config.Entrypoint,.Config.Cmd,.Config.Env,.RootFS.Layers) straight into jq'sjoin/.[]/to_entries, all of which iterate. Atmos's image isFROM debian:trixie-slimwith noENTRYPOINT, so.Config.Entrypointisnulland jq aborts; under the defaultbash -eshell that fails the whole step. - Fixed upstream in cloudposse/github-action-docker-build-push#111 (guards each iterating expression with
// []), released as v3.2.1. Verifiedff59bd5contains all four guards. This bump pins Atmos to that release so the release job's summary no longer crashes.
references
- Failing run: https://github.com/cloudposse/atmos/actions/runs/32415649296/job/96577335200
- Upstream fix: cloudposse/github-action-docker-build-push#111
- Release: https://github.com/cloudposse/github-action-docker-build-push/releases/tag/v3.2.1
Summary by CodeRabbit
- Chores
- Updated the Docker build workflow to use a newer action version, improving build pipeline maintenance and reliability.
🚀 Enhancements
fix: restore public API wrappers used by terraform-provider-utils @aknysh (#2996)
what
- Restore two public functions that external consumers of the Atmos Go library depend on:
pkg/aws.ExecuteAwsEksUpdateKubeconfig— thin public wrapper delegating tointernal/exec.ExecuteAwsEksUpdateKubeconfig.pkg/utils.JSONToMapOfInterfaces— decodes a JSON string into aschema.AtmosSectionMapType(errors on non-object top-level values, unlikeConvertFromJSON).
- Add tests covering both restored functions (which also keep them out of the
deadcode -testset). - Add a fix doc under
docs/fixes/.
why
- PR #2608 (
refactor(utils): drop dead helpers ...) removed both functions because thedeadcodesweep reported zero callers inside the Atmos repo. That analysis does not see external module consumers, so these were public-API removals, not truly dead code. cloudposse/terraform-provider-utilsembeds the Atmos Go library and relies on both:- its
utils_aws_eks_update_kubeconfigdata source callspkg/aws.ExecuteAwsEksUpdateKubeconfig; - its test suite calls
pkg/utils.JSONToMapOfInterfaces.
- its
- As a result, the provider fails to build against Atmos v1.222.0+ (the kubeconfig executor moved into
internal/exec, which external modules cannot import;JSONToMapOfInterfaceswas deleted). This pins the provider to v1.221.1 and prevents it from tracking newer Atmos releases — which matters because the provider must embed the same deep-merge semantics as the paired Atmos CLI. - Restoring these thin wrappers unblocks the provider upgrade with no behavior change. Verified by building
terraform-provider-utilsagainst this branch (localreplace+atmos@v1.226.1):go build ./...,go vet ./internal/..., and its full unit/library test suite all pass.deadcode -test ./...no longer reports either function.
references
- Regression introduced by #2608
- Downstream consumer: https://github.com/cloudposse/terraform-provider-utils (
utils_aws_eks_update_kubeconfigdata source,internal/converttests) - See
docs/fixes/2026-08-25-restore-public-provider-api-wrappers.md
Summary by CodeRabbit
-
New Features
- Restored public support for generating Amazon EKS kubeconfig files.
- Added a public utility for converting JSON objects into map values.
-
Bug Fixes
- EKS kubeconfig generation now reports conflicts between profile and role settings.
- JSON conversion now rejects malformed, empty,
null, and other non-object input.
-
Documentation
- Documented public API usage, validation behavior, and safeguards against accidental removal.
fix: bare --help shows everything when no atmos.yaml is found @osterman (#2995)
what
- Fixes
defaultCliConfig(the config used when noatmos.yamlis discoverable) to statesettings.terminal.help.filter: true, matching the journaled/SetDefaultvalue. - Fixes a blind spot in
TestJournalAgreesWithDefaultCliConfigthat treated "field absent from the struct" and "field explicitly serialized asfalse" as equivalent, letting this exact class of drift through silently. - Adds
TestLoadConfigNoAtmosYamlDefaults, a regression test that loads config from a directory with noatmos.yamlanywhere — the one fallback path every existing edition/help test skips.
why
- Bare
--helpwas regressing to the full--help=alloutput (all flags, no focused view, no--help=usage/--help=allhint) whenever noatmos.yamlwas discoverable — e.g. runningatmos --helpright after install or from outside a project directory. - Root cause:
defaultCliConfig'sTerminalliteral never setHelp, so it zero-valued toHelpSettings{Filter: false}. Since the field has noomitemptytag, that explicitfalsewas marshaled into Viper's CONFIG layer and silently overrode the intendedtruefromSetDefault, which only reaches the lower-priority DEFAULT layer. Introduced in #2762, which added the journal entry but missed the matchingdefaultCliConfigentry. - Verified the fix and both new/adjusted tests by reverting the fix locally and confirming they fail without it, then pass with it restored; also confirmed at the CLI level that
atmos --help(no config file) now differs from--help=alland shows the expected hint.
references
- Introduced by #2762 ("feat: add date-anchored default editions")
Summary by CodeRabbit
-
New Features
- Focused CLI help output is now enabled by default, making help information more concise and relevant.
-
Bug Fixes
- Default help behavior is applied consistently even when no
atmos.yamlconfiguration file is available.
- Default help behavior is applied consistently even when no
-
Tests
- Improved configuration validation to correctly recognize explicitly set values, including
false, empty strings, and0. - Updated timing checks to better accommodate scheduling delays across environments, including Windows CI.
- Improved configuration validation to correctly recognize explicitly set values, including
fix(workdir): stop mangling hyphens in .workdir directory names @osterman (#2985)
what
- Replace
pkg/provisioner/workdir's injective character-escaping scheme (-->-h,/->-s,\->-b) with a<stack>-<sanitized-name>-<hash>naming scheme for.workdir/<type>/...directories. - Add migration for both previously-shipped legacy naming formulas so existing on-disk workdirs get renamed forward instead of orphaned.
- Add a fail-closed identity check when reusing an existing hash-suffixed workdir, guarding against the (astronomically unlikely) hash-collision case.
- Update call sites and tests across
pkg/provisioner/workdir,pkg/provisioner/source,pkg/component,internal/terraform_backend,pkg/terraform/output, andtests/that asserted on the old escaped naming.
why
- Component/version names containing hyphens (e.g.
vpc-flow-logs-1.226.1) were mangled into unreadable directory names likevpc-hflow-hlogs-h1.226.1, since-was both the most common character in real component names and the encoding's own escape marker. - A hash-suffixed prefix keeps directory names human-readable for the common case while still guaranteeing collision-free uniqueness, without relying on a hand-rolled, hard-to-verify injective-escaping proof.
references
- Fix log:
docs/fixes/2026-08-22-workdir-naming-hash-suffix.md
Summary by CodeRabbit
-
New Features
- Workdir names now use sanitized component names with an 8-character hash suffix to prevent collisions.
- Legacy workdir formats can be migrated automatically.
- Existing workdirs are validated before reuse to prevent identity mismatches.
workdir clean --all --dry-runlists workdirs without deleting them.
-
Bug Fixes
- Improved workdir discovery, migration, and component-instance path handling.
- Build dependency downloads now retry transient failures.
-
Documentation
- Updated workdir naming, cleanup, listing, and description guidance.
fix(scaffold): pin --update base ref, exclude .git, fix dry-run parity @osterman (#2989)
what
- Pin
atmos scaffold generate --update's default 3-way-merge base ref to the commit
actually created by the initial--gitgeneration, instead of always defaulting to
liveHEAD. - Exclude
.gitdirectories when reading a template's files, for both local-directory
templates andgit::remote sources fetched into a temp dir. - Fix
atmos scaffold generate --dry-runto match real generation exactly: skip
directory entries, honorspec.files[].whenconditions, and render file paths with
the template's ownspec.delimiters.
why
--updatecould silently discard a customization a user had already committed to the
generated project, as long as the template's own change landed on a different line --
because the merge always diffed against liveHEAD, a committed edit became
indistinguishable from the "base" content and the freshly rendered template silently
won with no conflict reported.- A template source that was itself a git checkout (or fetched via
git::) leaked its
own.gitinternals (objects, refs, aconfigpointing at the source repo) into every
generated project. --dry-runreported more files than a real run actually produces (directories counted
as files,when: falsefiles listed anyway, custom-delimiter paths shown unrendered),
making the preview unreliable for reviewing what a generation would do before running it.- All three were reported by a client evaluating the (
[EXPERIMENTAL]) scaffold feature,
with exact repro steps; none had existing tracked issues. A fourth reported bug
(hardcoded default template delimiters in three call sites) is intentionally left out of
this PR -- the client has their own patch and will submit it separately.
references
- Fix record:
docs/fixes/2026-08-24-scaffold-update-git-dryrun-fixes.md
Summary by CodeRabbit
-
New Features
- Enhanced scaffold generation with matrix expansion, conditional files, custom delimiters, target overrides, and update merging.
- Added clearer dry-run previews that validate generation without writing files, creating directories, running hooks, or saving project records.
-
Bug Fixes
- Scaffold updates now preserve customizations using the correct pinned base revision.
- Prevented
.gitcontents from being copied into generated projects. - Improved target resolution, remote template handling, and metadata error reporting.
-
Documentation
- Updated guidance on scaffold updates, dry-run behavior, validation, and known limitations.
fix: ECR/ACR ambient-credential errors and broken --identity selector @osterman (#2977)
what
atmos aws ecr login/atmos azure acr loginambient-credential fallback (no Atmos identity
configured) now returns a rich, actionable error when the underlying cloud SDK fails to retrieve
credentials (e.g. EC2 IMDS timeout, Azure managed identity failure), with an explanation and a
hint to runlogin --identity <name>or configurevia.identity.- Fixed bare
--identity(no value) failing withflag needs an argumentinstead of showing the
interactive identity selector, on 6 commands: custom commands (atmos.yamlcommands:),
describe,list,aws ecr login,aws eks token, andazure aks token. Each had hand-rolled
its own--identityflag registration instead of using the sharedflags.WithIdentityFlag()
builder that ~150 other commands already use, so each silently lost theNoOptDefValwiring that
makes bare--identitylegal and triggers the picker. - Exported
auth.ResolveSelectedIdentity(pkg/auth/manager_helpers.go) so the
sentinel-to-interactive-picker resolution logic lives in one place instead of being duplicated
(aws ecr login) or missing entirely (the other five commands).
why
- A user hit both issues running a downstream custom command (
atmos app build): first
--identity(bare) rejected as a usage error instead of prompting, and separately — once
ambient AWS credentials were tried as a fallback — a bare EC2 IMDS timeout with no indication
that configuring an Atmos identity was the fix. - The
--identityflag exists as a single, centrally-defined flag specifically so this class of
bug can't happen; these 6 commands were the stragglers that never got migrated onto that shared
definition, so the bug had to be independently rediscovered and patched (see the ad-hoc
NoOptDefValfix already present onaws ecr login) instead of being fixed once.
references
docs/fixes/2026-08-20-ecr-acr-ambient-credential-identity-hint.mddocs/fixes/2026-08-21-identity-flag-noOptDefVal-consolidation.md
Summary by CodeRabbit
-
New Features
- Bare
--identitynow opens interactive identity selection across supported AWS, Azure, EKS, listing, description, and custom commands. - Selected identities are consistently applied to subsequent authentication and operations.
- Bare
-
Bug Fixes
- Improved ECR and ACR authentication errors with actionable identity configuration guidance.
- Preserved underlying authentication and selection errors for easier troubleshooting.
-
Documentation
- Added guidance covering interactive identity selection and ambient credential troubleshooting.
fix: prevent concurrent-map-write panic in global Viper singleton @osterman (#2980)
what
- Routes every access to the process-wide global Viper singleton through a new mutex-guarded
pkg/config.GlobalViper()wrapper (SafeViper), instead of callingviper.GetViper()/viper.Set/viper.Get*directly — mirroring the embedded-mutex pattern already used bypkg/io/pkg/ui. - Fixes
pkg/hooks.GetHooksto forward theAtmosConfigit already received intoExecuteDescribeComponentParams, removing a redundant second, independently concurrent config load per hook invocation. - Closes a second, independently racy package-level slice (
mergedConfigFilesinpkg/config/load.go) by wrapping it in its own mutex-guarded tracker. - Adds
pkg/config/load_concurrent_test.go, a-race-driven regression test that spins up concurrentLoadConfigcalls against a real fixture and reproduces the original panic on unfixed code. - Minor cleanup:
bridgeVendorUpdaterConfignow fetchesGlobalViper()once instead of once perSetcall, and a newciFlagKeyconstant replaces 10 duplicated"ci"string literals incmd/terraform/utils.go(surfaced by golangci-lint'sadd-constantcheck once those lines were touched).
why
atmos terraform ... --max-concurrency 3(and even2) could panic withfatal error: concurrent map writesinsideviper.(*Viper).Set, reported from production usage. Root cause:pkg/config.LoadConfigbridgesprofiles.base_pathandvendor.update.*/vendor.ci.*into the process-wide global Viper singleton on every call, with zero locking (spf13/viperhas no internal synchronization), while the DAG scheduler runsLoadConfigconcurrently — once per graph node — whenever--max-concurrency > 1.GetHookswas also triggering a second, entirely redundantInitCliConfig/LoadConfigcall per node because it never forwarded theAtmosConfigit was already given, doubling the exposure to the race for no reason.- The regression test proves the fix: run against the pre-fix code under
go test -race, it reliably reproduces the exactviper.(*Viper).Setrace reported in production; against the fixed code it passes clean.
references
- Reported in Slack by two engineers hitting the same panic at
--max-concurrency 2and3.
Summary by CodeRabbit
-
Bug Fixes
- Improved configuration handling during concurrent operations, preserving environment-key casing and preventing cross-load contamination.
- Ensured hooks use the active configuration when describing components.
- Standardized CI mode and profile settings detection across commands.
- Explicit
--ci=falsenow overrides CI environment settings and automatic CI detection. - Improved reliability when reading shared configuration during shell and command execution, including masking settings.
-
Tests
- Added coverage for concurrent configuration loading, CI precedence, shared configuration access, and configuration-aware hook execution.
fix(terraform): filter CLI args from output hooks @zack-is-cool (#2991)
Summary
TF_CLI_ARGS_apply configured through atmos.yaml no longer reaches Terraform-exec's internal output command. Post-apply output-store hooks can retrieve and publish the declared Terraform output after a successful apply.
Why
Terraform-exec rejects manual command-specific argument variables during its output invocation. Atmos filtered inherited variables but restored them from the resolved component environment. The output path now ignores TF_CLI_ARGS and TF_CLI_ARGS_* while preserving normal environment variables and TF_VAR_* values.
Validation
- Added a regression test for apply and plan CLI arguments while preserving
TF_VAR_*. go build ./...atmos fix coverage origin/main- Patch lint:
0 issues.
Closes #2990
Summary by CodeRabbit
-
Bug Fixes
- Fixed Terraform output retrieval failures caused by command-specific CLI argument environment variables.
- Preserved supported component variables, including
TF_VAR_*values, while excludingTF_CLI_ARGSsettings from output processing.
-
Documentation
- Added documentation describing the fix and its expected behavior.
fix(packer): inject Atmos Auth credentials into the packer subprocess @aknysh (#2986)
what
atmos packernow sets up Atmos Auth the same wayterraformandhelmfiledo: it creates and authenticates the componentAuthManager, passes it toProcessStacks, and injects the resolved identity's credentials into the packer subprocess environment before executing.- Extracted the credential-injection helpers (
resolveDefaultIdentityand the renamedprepareComponentAuthEnvironment, formerlyprepareHelmfileAuthEnvironment) intointernal/exec/utils_auth.goso helmfile and packer share one path instead of duplicating it. - Added regression tests (
internal/exec/packer_auth_test.go) via two test seams: one asserts a non-nilAuthManageris passed toProcessStacks; the other asserts an injected credential reaches the packer subprocess env. - Added a fix record under
docs/fixes/.
why
-
atmos packer buildran completely unauthenticated when relying on Atmos Auth.internal/exec/packer.gocalledProcessStacks(..., nil)(nilAuthManager) and never calledPrepareShellEnvironment, so no AWS credentials ever reached the packer process. Its datasources failed with:Error: Datasource.Execute failed: No valid credential sources found -
Both other component executors already do this —
terraformviasetupTerraformAuth+auth.TerraformPreHook,helmfileviaSetupComponentAuthForCLI+ credential injection — so packer was the odd one out, even though theAuthManagerinterface docstring explicitly lists Packer as a supported subprocess. -
Verified against a real workload:
atmos packer build <component> -s <stack>now proceeds into the AMI build (VPC prevalidation, keypair creation, etc.) where the stock binary failed with the credential error.
references
- Mirrors the existing helmfile auth flow in
internal/exec/helmfile.go. AuthManagercontract:pkg/auth/types/interfaces.go(PrepareShellEnvironment— "Use this for all subprocess invocations: Terraform, Helmfile, Packer, ...").- Fix doc:
docs/fixes/2026-08-23-packer-atmos-auth-credential-injection.md.
Summary by CodeRabbit
Bug Fixes
atmos packer buildnow honors configured authentication settings.- Credentials for authenticated components are automatically resolved and provided during Packer builds.
- Authentication behavior is now consistent across supported component workflows.
- Added regression coverage to improve reliability and prevent authentication regressions.
Documentation
- Added guidance for configuring authentication when using Packer builds.
- Updated workload and continuous integration examples with clearer, generic descriptions.