feat: add atmos ansible component support#2042
Conversation
Introduce first-class Ansible component support in Atmos. This includes new CLI commands (`atmos ansible`, `ansible playbook`, `ansible version`), schema and config updates, error handling, and stack processing logic. Adds Ansible to component path resolution, stack merging, and listing.
Refactored Ansible CLI support into a dedicated cmd/ansible package, splitting playbook and version commands into their own files. Added comprehensive flag handling, shell completion, and extensive tests for flags, command structure, and integration. Removed legacy ansible command files and updated root command registration.
- Implemented Ansible component support in Atmos, including path-based component resolution and variable file generation. - Added helper for extracting the generate section from component config. - Provided comprehensive documentation for Ansible commands, usage, flags, and stack configuration in the website docs. - Included tests for generate section extraction logic.
|
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. |
|
Warning Release Documentation RequiredThis PR is labeled
|
Dependency Review✅ No vulnerabilities or license issues found.Scanned FilesNone |
|
Warning Release Documentation RequiredThis PR is labeled
|
1 similar comment
|
Warning Release Documentation RequiredThis PR is labeled
|
|
Warning Release Documentation RequiredThis PR is labeled
|
|
Warning Release Documentation RequiredThis PR is labeled
|
|
Warning Release Documentation RequiredThis PR is labeled
|
|
Warning Release Documentation RequiredThis PR is labeled
|
Introduce Ansible as a first-class component type in Atmos, enabling unified orchestration of infrastructure provisioning and configuration management from the same stack manifests. Update documentation and roadmap to reflect new Ansible commands, stack integration, and workflow enhancements.
|
Warning Release Documentation RequiredThis PR is labeled
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds first-class Ansible support: new CLI commands (ansible/playbook/version) with flags and completions, an Ansible ComponentProvider and executor (varfile generation, env, deps, command assembly), schema/config/const updates, stack-processing plumbing for Ansible paths, exported file-generation helper, tests, docs, and snapshots. Changes
Sequence Diagram(s)sequenceDiagram
participant User as User/CLI
participant Cmd as "ansible Cmd"
participant Registry as "Component Registry"
participant Provider as "Ansible Provider"
participant Executor as "Ansible Executor"
participant AnsibleBin as "ansible / ansible-playbook"
User->>Cmd: run "atmos ansible playbook <component> --stack=... --playbook ... -- ..."
Cmd->>Cmd: initConfigAndStacksInfo()
Cmd->>Cmd: getAnsibleFlags()
Cmd->>Registry: lookup provider "ansible"
alt provider found
Cmd->>Provider: Execute(ExecutionContext)
Provider->>Provider: validate component & settings
Provider->>Provider: maybeAutoGenerateFiles / resolveComponentPath
Provider->>Provider: prepare env & varfile
Provider->>Executor: buildCommandArgs & exec
else provider not found
Cmd->>Executor: ExecutePlaybook(info, flags) (fallback)
end
Executor->>AnsibleBin: run command (env + args + extra-vars `@varfile`)
AnsibleBin-->>Executor: result/exit
Executor->>Provider: cleanup varfile
Provider-->>Cmd: propagate result/error
Cmd-->>User: exit code / output
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. 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 |
📝 WalkthroughWalkthroughIntroduces Ansible as a first-class Atmos component with dedicated CLI commands (playbook, version subcommands), full stack processor integration supporting variable inheritance, configuration management, and automatic file generation capabilities. Changes
Sequence Diagram(s)sequenceDiagram
participant User as User/CLI
participant Cmd as Ansible Command
participant StackProc as Stack Processor
participant ExecEngine as Execution Engine
participant FileGen as File Generation
participant ShellExec as Shell Executor
User->>Cmd: atmos ansible playbook -s stack -p my-playbook
Cmd->>Cmd: Parse flags & args
Cmd->>StackProc: initConfigAndStacksInfo
StackProc->>StackProc: Load stack config
StackProc->>StackProc: Resolve component settings
StackProc-->>Cmd: ConfigAndStacksInfo
Cmd->>Cmd: getAnsibleFlags
Cmd->>ExecEngine: ExecuteAnsible
ExecEngine->>ExecEngine: checkAnsibleConfig
ExecEngine->>ExecEngine: Validate component exists/enabled
ExecEngine->>ExecEngine: Resolve playbook (settings vs flags)
ExecEngine->>FileGen: Generate component varfile
FileGen->>FileGen: Create vars from component settings
FileGen-->>ExecEngine: varfile path
ExecEngine->>ExecEngine: Prepare environment (ATMOS_CLI_CONFIG_PATH, etc.)
ExecEngine->>ShellExec: ExecuteShellCommand
ShellExec->>ShellExec: ansible-playbook --extra-vars `@varfile`
ShellExec-->>ExecEngine: exit code
ExecEngine->>FileGen: Cleanup varfile
ExecEngine-->>Cmd: result/error
Cmd-->>User: output
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 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: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
internal/exec/utils.go (1)
309-316: IncludeAnsibleDirAbsolutePathin the FindStacksMap cache key.Stack processing now depends on this path, but the cache key omits it, so configs that only differ by Ansible base path can collide in a single process.
Proposed fix
keyBuilder.WriteString(atmosConfig.PackerDirAbsolutePath) keyBuilder.WriteString(cacheKeyDelimiter) + keyBuilder.WriteString(atmosConfig.AnsibleDirAbsolutePath) + keyBuilder.WriteString(cacheKeyDelimiter) keyBuilder.WriteString(fmt.Sprintf("%v", ignoreMissingFiles)) keyBuilder.WriteString(cacheKeyDelimiter)internal/exec/stack_processor_process_stacks_test.go (1)
306-313: Usefilepath.Joinfor test paths to keep Windows compatibility.The new path literal extends the hardcoded forward-slash pattern; prefer
filepath.Joinfor cross-platform paths.As per coding guidelines: NEVER use hardcoded forward slashes in paths - ALWAYS use filepath.Join() with separate arguments.Proposed fix
import ( + "path/filepath" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ t.Run(tt.name, func(t *testing.T) { _, err := ProcessStackConfig( atmosConfig, - "/test/stacks", - "/test/terraform", - "/test/helmfile", - "/test/packer", - "/test/ansible", + filepath.Join(string(filepath.Separator), "test", "stacks"), + filepath.Join(string(filepath.Separator), "test", "terraform"), + filepath.Join(string(filepath.Separator), "test", "helmfile"), + filepath.Join(string(filepath.Separator), "test", "packer"), + filepath.Join(string(filepath.Separator), "test", "ansible"), "test-stack.yaml", tt.config, false,
🤖 Fix all issues with AI agents
In `@cmd/ansible/ansible.go`:
- Around line 112-169: The buildConfigAndStacksInfo/initConfigAndStacksInfo flow
currently only reads the stack flag; update buildConfigAndStacksInfo (or call
into it from initConfigAndStacksInfo) to call flags.ParseGlobalFlags(cmd, v) and
copy the parsed values into the returned schema.ConfigAndStacksInfo fields
AtmosBasePath, AtmosConfigFilesFromArg, AtmosConfigDirsFromArg, and
ProfilesFromArg before the struct is used by InitCliConfig in ExecuteAnsible;
ensure you reference and populate these fields on the ConfigAndStacksInfo
instance created in buildConfigAndStacksInfo (and keep stack extraction) so
global flags --base-path, --config, --config-path and --profile are honored.
In `@internal/exec/ansible.go`:
- Around line 292-345: Replace passing the relative varFile to the playbook
command with the absolute varFilePath so the playbook can find the extra-vars
file when the working directory changes; in the ansible runner code where
info.SubCommand == "playbook" (the block that appends "--extra-vars", "@" +
varFile and later sets info.Command to "ansible-playbook"), use varFilePath (the
absolute path created earlier) instead of varFile when appending the
"--extra-vars" argument so ExecuteShellCommand is invoked with the correct
absolute file reference.
In `@pkg/list/list_components.go`:
- Around line 39-42: Add a trailing period to the comment above the ansible
extraction block: change the comment "Extract ansible components" to end with a
period so it reads "Extract ansible components." This affects the comment
immediately preceding the ansibleComponents type-assertion and append using
lo.Keys in the block that references componentsMap, ansibleComponents, and
allComponents.
In `@pkg/schema/schema.go`:
- Around line 477-484: Add a proper Go doc comment immediately above the
exported type Ansible that briefly describes what the struct represents and its
purpose (e.g., configuration for Ansible integration including BasePath,
Command, and AutoGenerateFiles behavior), following Go conventions: start the
comment with "Ansible" and keep it a single or couple of sentences so linters
accept it; place it directly above the type Ansible declaration to document the
exported type.
In `@website/blog/2026-01-29-ansible-component-support.mdx`:
- Around line 16-20: Change the phrase "Full stack processor support" to the
hyphenated compound adjective "Full‑stack processor support" in the blog bullets
(the line that currently reads "Full stack processor support including
inheritance, vars, env, settings, and auth sections") so the compound modifier
before "processor" is correctly hyphenated for readability.
In `@website/docs/cli/commands/ansible/ansible-version.mdx`:
- Around line 8-28: Add the missing Screengrab and Arguments/Flags sections to
this new CLI doc: update website/docs/cli/commands/ansible/ansible-version.mdx
to include a Screengrab (e.g., a short paragraph and an image/embed beneath the
Intro explaining expected output of `atmos ansible version`) and an
Arguments/Flags section using a <dl> list that documents any flags/options for
the `ansible version` command (even if none, include a note like "This command
accepts no flags" in a <dl>), keeping the existing Intro and Usage text and
preserving the `ansible version` command reference so reviewers can locate the
change.
🧹 Nitpick comments (3)
cmd/ansible/playbook.go (1)
30-39: Consider adding performance tracking.Per coding guidelines, public functions should include
defer perf.Track(...)(). Since this delegates toExecuteAnsible, it may be intentionally omitted, but worth considering for consistency.💡 Optional: Add perf tracking
func runPlaybook(cmd *cobra.Command, args []string) error { + defer perf.Track(nil, "ansible.runPlaybook")() + // Initialize config and stacks info. info := initConfigAndStacksInfo(cmd, "playbook", args)You'd need to add the perf import:
"github.com/cloudposse/atmos/pkg/perf"website/docs/cli/commands/ansible/usage.mdx (1)
1-17: Consider adding a Screengrab component.The documentation structure is solid. Per coding guidelines for CLI command docs, a Screengrab component showing the help output would complete the standard template. Not blocking, but worth adding for consistency.
internal/exec/ansible_test.go (1)
198-236: Table-driven test looks good, but note the slash-in-filename case.Line 217-218 tests a component name with
/(database/postgres), producing a filename with an embedded slash. This tests current behavior accurately, but filenames with/may cause issues on some filesystems. IfComponentshouldn't contain path separators, consider adding validation in the implementation.
|
💥 This pull request now has conflicts. Could you fix it @RoseSecurity? 🙏 |
|
@osterman Just resolved the merge conflicts |
|
@osterman Anything else needed for this? |
|
💥 This pull request now has conflicts. Could you fix it @RoseSecurity? 🙏 |
|
These changes were released in v1.206.3-rc.1. |
|
These changes were released in v1.207.0. |
|
These changes were released in v1.208.0-rc.0. |
|
These changes were released in v1.208.0-test.15. |
what
atmos ansible playbookcommand to execute Ansible playbooks with stack-based configurationatmos ansible versioncommand to display Ansible version information--extra-vars @<varfile>--separatoranforansible,pbforplaybookwhy
usage
Configuration
Add to
atmos.yaml:Stack Manifest
Define Ansible components in stack manifests:
Commands
Environment Variables
references
Summary by CodeRabbit
New Features
Documentation
Tests
Chores