Skip to content

feat: Packer directory-based template support and improvements#1982

Merged
aknysh merged 25 commits intomainfrom
aknysh/update-packer-2
Jan 17, 2026
Merged

feat: Packer directory-based template support and improvements#1982
aknysh merged 25 commits intomainfrom
aknysh/update-packer-2

Conversation

@aknysh
Copy link
Copy Markdown
Member

@aknysh aknysh commented Jan 16, 2026

what

  • Directory-based Packer templates: Atmos now defaults the template to . (current directory) when not specified, allowing Packer to load all *.pkr.hcl files from the component directory automatically. This aligns with HashiCorp's recommended multi-file configuration patterns.
  • Configuration validation: Added checkPackerConfig() validation to both ExecutePacker and ExecutePackerOutput functions, ensuring Packer base path is configured before execution.
  • Cleanup file leak fix: Implemented proper defer pattern for variable file cleanup to prevent file leaks on early errors.
  • Abstract and locked component protection: Added checks to prevent packer build on abstract (metadata.type: abstract) and locked (metadata.locked: true) components while allowing read-only commands like validate and inspect.
  • Error message consistency: Standardized error message quoting style across Packer files (using single quotes consistently).
  • New ErrMissingPackerBasePath error: Added dedicated error type for missing Packer configuration.
  • Comprehensive troubleshooting documentation: Added new troubleshooting guide covering common Packer issues and solutions.
  • Improved godoc comments: Added comprehensive documentation to PackerFlags struct and its fields.
  • Test coverage improvements:
    • Added TestExecutePacker_Fmt for the fmt command
    • Added TestExecutePacker_ComponentMetadata for abstract/locked component handling
    • Added TestCheckPackerConfig for configuration validation
    • Added captureStdout test helper to reduce code duplication
    • Added test for missing Packer base path in ExecutePackerOutput

why

  • Fixes GitHub issue Packer variables.pkr.hcl not utilized #1937: Users following HashiCorp's best practice of organizing Packer configurations across multiple files (variables.pkr.hcl, main.pkr.hcl, etc.) encountered "Unsupported attribute" errors because Atmos only loaded a single template file.
  • Improved reliability: The cleanup fix and configuration validation prevent resource leaks and provide better error messages.
  • Consistency with Terraform: The abstract/locked component protection matches the behavior already implemented for Terraform components.
  • Better developer experience: The troubleshooting documentation and improved error messages help users resolve issues faster.

references

Summary of Changes

New Features

  • Directory-based template loading (default to . when no template specified)
  • Multi-file Packer component support

Bug Fixes

  • Variable file cleanup on early errors (defer pattern)
  • Configuration validation before execution

Improvements

  • Abstract/locked component protection for packer build
  • Standardized error messages
  • Comprehensive troubleshooting documentation
  • Test coverage expansion
  • Code documentation (godoc comments)

Test Plan

  • All existing Packer tests pass
  • New tests for directory mode, fmt command, metadata handling
  • Configuration validation tests
  • Linter passes with 0 issues

Summary by CodeRabbit

Release Notes

  • New Features

    • Packer now defaults to directory mode, automatically loading all *.pkr.hcl files from the component directory without requiring explicit template configuration.
    • Template parameter is now optional; use --template flag or settings.packer.template to override.
  • Documentation

    • Added comprehensive Packer troubleshooting guide.
    • Enhanced documentation with directory mode usage examples and best practices.
    • Added blog article explaining directory-based template support.
  • Tests

    • Added extensive integration and unit test coverage for Packer commands.

✏️ Tip: You can customize this high-level summary in your review settings.

@aknysh aknysh requested review from a team as code owners January 16, 2026 20:53
@aknysh aknysh added the minor New features that do not break anything label Jan 16, 2026
@github-actions github-actions bot added the size/xl Extra large size PR label Jan 16, 2026
@github-actions
Copy link
Copy Markdown

Warning

Release Documentation Required

This PR is labeled minor or major and requires documentation updates:

  • Changelog entry
  • Roadmap update - Update website/src/data/roadmap.js with the new milestone

