Skip to content

fix: propagate auth to all YAML functions in multi-component execution#2140

Merged
aknysh merged 6 commits intomainfrom
aknysh/update-terraform-state-5
Mar 4, 2026
Merged

fix: propagate auth to all YAML functions in multi-component execution#2140
aknysh merged 6 commits intomainfrom
aknysh/update-terraform-state-5

Conversation

@aknysh
Copy link
Member

@aknysh aknysh commented Mar 4, 2026

what

  • Propagate Atmos authentication (SSO credentials) to all YAML functions and Go templates when running multi-component execution (--all, --everything)
  • Fix custom-gcl lint binary to build with Go 1.26 toolchain

Auth propagation fix

  • Create AuthManager in ExecuteTerraformQuery before calling ExecuteDescribeStacks (was passing nil)
  • Propagate both AuthContext and AuthManager on configAndStacksInfo in describe_stacks.go for all 4 component types (terraform, helmfile, packer, ansible)
  • Inject authbridge.Resolver into identity-aware stores for !store/!store.get auth support

Lint toolchain fix

  • Bump .custom-gcl.yml from v2.5.0 to v2.10.1 (Go 1.26 support added in v2.9.0)
  • Add GOTOOLCHAIN override in Makefile so custom-gcl is always built with the project's Go version

why

  • When running atmos terraform plan --all -s <stack>, YAML functions like !terraform.state, !terraform.output, !aws.*, !store, and Go template atmos.Component() failed to use Atmos-managed authentication (e.g., AWS SSO). Single-component execution worked correctly because ExecuteTerraform creates an AuthManager, but the multi-component path (ExecuteTerraformQuery) did not.
  • The custom-gcl binary was built with Go 1.25 after the project switched to Go 1.26 in go.mod, causing the golangci-lint pre-commit hook to fail with "Go language version used to build golangci-lint is lower than targeted"

Affected YAML functions

Function Auth mechanism Fixed
!terraform.state stackInfo.AuthContext + AuthManager Yes
!terraform.output stackInfo.AuthContext + AuthManager Yes
!aws.account_id stackInfo.AuthContext.AWS Yes
!aws.caller_identity_arn stackInfo.AuthContext.AWS Yes
!aws.caller_identity_user_id stackInfo.AuthContext.AWS Yes
!aws.region stackInfo.AuthContext.AWS Yes
!aws.organization_id stackInfo.AuthContext.AWS Yes
!store / !store.get authbridge.Resolver Yes
atmos.Component() configAndStacksInfo.AuthContext Yes

references

Summary by CodeRabbit

  • Bug Fixes

    • YAML and template functions (including !terraform.state and !terraform.output) now use authentication correctly during multi-component runs (e.g., --all).
  • Chores

    • Bumped release version to v2.10.1.
    • Removed a custom linter from the build config.
    • Build now invokes an explicit Go toolchain for the linter step.
  • Tests

    • Added extensive unit tests covering auth creation and propagation for YAML/template functions.

aknysh and others added 2 commits March 3, 2026 23:14
#2081)

When running `atmos terraform plan --all`, YAML functions like
`!terraform.state`, `!terraform.output`, `!aws.*`, `!store`, and Go
template `atmos.Component()` failed to use Atmos-managed authentication
(e.g., AWS SSO). This was because `ExecuteTerraformQuery` passed nil
AuthManager to `ExecuteDescribeStacks`.

Create AuthManager before `ExecuteDescribeStacks`, propagate both
AuthContext and AuthManager in `describe_stacks.go` for all 4 component
types, and inject auth resolver for identity-aware stores via
`authbridge.NewResolver`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bump .custom-gcl.yml from v2.5.0 to v2.10.1 (Go 1.26 support added in
v2.9.0). Add GOTOOLCHAIN override in Makefile to ensure custom-gcl is
always built with the same Go version used by the project, preventing
"Go language version used to build golangci-lint is lower than targeted"
errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@aknysh aknysh added the patch A minor, backward compatible change label Mar 4, 2026
@aknysh aknysh requested a review from a team as a code owner March 4, 2026 04:28
@aknysh aknysh added the patch A minor, backward compatible change label Mar 4, 2026
@github-actions github-actions bot added the size/l Large size PR label Mar 4, 2026
@aknysh aknysh self-assigned this Mar 4, 2026
@mergify
Copy link

mergify bot commented Mar 4, 2026

Important

Cloud Posse Engineering Team Review Required

This pull request modifies files that require Cloud Posse's review. Please be patient, and a core maintainer will review your changes.

To expedite this process, reach out to us on Slack in the #pr-reviews channel.

@mergify mergify bot added the needs-cloudposse Needs Cloud Posse assistance label Mar 4, 2026
@github-actions
Copy link

