component
The component field lets a custom command define its own component type beyond the built-in terraform, helmfile, packer, and ansible types. This brings Atmos's stack configuration system to any tool — AWS CDK, CloudFormation, Pulumi, Bicep, database migrations, and more.
Custom Component Types
When you define a component: section in a custom command with a type, Atmos:
- Registers the custom component type in the component registry
- Looks up component configuration from
components.<type>.<component>in your stack manifests - Makes the component configuration available via
{{ .Component.* }}template variables
Typed Arguments and Flags
To tell Atmos which argument or flag provides the component name and stack name, use semantic types:
- Arguments: Set
type: componentortype: stackin the argument definition - Flags: Set
semantic_type: componentorsemantic_type: stackin the flag definition
Note: For flags, we use semantic_type because type is already used to specify the data type (string, bool).
Example: Script Runner
Here's a complete example of a custom command that runs script components:
atmos.yaml:
commands:
- name: script
description: "Run script components"
arguments:
- name: component
description: "Component name"
type: component # This argument provides the component name
required: true
flags:
- name: stack
shorthand: s
description: "Stack name"
semantic_type: stack # This flag provides the stack name
required: true
component:
type: script # Define the custom component type
base_path: components/script # Optional: defaults to components/<type>
steps:
- 'echo "Running {{ .Component.component }} in {{ .Component.atmos_stack }}"'
- 'echo "App: {{ .Component.vars.app_name }}"'
- 'echo "Version: {{ .Component.vars.version }}"'
- 'cd {{ .Component.vars.script_dir }} && ./deploy.sh'
stacks/catalog/script/deploy-app.yaml:
components:
script: # Matches component.type in the command
deploy-app: # Component name
vars:
app_name: "myapp"
version: "1.0.0"
script_dir: "${atmos.base_path}/components/script/deploy-app"
stacks/deploy/dev.yaml:
import:
- catalog/script/deploy-app
vars:
stage: dev
components:
script:
deploy-app:
vars:
version: "1.0.0-dev" # Override for dev environment
Usage:
atmos script deploy-app -s dev
# Output:
# Running deploy-app in dev
# App: myapp
# Version: 1.0.0-dev
# (runs deploy.sh)
Available Template Variables
When using custom component types, the {{ .Component }} object contains:
| Variable | Description |
|---|---|
{{ .Component.component }} | Component name |
{{ .Component.component_type }} | Component type (e.g., "script") |
{{ .Component.atmos_stack }} | Stack name |
{{ .Component.vars.* }} | Variables defined in the component |
{{ .Component.settings.* }} | Settings defined in the component |
{{ .Component.env.* }} | Environment variables defined in the component |
Passing Secrets to Custom Components
A custom component's env section is exported as real environment variables to every step,
just like the built-in terraform/helmfile/packer/ansible component types. This makes secrets
easy to pass securely: declare them under secrets.vars,
reference them with !secret in the component env section, and read them
in your steps (or the scripts they invoke) as ordinary environment variables.
Reference secrets as environment variables ($DB_PASSWORD), not by inlining the template value
(echo {{ .Component.env.DB_PASSWORD }}). An inlined value lands in shell history and process
arguments. Step output is masked, but that is defense‑in‑depth, not the primary mitigation.
See Passing Secrets for the full list of supported secret backends (AWS SSM/Secrets Manager, Vault, Azure Key Vault, GCP Secret Manager, 1Password, SOPS, and more).
Configuration Options
The component: section supports:
| Option | Description |
|---|---|
type | Required. The component type name (e.g., "script", "ansible", "manifest") |
base_path | Optional. Base directory for components of this type. Defaults to components/<type> |
Comparison with component_config
The component: section differs from the legacy component_config: in several ways:
| Feature | component: (new) | component_config: (legacy) |
|---|---|---|
| Component type | Custom types | Terraform only |
| Component/stack source | Inferred from typed args/flags | Explicit templates |
| Template variable | {{ .Component.* }} | {{ .ComponentConfig.* }} |
| Stack location | components.<type>.<component> | components.terraform.<component> |
Use component: for new custom commands. The component_config: approach continues to work for backward compatibility but is limited to Terraform components.
Example: Ansible Playbook Runner
commands:
- name: ansible
description: "Run Ansible playbooks"
arguments:
- name: component
type: component
required: true
flags:
- name: stack
shorthand: s
semantic_type: stack
required: true
- name: check
description: "Run in check mode (dry-run)"
type: bool
component:
type: ansible
base_path: components/ansible
steps:
- |
cd {{ .Component.vars.playbook_dir }}
ansible-playbook {{ .Component.vars.playbook }} \
-i {{ .Component.vars.inventory }} \
--extra-vars "env={{ .Component.vars.environment }}" \
{{ if .Flags.check }}--check{{ end }}
Example: Kubernetes Manifest Deployer
commands:
- name: manifest
description: "Apply Kubernetes manifests"
arguments:
- name: component
type: component
required: true
flags:
- name: stack
shorthand: s
semantic_type: stack
required: true
- name: dry-run
type: bool
component:
type: manifest
steps:
- |
kubectl apply \
--context {{ .Component.vars.cluster_context }} \
--namespace {{ .Component.vars.namespace }} \
{{ if index .Flags "dry-run" }}--dry-run=client{{ end }} \
-f {{ .Component.vars.manifest_path }}