Alternatively: If this change doesn't require release documentation, remove the minor or major label.

1 similar comment
@github-actions
Copy link
Copy Markdown

Warning

Release Documentation Required

This PR is labeled minor or major and requires documentation updates:

  • Changelog entry
  • Roadmap update - Update website/src/data/roadmap.js with the new milestone

Alternatively: If this change doesn't require release documentation, remove the minor or major label.

@mergify
Copy link
Copy Markdown

mergify bot commented Jan 16, 2026

Warning

This PR exceeds the recommended limit of 1,000 lines.

Large PRs are difficult to review and may be rejected due to their size.

Please verify that this PR does not address multiple issues.
Consider refactoring it into smaller, more focused PRs to facilitate a smoother review process.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 16, 2026

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@aknysh aknysh self-assigned this Jan 16, 2026
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 16, 2026

📝 Walkthrough

Walkthrough

This PR introduces directory-based template support for Packer in Atmos by defaulting the template parameter to "." when unspecified, enabling automatic loading of all *.pkr.hcl files from a component directory. Includes validation, configuration checks, comprehensive tests, and documentation.

Changes

Cohort / File(s) Summary
Core Packer Execution
internal/exec/packer.go, internal/exec/packer_output.go
Modified template handling to default to "." instead of failing; added early config validation via checkPackerConfig; updated error messages with better formatting; added deferred cleanup for variable files; simplified component permission checks
Packer Validation & Utilities
internal/exec/packer_utils.go, internal/exec/packer_utils_test.go
Added checkPackerConfig() helper to validate presence of components.packer.base_path; introduced ErrMissingPackerBasePath error in errors/errors.go
Unit & Integration Tests
cmd/packer_build_test.go, internal/exec/packer_test.go, internal/exec/packer_output_test.go
Added new integration tests for packer build command with various scenarios (invalid component, missing stack, directory template); expanded packer execution tests covering fmt, dry-run, directory mode, multi-file components, and component metadata; added output execution tests with config validation
Test Harness & CLI Tests
tests/cli_test.go
Added three new precondition checks: terraform, packer, helmfile
Test Fixtures - Components
tests/fixtures/scenarios/packer/components/packer/aws/multi-file/*
Added new multi-file packer component with variables.pkr.hcl, main.pkr.hcl, manifest.json, and README.md; minor formatting in bastion fixture
Test Fixtures - Stacks
tests/fixtures/scenarios/packer/stacks/catalog/aws/multi-file/defaults.yaml, tests/fixtures/scenarios/packer/stacks/deploy/nonprod.yaml, tests/fixtures/scenarios/packer/stacks/deploy/prod.yaml
Added multi-file component catalog defaults; new components (aws/multi-file, aws/bastion-abstract, aws/bastion-locked, aws/bastion-disabled) in nonprod/prod stacks
Integration Test Cases
tests/test-cases/packer.yaml
New test suite covering packer version, inspect, output, describe, and error scenarios for directory and multi-file modes
Documentation - Guides & Reference
website/docs/cli/commands/packer/packer-build.mdx, website/docs/cli/commands/packer/usage.mdx, website/docs/stacks/components/packer.mdx
Expanded --template flag documentation; added Directory Mode vs Single File Mode sections; clarified default behavior and precedence; added troubleshooting references
Documentation - PRD & Troubleshooting
docs/prd/packer-directory-template-support.md, website/docs/troubleshoot/packer.mdx
New PRD detailing directory-template support design; new comprehensive troubleshooting guide covering configuration, build, template, and output errors
Blog & Roadmap
website/blog/2026-01-16-packer-directory-based-templates.mdx, website/src/data/roadmap.js
Added blog article explaining directory mode vs single file mode with examples; added roadmap milestone entry for shipped feature
Website Infrastructure
website/plugins/fetch-latest-release/index.js
Added timeout handling (30-second AbortController), improved error messages for network issues, development mode placeholder behavior, restructured module export with loadContent and contentLoaded lifecycle methods

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PR #1774 — Both PRs modify packer command behavior, execution utilities, and test coverage; share similar patterns for config validation and packer execution paths.

Suggested reviewers

  • osterman
🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes an out-of-scope change: website/plugins/fetch-latest-release/index.js refactors the public module export signature and adds timeout handling, which is unrelated to Packer directory-based template support or issue #1937. Remove the fetch-latest-release plugin changes or move them to a separate PR focused on plugin improvements and timeout handling.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 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 change: introducing directory-based Packer template support with improvements. It's specific, clear, and reflects the primary objective from linked issue #1937.
Linked Issues check ✅ Passed The PR comprehensively addresses #1937 requirements: defaults template to '.' enabling multi-file *.pkr.hcl loading, adds configuration validation (ErrMissingPackerBasePath), fixes cleanup leaks, prevents build on abstract/locked components, and expands test coverage.

✏️ 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/update-packer-2

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 Jan 16, 2026

@coderabbitai full review please

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 16, 2026

@aknysh: I'll conduct a comprehensive review of all the changes in this PR, covering the Packer directory-based template support, configuration validation, bug fixes, component protection, documentation updates, and test improvements.


🧠 Learnings used
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.

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: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).

Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.

Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).
✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 16, 2026

@aknysh: I'll conduct a comprehensive review of all the changes in this PR, covering the Packer directory-based template support, configuration validation, bug fixes, component protection, documentation updates, and test improvements.


🧠 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: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.

Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).

Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).

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: 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: osterman
Repo: cloudposse/atmos PR: 768
File: internal/exec/vendor_utils.go:496-513
Timestamp: 2024-11-22T12:38:33.132Z
Learning: In the Atmos project, continue to flag path traversal issues in code reviews but acknowledge when they are expected and acceptable in specific cases.

Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.
✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 16, 2026

@aknysh: I'll conduct a comprehensive review of all the changes in this PR, covering the Packer directory-based template support, configuration validation, bug fixes, component protection, documentation updates, and test improvements.


🧠 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: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).

Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.

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: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).

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: 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: 768
File: internal/exec/vendor_utils.go:496-513
Timestamp: 2024-11-22T12:38:33.132Z
Learning: In the Atmos project, continue to flag path traversal issues in code reviews but acknowledge when they are expected and acceptable in specific cases.

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: 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: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.
✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 16, 2026

📝 Walkthrough

Walkthrough

This PR adds directory-based template support for Packer in Atmos. When no template is specified, Atmos defaults to the current directory (".") to enable Packer to load all *.pkr.hcl files from a component directory, fixing the issue where variables.pkr.hcl was not being utilized.

Changes

Cohort / File(s) Summary
Error Handling
errors/errors.go
Introduces new error sentinel ErrMissingPackerBasePath for missing Packer base path validation.
Core Packer Execution
internal/exec/packer.go, internal/exec/packer_utils.go
Adds pre-flight config validation via checkPackerConfig(). Defaults template to "." when empty. Defers cleanup of temporary variable files. Standardizes log messages.
Packer Output Handling
internal/exec/packer_output.go, internal/exec/packer_utils.go
Integrates config validation into output operations. Updates error message formatting for missing components and manifests.
Unit Tests - Core Logic
internal/exec/packer_test.go, internal/exec/packer_utils_test.go, internal/exec/packer_output_test.go
Adds tests for config validation, directory mode, multi-file components, component metadata (abstract/locked), and fmt operations. Introduces captureStdout helper.
CLI Command Tests
cmd/packer_build_test.go
Adds four test functions covering valid builds, invalid components, missing stacks, and directory template usage.
CLI Preconditions
tests/cli_test.go
Adds terraform, packer, and helmfile precondition checks.
Multi-File Component Fixtures
tests/fixtures/scenarios/packer/components/packer/aws/multi-file/*
Adds multi-file Packer component structure with variables.pkr.hcl, main.pkr.hcl, manifest.json, and README.md.
Stack Configuration Fixtures
tests/fixtures/scenarios/packer/stacks/catalog/aws/multi-file/defaults.yaml, tests/fixtures/scenarios/packer/stacks/deploy/{nonprod,prod}.yaml
Defines stack configurations for multi-file component, abstract component (aws/bastion-abstract), and locked component (aws/bastion-locked) test scenarios.
Integration Tests
tests/test-cases/packer.yaml
Adds comprehensive integration test suite covering version, inspect, output, describe, and error handling scenarios for directory and single-file modes.
Documentation
website/docs/cli/commands/packer/{packer-build,usage}.mdx, website/docs/stacks/components/packer.mdx
Updates --template flag descriptions and adds Directory Mode vs Single File Mode sections with examples and troubleshooting links.
Troubleshooting Guide
website/docs/cli/commands/packer/troubleshooting.mdx
New guide covering configuration errors, build errors, template errors, output errors, and debugging tips.
Blog Post
website/blog/2026-01-16-packer-directory-based-templates.mdx
Announces directory-based template support with rationale, examples, and backward compatibility notes.
Product Documentation
docs/prd/packer-directory-template-support.md
Product requirements document detailing behavioral changes, unit/integration tests, and fixtures.
Roadmap
website/src/data/roadmap.js
Adds "Packer directory-based templates" milestone entry with shipped status for q1-2026.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • osterman
  • nitrocode
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: Packer directory-based template support. It is concise, clear, and highlights the primary feature being introduced.
Linked Issues check ✅ Passed The PR fully addresses issue #1937 by enabling multi-file Packer configurations through directory-based template loading. When no template is specified, Atmos now defaults to '.' so Packer loads all *.pkr.hcl files from the component directory, resolving the variables.pkr.hcl utilization issue.
Out of Scope Changes check ✅ Passed All changes are directly related to directory-based Packer support or supporting infrastructure. Includes configuration validation, error handling, comprehensive tests, fixtures, and documentation. No unrelated modifications detected.

✏️ 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/update-packer-2

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: 5

🤖 Fix all issues with AI agents
In `@cmd/packer_build_test.go`:
- Around line 20-71: TestPackerBuildCmd (and
TestPackerBuildCmdWithDirectoryTemplate) only capture stdout and don't
initialize plugins, so stderr plugin errors like "Missing plugins… run packer
init" are missed; before calling Execute() run "packer init" for the same
workDir and skip the test if init fails, redirect/capture both stdout and stderr
(duplicate os.Stderr into the same pipe used for stdout or create a combined
reader) so plugin messages are visible, close the write end after both init and
build, read the combined output into output string, and explicitly check output
for missing-plugin phrases ("Missing plugins", "run packer init") and treat that
case as expected/skip rather than a test failure; update logic in
TestPackerBuildCmd and TestPackerBuildCmdWithDirectoryTemplate accordingly.

In `@internal/exec/packer_output_test.go`:
- Around line 72-85: The test writes YAML with a double-quoted base_path using
tempDir which on Windows contains backslashes that become invalid YAML escapes;
update the os.WriteFile call that writes the config (the fmt.Sprintf block
around base_path) inside packer_output_test.go to either wrap the inserted path
in single quotes or normalize the path (e.g., replace backslashes with forward
slashes) before formatting; ensure you update the variable used in the
fmt.Sprintf (tempDir) so the produced YAML is safe on Windows and the subsequent
parsing in the test succeeds.

In `@internal/exec/packer_test.go`:
- Around line 18-48: captureStdout leaves the global logger pointed at a closed
pipe and can leak file descriptors on panic; update captureStdout to save the
original logger writer (e.g. oldLog := log.Writer()) and restore it in a defer
alongside restoring os.Stdout, and close both pipe ends (w.Close() and
r.Close()) in that defer so the writer is closed even on panic; ensure you still
close w before copying from r when normal execution reaches the read, but rely
on the deferred closes for panic-safe cleanup so the function (and symbols
captureStdout, oldStdout, log.SetOutput, os.Pipe, r, w) always restores state
and frees FDs.
- Around line 230-258: The test TestExecutePacker_Fmt currently ignores the
returned error from ExecutePacker making it ineffective; update the test to
assert the call succeeds by replacing the unused assignment with an assertion
such as assert.NoError(t, err) after calling ExecutePacker(&info, &packerFlags)
(keep the function name ExecutePacker and test name TestExecutePacker_Fmt to
locate the change).

In `@tests/fixtures/scenarios/packer/components/packer/aws/multi-file/README.md`:
- Around line 7-34: In README.md update the top fenced example to include a
language tag (change ``` to ```text) and replace the two bare URLs under
"Related" with markdown links: change the GitHub Issue URL to
[cloudposse/atmos#1937](https://github.com/cloudposse/atmos/issues/1937) and the
Packer docs URL to [HCL
Templates](https://developer.hashicorp.com/packer/docs/templates/hcl_templates);
locate the fenced block and the Related section in aws/multi-file/README.md and
apply these exact substitutions.
🧹 Nitpick comments (2)
website/docs/cli/commands/packer/troubleshooting.mdx (1)

9-9: Unused import.

The Terminal component is imported but not used in this file. Consider removing it.

🧹 Suggested cleanup
 ---
 import Terminal from '@site/src/components/Terminal'
-
+

Or simply remove line 9 entirely if the Terminal component isn't needed.

docs/prd/packer-directory-template-support.md (1)

170-178: Add a language tag to the fenced test-output block (non-blocking).

markdownlint MD040 flags the unlabeled fence; consider text or console in a doc-only cleanup PR. Based on learnings, markdownlint cleanups in docs/prd/ should be handled in a dedicated follow-up.

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: 3

🤖 Fix all issues with AI agents
In `@internal/exec/packer_output_test.go`:
- Around line 72-85: The YAML config write in the os.WriteFile call uses tempDir
directly which on Windows contains backslashes that YAML treats as escape
sequences; change the value passed into fmt.Sprintf to filepath.ToSlash(tempDir)
(normalize tempDir to forward slashes) before embedding it into the YAML string,
and add the necessary import for "path/filepath" so the os.WriteFile(configPath,
[]byte(fmt.Sprintf(..., filepath.ToSlash(tempDir))), 0o644) uses the normalized
path.

In `@tests/fixtures/scenarios/packer/components/packer/aws/multi-file/README.md`:
- Around line 7-34: The README.md uses unmarked code fences and bare URLs which
trigger markdownlint (MD040/MD034); update the code fences to include a language
(e.g., change the top triple backticks to ```text and keep the bash block as
```bash) and replace bare URLs in the "Related" list with Markdown link syntax
(e.g., convert the plain https://... links to
[cloudposse/atmos#1937](https://github.com/cloudposse/atmos/issues/1937) and
[HCL
Templates](https://developer.hashicorp.com/packer/docs/templates/hcl_templates));
edit the README.md content around the directory tree code block, the bash
example block, and the Related list to apply these changes.

In `@website/docs/cli/commands/packer/troubleshooting.mdx`:
- Around line 1-279: The page titled "Packer Troubleshooting" is missing
required CLI docs structure; update the MDX by adding the required frontmatter
(title, sidebar_* fields as used elsewhere), an Intro section under the main
header, a Screengrab component usage, a Usage section showing command
invocation, an Arguments/Flags description using a <dl> block, and an Examples
section with one or more runnable examples (or alternatively move this content
out of the cli/commands tree into a general troubleshooting docs folder); ensure
the new sections use the same headings/structures as other files in cli/commands
so the docs build passes.
🧹 Nitpick comments (3)
cmd/packer_build_test.go (1)

30-32: os.Pipe() error is silently ignored.

If pipe creation fails, subsequent operations will have undefined behavior. Consider checking the error.

Suggested fix
 	oldStd := os.Stdout
 	r, w, _ := os.Pipe()
+	if r == nil || w == nil {
+		t.Fatal("failed to create pipe for stdout capture")
+	}
 	os.Stdout = w
internal/exec/packer_test.go (2)

253-258: Consider verifying command execution succeeded.

The test currently ignores the error entirely. While the comment explains the intent, you could at least log the error for debugging purposes when it does occur.

Suggested improvement
 	// packer fmt -check returns 0 if files are formatted, non-zero otherwise.
 	// We just verify the command executes without errors.
 	err := ExecutePacker(&info, &packerFlags)
-	// The test passes regardless of fmt exit code since we're testing command execution.
-	_ = err
+	// Log the error for debugging, but don't fail - we're testing command execution.
+	if err != nil {
+		t.Logf("packer fmt returned: %v (this may be expected)", err)
+	}

774-787: Minor: errorSubstring field unused when shouldError: false.

For test cases where shouldError: false, the errorSubstring field is set but only used in the NotContains assertion (line 833). The current value works, but it's semantically clearer to leave it empty for non-error cases or rename the field to clarify its dual purpose.

aknysh and others added 3 commits January 16, 2026 16:49
- Remove unused Terminal import from troubleshooting.mdx
- Add language tag to PRD code block
- Improve packer build tests (run init first, capture stderr, skip if plugins missing)
- Fix Windows path quoting in packer_output_test.go (use single quotes)
- Improve captureStdout helper (restore logger output, close pipes properly, handle panics)
- Add fallback for network timeout in fetch-latest-release plugin
- Fix broken documentation link (packer-build → build)
- Refactor nested if blocks to reduce complexity (nestif linter)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 16, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Jan 16, 2026

Codecov Report

❌ Patch coverage is 82.60870% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.75%. Comparing base (bda1aab) to head (2dd84a8).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
internal/exec/packer.go 84.61% 1 Missing and 1 partial ⚠️
internal/exec/packer_output.go 50.00% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1982      +/-   ##
==========================================
+ Coverage   74.72%   74.75%   +0.03%     
==========================================
  Files         777      777              
  Lines       71171    71176       +5     
==========================================
+ Hits        53180    53210      +30     
+ Misses      14525    14507      -18     
+ Partials     3466     3459       -7     
Flag Coverage Δ
unittests 74.75% <82.60%> (+0.03%) ⬆️

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

Files with missing lines Coverage Δ
errors/errors.go 100.00% <ø> (ø)
internal/exec/packer_utils.go 100.00% <100.00%> (+9.52%) ⬆️
internal/exec/packer.go 63.26% <84.61%> (+9.26%) ⬆️
internal/exec/packer_output.go 48.97% <50.00%> (+8.55%) ⬆️

... and 5 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[bot]
coderabbitai bot previously approved these changes Jan 17, 2026
coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 17, 2026
coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 17, 2026
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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/exec/packer.go (1)

47-61: Move config validation below the version guard to allow atmos packer version without base_path.

checkPackerConfig requires Components.Packer.BasePath and runs before the version subcommand check. This means atmos packer version fails if base_path isn't configured, even though the version command doesn't need component or stack information. Terraform handles this by deferring deeper validation until after the version check. Move the validation below line 61 to match that pattern.

Proposed adjustment
-	// Validate packer configuration.
-	if err := checkPackerConfig(&atmosConfig); err != nil {
-		return err
-	}
-
 	// Add the `command` from `components.packer.command` from `atmos.yaml`.
 	if info.Command == "" {
 		if atmosConfig.Components.Packer.Command != "" {
 			info.Command = atmosConfig.Components.Packer.Command
 		} else {
 			info.Command = cfg.PackerComponentType
 		}
 	}
 
 	if info.SubCommand == "version" {
 		return ExecuteShellCommand(
 			atmosConfig,
 			info.Command,
 			[]string{info.SubCommand},
 			"",
 			nil,
 			false,
 			info.RedirectStdErr,
 		)
 	}
+
+	// Validate packer configuration.
+	if err := checkPackerConfig(&atmosConfig); err != nil {
+		return err
+	}

@aknysh aknysh merged commit 994635c into main Jan 17, 2026
57 checks passed
@aknysh aknysh deleted the aknysh/update-packer-2 branch January 17, 2026 16:29
@github-actions
Copy link
Copy Markdown

These changes were released in v1.204.1-rc.2.

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

Labels

minor New features that do not break anything size/xl Extra large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Packer variables.pkr.hcl not utilized

2 participants