github-actions bot commented Mar 4, 2026

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 4, 2026

📝 Walkthrough

Walkthrough

Adds an authentication creation and propagation path so YAML Terraform functions (!terraform.state, !terraform.output) run with Atmos AuthManager/AuthContext during multi-component execution (e.g., --all), and adds tests and docs validating the behavior.

Changes

Cohort / File(s) Summary
Build & Configuration
\.custom-gcl\.yml, Makefile
Bump golangci-lint version to v2.10.1, remove lintroller plugin entry, and set GOTOOLCHAIN in the custom golangci-lint build step.
Documentation
docs/fixes/2026-03-03-yaml-functions-auth-multi-component.md
New detailed doc describing AuthManager/AuthContext propagation for YAML functions across multi-component execution and test coverage.
Core Implementation
internal/exec/terraform_query.go, internal/exec/describe_stacks.go
Add createQueryAuthManager and propagateAuth helpers; wire AuthManager creation into terraform query flow, inject auth resolver into stores, and pass AuthManager/AuthContext into ExecuteDescribeStacks and downstream processing.
Tests
internal/exec/terraform_query_test.go
New comprehensive tests (multiple cases) validating AuthManager creation, error handling (including user abort), and AuthContext/AuthManager propagation into YAML terraform functions.

Sequence Diagram(s)

sequenceDiagram
    actor User as User
    participant TQ as terraform_query
    participant AM as AuthManager
    participant Stores as AtmosStores
    participant DS as describe_stacks
    participant YF as YAML_Functions
    participant TG as Terraform_StateGetter

    User->>TQ: run plan --all
    activate TQ
    TQ->>AM: createQueryAuthManager()
    activate AM
    AM-->>TQ: AuthManager (or nil / error)
    deactivate AM
    alt auth manager created
        TQ->>Stores: SetAuthContextResolver(authbridge.NewResolver(AuthManager, info))
    end
    TQ->>DS: ExecuteDescribeStacks(authManager)
    activate DS
    DS->>YF: resolve YAML functions (state/output) with AuthContext
    activate YF
    YF->>TG: GetState/GetOutput(with AuthContext)
    activate TG
    TG-->>YF: state/output data
    deactivate TG
    YF-->>DS: resolved values
    deactivate YF
    DS-->>TQ: stacks info/result
    deactivate DS
    TQ-->>User: result/exit
    deactivate TQ
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • osterman
  • milldr
  • mcalhoun
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: propagating authentication to YAML functions during multi-component execution, which directly addresses the core issue.
Linked Issues check ✅ Passed All coding requirements from issue #2081 are met: AuthManager creation in ExecuteTerraformQuery, auth propagation through configAndStacksInfo, authbridge resolver injection, and YAML function fixes.
Out of Scope Changes check ✅ Passed Changes are scoped to the linked issue: auth propagation for multi-component execution and a necessary toolchain fix for golangci-lint compatibility. No unrelated changes detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch aknysh/update-terraform-state-5

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
internal/exec/terraform_query_test.go (1)

17-66: Consider consolidating these auth-manager scenarios into a table-driven test.

The three createQueryAuthManager tests follow the same setup/assert structure and can be compacted into a single table-driven case matrix for maintainability.

As per coding guidelines: Use table-driven tests for testing multiple scenarios in Go.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/exec/terraform_query_test.go` around lines 17 - 66, Consolidate the
three tests for createQueryAuthManager
(TestCreateQueryAuthManager_NoAuthConfigured,
TestCreateQueryAuthManager_ErrorReturned,
TestCreateQueryAuthManager_EmptyIdentity) into a single table-driven test:
define a slice of test cases with fields like name, info
(*schema.ConfigAndStacksInfo), atmosConfig (*schema.AtmosConfiguration), wantErr
(bool), wantErrIs (error or nil), and wantAuthNil (bool); iterate over cases
with t.Run(tc.name, func(t *testing.T) { authManager, err :=
createQueryAuthManager(tc.info, tc.atmosConfig); assert conditions using
tc.wantErr, assert.ErrorIs for tc.wantErrIs when non-nil, and
assert.Nil/assert.NotNil on authManager and tc.info.AuthManager per
tc.wantAuthNil }); keep each case setup minimal (use t.TempDir for BasePath) and
preserve the original expectations (ErrAuthNotConfigured for the error case).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/exec/terraform_query_test.go`:
- Around line 68-142: The test currently bypasses ExecuteDescribeStacks by
seeding AuthContext and calling ProcessCustomYamlTags directly; change it to
exercise the actual propagation path by invoking ExecuteDescribeStacks (or the
helper that drives the describe-stacks flow) with mockManager so that
ExecuteDescribeStacks calls authManager.GetStackInfo() and sets
configAndStacksInfo.AuthContext before YAML processing; keep the
mockManager.Expect().GetStackInfo().Return(stackInfo).AnyTimes(), keep the
mockStateGetter to assert GetState receives gomock.Eq(expectedAuthContext), and
do not pre-populate AuthContext in the ProcessCustomYamlTags call—pass nil so
the AuthContext must come from GetStackInfo via ExecuteDescribeStacks
(references: TestDescribeStacksAuthPropagation, ExecuteDescribeStacks,
ProcessCustomYamlTags, GetStackInfo, ConfigAndStacksInfo.AuthContext).

