Using Custom Component Types
Beyond the native component types, Atmos lets you define custom component types so you can manage any tool—AWS CDK, Pulumi, Bicep, database migrations, and more—with the same stack-based configuration system used for Terraform, Helmfile, and Packer.
Use the built-in CloudFormation component and CloudFormation commands to deploy templates. The component type is currently experimental.
Custom component types are defined through custom commands. Unlike the native types, which ship with built-in orchestration, a custom type is one you wire up yourself: you declare the type on a custom command and supply the execution steps, while Atmos handles stack resolution, inheritance, and configuration merging exactly as it does for native components.
How It Works
Define a component.type on a custom command and tell Atmos which argument provides the component name and which provides the stack name. Atmos then looks up components.<type>.<name> from your stack manifests and exposes the fully resolved configuration via {{ .Component.* }}.
# atmos.yaml
commands:
- name: example
description: "Run example components"
arguments:
- name: component
provides: component # Provides the component name
required: true
flags:
- name: stack
shorthand: s
provides: stack # Provides the stack name
required: true
component:
type: example # Your custom component type
steps:
- 'echo "App: {{ .Component.vars.app_name }}"'
- 'echo "Version: {{ .Component.vars.version }}"'
Configure the component in stack manifests just like a native type—with full imports and inheritance:
# stacks/deploy/dev.yaml
components:
example: # Matches component.type
deploy-app:
vars:
app_name: "myapp"
version: "1.0.0"
Run it:
atmos example deploy-app --stack dev
# App: myapp
# Version: 1.0.0
Global vars, settings, and env are merged automatically, and a component's env section is exported as real environment variables—making it straightforward to pass secrets securely.
Implement components with Starlark
Use Atmos scripting, based on Starlark, to implement custom components
with validation, conditions, loops, and reusable functions. The interpreter ships
with Atmos. Replace the command's shell steps with a type: script step:
steps:
- type: script
interpreter: starlark
script: |
component = ctx.component
if not component.vars.get("app_name"):
fail("app_name is required")
print("App: {}".format(component.vars["app_name"]))
print("Version: {}".format(component.vars["version"]))
ctx.component provides the resolved
component configuration. Use its exec() method
to call tools from the component directory, and move shared logic into .star
files with !include. Atmos supports
tests for these functions and commands.
Here, example names the custom command and component type; script names the
step type that runs the Starlark implementation.
Native vs. Custom
| Aspect | Native types (Terraform/Helmfile/Packer/Ansible) | Custom types |
|---|---|---|
| Orchestration | Built into Atmos | You supply the steps |
| Definition | Always available | Defined via a custom command |
| Stack configuration | components.<type>.<name> | components.<type>.<name> |
| Configuration access | Native flags/varfiles | {{ .Component.* }} templates or ctx.component in Starlark |
Try It
Explore a complete, working example that defines a custom example component type and configures it through stacks.
Related
- Custom Component Types — Full reference, including template variables and configuration options
- Custom Commands — How to define custom commands
- Introducing Custom Component Types — Background and real-world examples