fix: propagate auth to all YAML functions in multi-component execution#2140
fix: propagate auth to all YAML functions in multi-component execution#2140
Conversation
#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>
|
Important Cloud Posse Engineering Team Review RequiredThis 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 |
Dependency Review✅ No vulnerabilities or license issues found.Scanned FilesNone |
📝 WalkthroughWalkthroughAdds an authentication creation and propagation path so YAML Terraform functions ( Changes
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
createQueryAuthManagertests 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
📒 Files selected for processing (6)
.custom-gcl.ymlMakefiledocs/fixes/2026-03-03-yaml-functions-auth-multi-component.mdinternal/exec/describe_stacks.gointernal/exec/terraform_query.gointernal/exec/terraform_query_test.go
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ 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
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
- 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>
… into aknysh/update-terraform-state-5
There was a problem hiding this comment.
🧹 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
📒 Files selected for processing (3)
internal/exec/describe_stacks.gointernal/exec/terraform_query.gointernal/exec/terraform_query_test.go
|
These changes were released in v1.208.1-test.0. |
…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) ...
|
These changes were released in v1.208.1-test.9. |
|
These changes were released in v1.208.1-test.10. |
what
--all,--everything)custom-gcllint binary to build with Go 1.26 toolchainAuth propagation fix
AuthManagerinExecuteTerraformQuerybefore callingExecuteDescribeStacks(was passingnil)AuthContextandAuthManageronconfigAndStacksInfoindescribe_stacks.gofor all 4 component types (terraform, helmfile, packer, ansible)authbridge.Resolverinto identity-aware stores for!store/!store.getauth supportLint toolchain fix
.custom-gcl.ymlfrom v2.5.0 to v2.10.1 (Go 1.26 support added in v2.9.0)GOTOOLCHAINoverride in Makefile socustom-gclis always built with the project's Go versionwhy
atmos terraform plan --all -s <stack>, YAML functions like!terraform.state,!terraform.output,!aws.*,!store, and Go templateatmos.Component()failed to use Atmos-managed authentication (e.g., AWS SSO). Single-component execution worked correctly becauseExecuteTerraformcreates anAuthManager, but the multi-component path (ExecuteTerraformQuery) did not.custom-gclbinary was built with Go 1.25 after the project switched to Go 1.26 ingo.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
!terraform.statestackInfo.AuthContext+AuthManager!terraform.outputstackInfo.AuthContext+AuthManager!aws.account_idstackInfo.AuthContext.AWS!aws.caller_identity_arnstackInfo.AuthContext.AWS!aws.caller_identity_user_idstackInfo.AuthContext.AWS!aws.regionstackInfo.AuthContext.AWS!aws.organization_idstackInfo.AuthContext.AWS!store/!store.getauthbridge.Resolveratmos.Component()configAndStacksInfo.AuthContextreferences
Summary by CodeRabbit
Bug Fixes
Chores
Tests