In `@internal/exec/terraform_query.go`:
- Around line 94-99: The error returned from the auth creation branch is
returned raw, losing context; update the return to wrap err with query-specific
context using fmt.Errorf, e.g. replace the bare "return nil, err" with "return
nil, fmt.Errorf(\"creating auth for terraform query: %w\", err)"; keep the
existing handling for errors.Is(err, errUtils.ErrUserAborted) and errUtils.Exit
and ensure fmt is imported if not already.

---

Nitpick comments:
In `@internal/exec/terraform_query_test.go`:
- Around line 17-66: Consolidate the three tests for createQueryAuthManager
(TestCreateQueryAuthManager_NoAuthConfigured,
TestCreateQueryAuthManager_ErrorReturned,
TestCreateQueryAuthManager_EmptyIdentity) into a single table-driven test:
define a slice of test cases with fields like name, info
(*schema.ConfigAndStacksInfo), atmosConfig (*schema.AtmosConfiguration), wantErr
(bool), wantErrIs (error or nil), and wantAuthNil (bool); iterate over cases
with t.Run(tc.name, func(t *testing.T) { authManager, err :=
createQueryAuthManager(tc.info, tc.atmosConfig); assert conditions using
tc.wantErr, assert.ErrorIs for tc.wantErrIs when non-nil, and
assert.Nil/assert.NotNil on authManager and tc.info.AuthManager per
tc.wantAuthNil }); keep each case setup minimal (use t.TempDir for BasePath) and
preserve the original expectations (ErrAuthNotConfigured for the error case).

ℹ️ Review info
Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7ff75bc0-351b-4fb9-8514-92687b7a0c5b

📥 Commits

Reviewing files that changed from the base of the PR and between 8cd0056 and ffdffe7.

📒 Files selected for processing (6)
  • .custom-gcl.yml
  • Makefile
  • docs/fixes/2026-03-03-yaml-functions-auth-multi-component.md
  • internal/exec/describe_stacks.go
  • internal/exec/terraform_query.go
  • internal/exec/terraform_query_test.go

@codecov
Copy link

codecov bot commented Mar 4, 2026

Codecov Report

❌ Patch coverage is 85.29412% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.59%. Comparing base (82c6e20) to head (7592729).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
internal/exec/terraform_query.go 78.26% 3 Missing and 2 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2140      +/-   ##
==========================================
+ Coverage   76.56%   76.59%   +0.03%     
==========================================
  Files         832      832              
  Lines       79507    79524      +17     
==========================================
+ Hits        60874    60915      +41     
+ Misses      14836    14812      -24     
  Partials     3797     3797              
Flag Coverage Δ
unittests 76.59% <85.29%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
internal/exec/describe_stacks.go 72.58% <100.00%> (+1.31%) ⬆️
internal/exec/terraform_query.go 79.62% <78.26%> (-1.63%) ⬇️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

aknysh and others added 3 commits March 4, 2026 00:03
- Extract propagateAuth helper from describe_stacks.go inline blocks
- Consolidate createQueryAuthManager tests into table-driven test
- Replace TestDescribeStacksAuthPropagation with TestPropagateAuth that
  exercises the actual GetStackInfo() -> AuthContext propagation path
- Inject authManagerFactory for testability, covering ErrUserAborted
  exit path and non-nil manager stored in info
- Wrap auth creation error with call-site context
- Achieve 100% coverage on createQueryAuthManager and propagateAuth

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions bot added size/m Medium size PR and removed size/l Large size PR labels Mar 4, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
internal/exec/terraform_query.go (1)

17-22: Prefer injected dependencies over a package-global factory hook.

This works, but a mutable package-global test hook can make test isolation brittle over time. A small injected dependency container for query execution would keep the same testability without shared global state.

♻️ Optional refactor sketch
+type terraformQueryDeps struct {
+	createAuthManager func(identity string, authConfig schema.AuthConfig, flagSelectValue string, atmosConfig *schema.AtmosConfiguration) (auth.AuthManager, error)
+}
+
+var defaultTerraformQueryDeps = terraformQueryDeps{
+	createAuthManager: func(identity string, authConfig schema.AuthConfig, flagSelectValue string, atmosConfig *schema.AtmosConfiguration) (auth.AuthManager, error) {
+		mergedAuthConfig := auth.CopyGlobalAuthConfig(&authConfig)
+		return auth.CreateAndAuthenticateManagerWithAtmosConfig(identity, mergedAuthConfig, flagSelectValue, atmosConfig)
+	},
+}

As per coding guidelines: Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/exec/terraform_query.go` around lines 17 - 22, Replace the mutable
package-global test hook authManagerFactory with an injected dependency: add an
interface (e.g., AuthManagerFactory with a Create(identity, authConfig,
flagSelectValue, atmosConfig) method) and accept an implementation via the
constructor or as a field on the query executor type that currently uses
authManagerFactory; update all call sites to use the injected factory instead of
the package variable and provide a mock implementation in tests (use
testify/mock or a simple stub) that delegates to
auth.CreateAndAuthenticateManagerWithAtmosConfig for production. Ensure the new
interface name and method map to authManagerFactory's signature so callers like
CreateAndAuthenticateManagerWithAtmosConfig are easy to replace in tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@internal/exec/terraform_query.go`:
- Around line 17-22: Replace the mutable package-global test hook
authManagerFactory with an injected dependency: add an interface (e.g.,
AuthManagerFactory with a Create(identity, authConfig, flagSelectValue,
atmosConfig) method) and accept an implementation via the constructor or as a
field on the query executor type that currently uses authManagerFactory; update
all call sites to use the injected factory instead of the package variable and
provide a mock implementation in tests (use testify/mock or a simple stub) that
delegates to auth.CreateAndAuthenticateManagerWithAtmosConfig for production.
Ensure the new interface name and method map to authManagerFactory's signature
so callers like CreateAndAuthenticateManagerWithAtmosConfig are easy to replace
in tests.

ℹ️ Review info
Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: caa6b8d0-abdf-408b-b38f-903d1dbc2a10

📥 Commits

Reviewing files that changed from the base of the PR and between ffdffe7 and 5b265d0.

📒 Files selected for processing (3)
  • internal/exec/describe_stacks.go
  • internal/exec/terraform_query.go
  • internal/exec/terraform_query_test.go

@aknysh aknysh merged commit 74b4aae into main Mar 4, 2026
57 checks passed
@aknysh aknysh deleted the aknysh/update-terraform-state-5 branch March 4, 2026 16:02
@mergify mergify bot removed the needs-cloudposse Needs Cloud Posse assistance label Mar 4, 2026
@github-actions
Copy link

github-actions bot commented Mar 5, 2026

These changes were released in v1.208.1-test.0.

goruha added a commit that referenced this pull request Mar 9, 2026
…raform-plan

* osterman/native-ci-terraform: (28 commits)
  feat: Add source cache TTL for JIT-vendored components (#2138)
  feat: Per-target version overrides in vendor manifests (#2141)
  docs: Add PRD for browser-based auth in aws/user identity (#1887)
  docs: Add EKS kubeconfig authentication integration PRD (#1884)
  fix: correct marketplace.json schema and update docs with install/uninstall commands (#2142)
  fix: propagate auth to all YAML functions in multi-component execution (#2140)
  fix: Use atmos_component for source provisioner workdir paths (#2137)
  Fix identity prompts to respect --interactive flag (#2130)
  Increase PR size thresholds to accommodate AI-assisted development (#2136)
  docs: Add Azure authentication provider documentation (#2132)
  fix: propagate component-type level dependencies through stack processor (#2127)
  fix: Add retry and missing workflow step properties to all schema copies (#2113)
  Exclude unsupported windows/arm from goreleaser build matrix (#2133)
  Add AI Agent Skills for LLM-Powered Infrastructure Development (#2121)
  Fix: Convert toolchain paths to absolute in PATH to resolve exec.LookPath failures (#2095)
  Fix workdir collision for component instances sharing base component (#2093)
  fix(auth): propagate TTY state to subprocesses for SSO device flow in workflows (#2126)
  fix(security): prevent SSRF in GitHub OIDC token URL handling (CWE-918) (#2106)
  Fix #2112: add workflow_retry definition and retry property to workflow step schema (#2114)
  fix(auth): auto-detect GitHub Actions WIF with proper audience, host validation, and lazy GSM init (#2109)
  ...
@github-actions
Copy link

github-actions bot commented Mar 9, 2026

These changes were released in v1.208.1-test.9.

@github-actions
Copy link

github-actions bot commented Mar 9, 2026

These changes were released in v1.208.1-test.10.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

patch A minor, backward compatible change size/m Medium size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

!terraform.state not using Atmos authentication when planning/applying the entire stack

2 participants