Atmos Core: Component Type Development
SkillCloud & infraThis skill gives your AI a contributor guide for Atmos, the open source tool at github.com/cloudposse/atmos, focused on adding or changing component types in its Go codebase. Once added, your AI can extend Atmos with new component types such as terraform, helmfile, packer, ansible, or container, covering everything from the internal registry and commands to the schema and tests.
Available today. Use it from your connected AI after setup.
No other account needed.
Tell your AI which component type you want to add or modify in Atmos, and it will follow the guide step by step through the registry, commands, schema, and tests.
Then ask your AI: use the Atmos Core: Component Type Development skill
What your AI can do with it
- Add a new component type to Atmos, such as terraform, helmfile, packer, ansible, or container
- Register component types in the internal registry and provider
- Add command-line commands for a component type
- Update which component types Atmos can list and describe
- Implement inheritance and deep-merge behavior for custom components
- Update the schema and write tests for component type changes
What this skill tells your AI
The instructions your AI receives, as published by cloudposse/atmos in .claude/skills/atmos-core-component-development/SKILL.md and read by ahel’s review.
Use this skill when developing Atmos itself — adding or modifying a component type (kind) in the
Go codebase. This is contributor/core guidance, distinct from the user-facing atmos-components skill
(which documents authoring terraform/helmfile/container components in stacks).
Start from docs/developing-component-plugins.md (the component-plugin development guide). The notes
below capture the non-obvious wiring learned while adding the container component type.
The component provider (pkg/component)
A component type is a ComponentProvider (pkg/component/provider.go) registered via init() with
component.Register(...) (pkg/component/registry.go). Reference impls:
pkg/component/ansible/— typed-config built-in style.pkg/component/mock/,pkg/component/custom/— thePlugins-map plugin style.pkg/component/container/— provider +cmd/lifecycle split.
Layout per the guide: config.go (typed Config + parseConfig), <type>.go (provider + init),
executor.go (verb implementations), <type>_test.go (>90% coverage). Wire a blank import into
cmd/root.go so init() runs.
Reusable error sentinels live in errors/errors.go: ErrComponentExecutionFailed,
ErrComponentConfigInvalid, ErrComponentValidationFailed, ErrComponentTypeEmpty.
First-class component config (NOT vars)
Per-instance config that is not arbitrary template data must be first-class top-level sections
(siblings of metadata/env/composition), NOT nested under vars. For container, the config reuses
the workflow container-step structs (schema.ContainerBuildStep/ContainerRunStep/ContainerMount/
ContainerPort in pkg/schema/workflow.go) for consistency. Decode a YAML-derived map[string]any
into those structs with mapstructure using TagName: "yaml" so snake_case keys (build_args,
read_only) map.
The CLI command group (cmd/)
Mirror cmd/ansible/: a base cobra.Command registered through the command registry
(cmd/internal CommandProvider), persistent flags via flags.NewStandardParser() (NEVER
viper.BindEnv/BindPFlag), one thin file per verb dispatching to
component.MustGetProvider(<type>).Execute(&component.ExecutionContext{...}). Wire a blank import into
cmd/root.go.
CRITICAL: the describe/list type whitelist
A new top-level components.<type> is dropped (stack renders {}, "component not found") unless
the type is added to several hardcoded lists. Grep AnsibleSectionName / "ansible" across
internal/exec + pkg/list/extract and mirror every hit:
pkg/config/const.go—XComponentType/XSectionNameconsts.internal/exec/describe_stacks_component_processor.go— thetypeEntrieslist ANDcomponentsSectionHasComponents.internal/exec/describe_stacks.go—getComponentBasePathswitch.internal/exec/describe_component.go— thedetectComponentTypeauto-detect order (a loop over[terraform, helmfile, packer, ansible, container]); a type missing here makesatmos describe component <name>fail even when the lifecycle works.pkg/list/extract/components.go— THREE hardcoded type lists (per-stackextractComponentType×2, uniqueextractUniqueComponentType).
Verify with atmos describe stacks (stack with only the new type must be non-empty) and
atmos describe component <name> -s <stack>.
Inheritance & deep-merge for custom types
Built-in types (terraform/helmfile/packer/ansible) get full inheritance via the processComponent
pipeline. Other types ride the custom-component fallback in
internal/exec/stack_processor_process_stacks.go. That fallback now resolves metadata.inherits and
generic-deep-merges all top-level keys (resolveCustomComponentInheritance), so custom types honor
catalog/abstract defaults. Gotchas:
- Strip
metadata.type/inherits/componentfrom a base before merging, or an abstract base poisons the concrete component (sanitizeBaseForInheritance). - Reject
metadata.type: abstractfor execution and filter it from listings. - Use the native merge (
pkg/merge) — it already incorporates the slice-truncation and permissive-type-mismatch fixes indocs/fixes/2026-03-19-*anddocs/fixes/2026-03-24-*. - Component-level config sections (vars/settings/env/hooks/secrets/...) that need per-section
inheritance still require the section whitelist plumbing (see
docs/errors.md/ the merge helpers).
Schema, docs, tests
- JSON schema:
pkg/datafetcher/schema/atmos/manifest/1.0.json— add<type>_components+<type>_component_manifestdefinitions and thecomponents.<type>property. - Docs:
website/docs/components/components-overview.mdx(Component Types table + directory diagram),website/docs/components/<type>.mdx, andwebsite/docs/cli/commands/<type>/usage.mdx. - Tests: provider unit tests with a mockgen
Runtime/dependency,cmd.NewTestKitfor the command, inheritance + abstract + graceful-empty cases. Regenerate affected--helpgolden snapshots with-regenerate-snapshots(never hand-edit). - Gate:
./custom-gcl run --new-from-rev=origin/<base> ./pkg/component/<type>/... ./internal/exec/....
Signals
- GitHub stars
- 1k
- Forks
- 175
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
atmos-core-component-development- Source
- github.com/cloudposse/atmos