Skip to content

fix: Resolve Atmos Pro template regression with {{ .atmos_component }} in non-.tmpl files#2053

Merged
aknysh merged 2 commits intomainfrom
aknysh/fix-atmos-pro-regression
Feb 4, 2026
Merged

fix: Resolve Atmos Pro template regression with {{ .atmos_component }} in non-.tmpl files#2053
aknysh merged 2 commits intomainfrom
aknysh/fix-atmos-pro-regression

Conversation

@aknysh
Copy link
Copy Markdown
Member

@aknysh aknysh commented Feb 4, 2026

what

  • Fix regression introduced in Atmos 1.205 where {{ .atmos_component }} and {{ .atmos_stack }} templates in non-.tmpl files fail during import with: map has no entry for key "atmos_component"
  • Add processTemplatesInSection() helper to resolve {{ .locals.X }} in individual sections (settings, vars, env) without triggering full-file template processing
  • Skip .terraform directories in describe-affected test copies to avoid dangling symlink failures
  • Add --verify=false to helm plugin install in Dockerfile for Helm 4 compatibility

why

Atmos Pro template regression (Issue #2032)

The locals feature (PR #1994) inadvertently triggered template processing for imported non-.tmpl files. extractAndAddLocalsToContext() populated the template context with settings/vars/env from the file, making len(context) > 0, which triggered the template processing guard. Templates like {{ .atmos_component }} then failed because component context isn't available at import time.

Fix: Track whether context was originally provided externally (originalContextProvided) vs extracted from the file itself. When template processing fails and only file-extracted context is available, gracefully fall back to raw content — preserving templates like {{ .atmos_component }} for later resolution in ProcessStacks when the full component context is available.

Additionally, extractAndAddLocalsToContext() now processes templates in individual sections (settings → vars → env) using a pipeline with resolved locals context. This enables bidirectional references between locals and settings while avoiding premature processing of component-scoped templates.

Dangling .terraform symlinks in describe-affected tests

TestDescribeAffectedWith* tests failed locally due to a dangling symlink in examples/secrets-masking/.terraform/providers/ left by a previous test run. Added .terraform to the copy skip filter alongside the existing node_modules skip.

Helm plugin install in Dockerfile

Helm 4 requires --verify=false because helm-diff does not ship .prov signature files.

references

Summary by CodeRabbit

  • Bug Fixes

    • Preserve component- and stack-level templates during import and defer evaluation until full context is available to prevent premature resolution and regressions.
    • Persist resolved section values so downstream describe/merge flows see processed results.
  • New Features

    • Enhanced template resolution to support cross-references between locals, settings, vars, and env.
  • New Tests

    • Large suite of tests covering template processing, cross-references, external-context behavior, and a regression case.
  • Chores

    • Adjusted Helm plugin install for Helm 4 compatibility and expanded file exclusion patterns during config processing.

…} in non-.tmpl files

Starting in Atmos 1.205, stack manifests using {{ .atmos_component }} or
{{ .atmos_stack }} in non-template files fail during import with:
"map has no entry for key atmos_component"

The locals feature inadvertently triggered template processing for imported
files by populating the template context with settings/vars/env, making
len(context) > 0. Templates like {{ .atmos_component }} then failed because
component context isn't available at import time.

Fix: Track whether context was originally provided externally vs extracted
from the file itself. When template processing fails and only file-extracted
context is available, gracefully fall back to raw content — preserving
templates for later resolution in ProcessStacks when full component context
is available.

Also adds processTemplatesInSection() to resolve {{ .locals.X }} references
in individual sections (settings, vars, env) without processing the whole
file, and persists resolved sections back into stackConfigMap.

Additional fixes included:
- Skip .terraform dirs in describe-affected test copies (dangling symlinks)
- Add --verify=false to helm plugin install in Dockerfile (Helm 4 compat)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@aknysh aknysh requested a review from a team as a code owner February 4, 2026 18:58
@aknysh aknysh added the patch A minor, backward compatible change label Feb 4, 2026
@aknysh aknysh requested a review from a team as a code owner February 4, 2026 18:58
@github-actions github-actions bot added the size/m Medium size PR label Feb 4, 2026
@aknysh aknysh self-assigned this Feb 4, 2026
@mergify
Copy link
Copy Markdown

mergify bot commented Feb 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 Feb 4, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 4, 2026

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 4, 2026

📝 Walkthrough

Walkthrough

Adds YAML-aware template processing for stack-level sections (locals, settings, vars, env): introduces an unexported helper to render templates inside sections, changes locals key to cfg.LocalsSectionName, defers import-time template evaluation when no external context is provided, persists resolved sections into stackConfigMap, adds tests and fixtures, and tweaks Dockerfile helm-diff install.

Changes

Cohort / File(s) Summary
Core template logic
internal/exec/stack_processor_utils.go
Adds processTemplatesInSection (unexported); processes locals first, then settings/vars/env via YAML round-trip templating; switches file-scoped locals key to cfg.LocalsSectionName; defers import template processing when no external context; persists resolved sections into stackConfigMap.
Tests & test helpers
internal/exec/stack_processor_utils_test.go, internal/exec/describe_affected_test.go
Adds extensive tests for section template processing, context interplay, and regression (TestAtmosProTemplateRegression); updates test copy skip rules to ignore node_modules and .terraform.
Fixtures (new scenario)
tests/fixtures/scenarios/atmos-pro-template-regression/...
Adds scenario fixtures: atmos.yaml, stacks/deploy/test.yaml, stacks/mixins/atmos-pro.yaml, and components/terraform/vpc/main.tf to reproduce template/local interaction/regression.
CI container
Dockerfile
Changes helm-diff plugin install to helm plugin install --verify=false https://github.com/databus23/helm-diff with comment about Helm 4 requiring --verify=false due to missing .prov signatures.

Sequence Diagram(s)

(Skipped — internal template-processing changes do not introduce a new multi-actor runtime flow requiring a sequence diagram.)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • osterman
🚥 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 describes the main fix: resolving a regression where {{ .atmos_component }} templates in non-.tmpl files fail during import.
Linked Issues check ✅ Passed The PR addresses all requirements from issue #2032: restores settings-to-locals references, enables locals-to-settings references, and ensures bidirectional resolution with proper fallback behavior.
Out of Scope Changes check ✅ Passed All changes align with stated objectives: Dockerfile helm-diff fix, test fixture skips for .terraform, section-level template processing, and regression test fixture are all justified by the regression fix or infrastructure improvements.
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
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch aknysh/fix-atmos-pro-regression

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.

@aknysh
Copy link
Copy Markdown
Member Author

aknysh commented Feb 4, 2026

@coderabbitai full review please

@codecov
Copy link
Copy Markdown

codecov bot commented Feb 4, 2026

Codecov Report

❌ Patch coverage is 90.41096% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.69%. Comparing base (a20e3fe) to head (4162ad5).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
internal/exec/stack_processor_utils.go 90.41% 4 Missing and 3 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2053      +/-   ##
==========================================
+ Coverage   75.65%   75.69%   +0.04%     
==========================================
  Files         793      793              
  Lines       73892    73953      +61     
==========================================
+ Hits        55901    55979      +78     
+ Misses      14498    14479      -19     
- Partials     3493     3495       +2     
Flag Coverage Δ
unittests 75.69% <90.41%> (+0.04%) ⬆️

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

Files with missing lines Coverage Δ
internal/exec/stack_processor_utils.go 81.14% <90.41%> (+1.44%) ⬆️

... 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.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 4, 2026

@aknysh I'll conduct a full review of all the changes in this PR.


🧠 Learnings used
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.

Learnt from: aknysh
Repo: cloudposse/atmos PR: 1363
File: internal/exec/template_utils.go:18-18
Timestamp: 2025-07-05T20:59:02.914Z
Learning: In the Atmos project, gomplate v4 is imported with a blank import (`_ "github.com/hairyhenderson/gomplate/v4"`) alongside v3 imports to resolve AWS SDK version conflicts. V3 uses older AWS SDK versions that conflict with newer AWS modules used by Atmos. A full migration to v4 requires extensive refactoring due to API changes and should be handled in a separate PR.

Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: docs/prd/tool-dependencies-integration.md:58-64
Timestamp: 2025-12-13T06:07:37.766Z
Learning: cloudposse/atmos: For PRD docs (docs/prd/*.md), markdownlint issues like MD040/MD010/MD034 can be handled in a separate documentation cleanup commit and should not block the current PR.

Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.

Learnt from: osterman
Repo: cloudposse/atmos PR: 1891
File: pkg/ci/terraform/templates/apply.md:17-17
Timestamp: 2025-12-24T04:29:23.938Z
Learning: In the cloudposse/atmos repository, Terraform CI templates (pkg/ci/terraform/templates/*.md) are rendered using TerraformTemplateContext (defined in pkg/ci/terraform/context.go), not the base ci.TemplateContext. TerraformTemplateContext provides top-level fields: .Resources (ci.ResourceCounts), .HasChanges() method, and .HasDestroy field, which are correctly accessed directly in templates without a .Result prefix.
✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 4, 2026

📝 Walkthrough

Walkthrough

This PR addresses a regression where settings could not reference locals in version 1.205. It introduces deferred, section-aware template processing for locals, settings, vars, and env with an originalContextProvided flag to distinguish import-time processing from component-specific context. A regression test validates that templates in settings can safely reference locals.

Changes

Cohort / File(s) Summary
Helm Configuration
Dockerfile
Added --verify=false flag to helm-diff plugin installation with clarifying comment regarding Helm 4 signature limitations.
Test Infrastructure
internal/exec/describe_affected_test.go
Updated Skip filter to exclude both node_modules and .terraform directories during test file copying.
Core Template Processing
internal/exec/stack_processor_utils.go, internal/exec/stack_processor_utils_test.go
Introduced processTemplatesInSection helper function to handle YAML template resolution within sections. Integrated per-section template processing order (locals → settings → vars → env) with deferred processing for import contexts lacking external input. Added originalContextProvided flag to control fallback behavior. New regression test validates settings can reference locals without premature template resolution.
Test Fixtures for Regression
tests/fixtures/scenarios/atmos-pro-template-regression/*
Added complete test scenario including Atmos configuration, mixin with locals and settings references, Terraform component definition, and stack deployment files to reproduce and validate the locals-in-settings reference fix.

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related PRs

Suggested Reviewers

  • osterman
  • kevcube
🚥 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 PR title accurately describes the main fix—resolving a template regression with {{ .atmos_component }} in non-.tmpl files, which directly addresses the core issue being fixed.
Linked Issues check ✅ Passed The code changes comprehensively address all requirements from issue #2032: template processing now respects context origin, settings can reference locals through new processTemplatesInSection(), and component-scoped templates defer processing until appropriate context is available.
Out of Scope Changes check ✅ Passed All changes directly support the core fix objectives. The Dockerfile helm-diff fix aids compatibility, test fixture exclusion of .terraform prevents unrelated failures, and the new regression test validates the fix—all reasonably scoped.
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
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch aknysh/fix-atmos-pro-regression

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
Copy Markdown
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: 1

🤖 Fix all issues with AI agents
In `@internal/exec/stack_processor_utils.go`:
- Around line 247-284: The section template contexts currently use only locals
(localsOnlyContext / varsContext / envContext) which ignores any external import
context present in the surrounding `context`, causing templates like `{{
.settings.foo }}` to resolve incorrectly; update the code that builds the
context for processTemplatesInSection (for settings, vars, and env) to start by
copying the existing `context` map, then set/override the entries for
cfg.LocalsSectionName, cfg.SettingsSectionName and cfg.VarsSectionName as needed
before calling processTemplatesInSection so that explicit import/component
context already present in `context` is honored (refer to
processTemplatesInSection, cfg.SettingsSectionName, cfg.VarsSectionName,
cfg.LocalsSectionName, and extractResult.settings/vars/env to locate the spots
to change).
🧹 Nitpick comments (1)
internal/exec/stack_processor_utils_test.go (1)

1975-2061: Solid regression test.

Good coverage of the Atmos Pro template regression. The test:

  • Clearly documents the 1.204 vs 1.205 behavior difference
  • Uses filepath.Join for cross-platform paths
  • Validates both success and template preservation

One minor note: the assertion on line 2059 checks Contains(componentInput, "atmos_component") which works, but checking for the exact template string "{{ .atmos_component }}" would be more precise.

Optional: More precise assertion
-	assert.Contains(t, componentInput, "atmos_component",
-		"Template {{ .atmos_component }} should be preserved during import, not processed")
+	assert.Equal(t, "{{ .atmos_component }}", componentInput,
+		"Template {{ .atmos_component }} should be preserved during import, not processed")

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 4, 2026

@aknysh I'll conduct a comprehensive review of all the changes in this PR.


🧠 Learnings used
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.

Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: docs/prd/tool-dependencies-integration.md:58-64
Timestamp: 2025-12-13T06:07:37.766Z
Learning: cloudposse/atmos: For PRD docs (docs/prd/*.md), markdownlint issues like MD040/MD010/MD034 can be handled in a separate documentation cleanup commit and should not block the current PR.

Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: pkg/config/config.go:478-483
Timestamp: 2024-12-02T21:26:32.337Z
Learning: In the 'atmos' project, when reviewing Go code like `pkg/config/config.go`, avoid suggesting file size checks after downloading remote configs if such checks aren't implemented elsewhere in the codebase.

Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: examples/quick-start-advanced/components/terraform/vpc/README.md.gotmpl:0-0
Timestamp: 2025-01-25T03:46:21.660Z
Learning: Template formatting and content changes in `.gotmpl` files are out of scope for review unless explicitly requested.

Learnt from: aknysh
Repo: cloudposse/atmos PR: 1327
File: internal/exec/describe_affected_utils_2.go:248-248
Timestamp: 2025-06-23T18:50:33.614Z
Learning: When aknysh mentions that a suggestion is not related to the current PR and needs separate tests to be reviewed in a separate PR, this indicates their preference for maintaining focused PR scope and proper test coverage for each change.

Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.

Learnt from: aknysh
Repo: cloudposse/atmos PR: 1363
File: internal/exec/template_utils.go:18-18
Timestamp: 2025-07-05T20:59:02.914Z
Learning: In the Atmos project, gomplate v4 is imported with a blank import (`_ "github.com/hairyhenderson/gomplate/v4"`) alongside v3 imports to resolve AWS SDK version conflicts. V3 uses older AWS SDK versions that conflict with newer AWS modules used by Atmos. A full migration to v4 requires extensive refactoring due to API changes and should be handled in a separate PR.

Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/http_client_test.go:3-10
Timestamp: 2025-09-10T21:17:55.273Z
Learning: In the cloudposse/atmos repository, imports should never be changed as per samtholiya's coding guidelines.

Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: errors/errors.go:184-203
Timestamp: 2025-12-13T06:10:13.688Z
Learning: cloudposse/atmos: For toolchain work, duplicate/unused error sentinels in errors/errors.go should be cleaned up in a separate refactor PR and not block feature PRs; canonical toolchain sentinels live under toolchain/registry with re-exports in toolchain/errors.go.

Learnt from: osterman
Repo: cloudposse/atmos PR: 1891
File: pkg/ci/terraform/templates/apply.md:17-17
Timestamp: 2025-12-24T04:29:23.938Z
Learning: In the cloudposse/atmos repository, Terraform CI templates (pkg/ci/terraform/templates/*.md) are rendered using TerraformTemplateContext (defined in pkg/ci/terraform/context.go), not the base ci.TemplateContext. TerraformTemplateContext provides top-level fields: .Resources (ci.ResourceCounts), .HasChanges() method, and .HasDestroy field, which are correctly accessed directly in templates without a .Result prefix.
✅ Actions performed

Full review triggered.

…nd improve test precision

- Seed section contexts (settings/vars/env) with external import context
  so templates referencing import-provided values resolve during section
  processing, not just during full-file processing
- Change assert.Contains to assert.Equal for template preservation
  assertions to verify exact template strings are preserved verbatim
- Add TestExtractAndAddLocalsToContext_ExternalContext with 3 subtests
  covering external context resolution, cross-section propagation,
  and graceful fallback when context is insufficient

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions github-actions bot added size/l Large size PR and removed size/m Medium size PR labels Feb 4, 2026
@aknysh aknysh merged commit 802e656 into main Feb 4, 2026
56 checks passed
@aknysh aknysh deleted the aknysh/fix-atmos-pro-regression branch February 4, 2026 20:44
@mergify mergify bot removed the needs-cloudposse Needs Cloud Posse assistance label Feb 4, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 5, 2026

These changes were released in v1.205.1.

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/l Large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1.205 regression: Settings can't refer to locals anymore

2 participants