Skip to main content

Component Dependencies

The dependencies.components section defines relationships between components, ensuring they are deployed in the correct order. Use it to declare which components must be applied before others.

Use Cases

  • Execution Order: Ensure VPC is created before subnets
  • CI/CD Orchestration: Spacelift and other integrations use dependencies to order stack runs
  • Impact Analysis: The atmos describe affected command uses dependencies to find impacted components
  • File/Folder Watching: Trigger component redeployment when external files change

Configuration

The dependencies.components section is a list of dependency objects.

Schema

component (optional)
The component instance name as defined in the stack (e.g., vpc, subnet, tgw/hub). This is the name under components.<kind>.<name>, not the Terraform module path. Required for component dependencies.
stack (optional)
The Atmos stack name where the component is provisioned (e.g., tenant1-ue2-prod). If omitted, the component is assumed to be in the same stack. Use templates to construct stack names dynamically.
kind (optional)
The dependency type: terraform, helmfile, packer, file, folder, or a registered plugin type. Defaults to the declaring component's type for component dependencies. Use file or folder for path-based dependencies.
path (optional)
The file or folder path for path-based dependencies. Required when kind is file or folder. Changes to files at this path mark the component as affected.
info

For component dependencies, component is required. For path dependencies (kind: file or kind: folder), path is required.

Examples

Same-Stack Dependency

The simplest case: a component depends on another component in the same stack.

stacks/catalog/network.yaml

components:
terraform:
vpc:
vars:
cidr_block: "10.0.0.0/16"

subnet:
dependencies:
components:
- component: vpc
vars:
vpc_id: !terraform.output vpc.vpc_id

Cross-Stack Dependencies

Use the stack field or templates to depend on components in different stacks.

stacks/orgs/acme/plat/dev/us-east-1.yaml

vars:
tenant: acme
environment: ue1
stage: dev

components:
terraform:
app:
dependencies:
components:
# Depend on vpc in the same stack (no stack field needed)
- component: vpc

# Depend on shared-services in a specific stack
- component: shared-services
stack: acme-ue1-network

# Depend on rds in prod using a template
- component: rds
stack: "{{ .vars.tenant }}-{{ .vars.environment }}-prod"

# Depend on tgw/hub in a different region using a template
- component: tgw/hub
stack: "{{ .vars.tenant }}-uw2-{{ .vars.stage }}"

File and Folder Dependencies

Trigger describe affected when external files or folders change using kind and path.

stacks/catalog/lambda.yaml

components:
terraform:
lambda-function:
dependencies:
components:
# Re-deploy when the Lambda source code changes
- kind: folder
path: "src/lambda/my-function"

# Re-deploy when a specific config file changes
- kind: file
path: "configs/lambda-settings.json"

# Also depend on the vpc component
- component: vpc

Cross-Type Dependencies

Depend on components of a different type using the kind field.

stacks/catalog/app.yaml

components:
terraform:
app:
dependencies:
components:
# Terraform component (default kind for terraform components)
- component: vpc

# Helmfile component in a different stack
- component: nginx-ingress
kind: helmfile
stack: platform-stack

# Packer component
- component: base-ami
kind: packer

Merge Behavior

dependencies.components uses append merge behavior: child stacks add their dependencies to parent dependencies.

stacks/catalog/base.yaml

# Parent stack defines base dependencies
dependencies:
components:
- component: account-settings

stacks/orgs/acme/plat/prod/us-east-1.yaml

import:
- catalog/base

components:
terraform:
vpc:
dependencies:
components:
# This is APPENDED to the parent's dependencies
- component: network-baseline

# Result: vpc depends on both account-settings AND network-baseline

Integration with atmos describe affected

The dependencies.components section is used by atmos describe affected to determine which components are impacted by changes.

How It Works

When you run atmos describe affected:

  1. Atmos compares the current branch to the target branch (e.g., main)
  2. It identifies changed files (stack configs, component code)
  3. It checks dependencies.components for file/folder dependencies
  4. Components with changed dependencies are marked as "affected"

Example: File Dependency

stacks/catalog/lambda.yaml

components:
terraform:
my-lambda:
dependencies:
components:
- kind: folder
path: "src/lambda/handler"
# If src/lambda/handler/index.js changed:
atmos describe affected --ref refs/heads/main

# Output includes my-lambda because its dependency folder changed

Example: Component Dependency

If component A depends on component B, and component B is affected by changes, component A is also marked as affected (transitive dependency).

Viewing Dependencies

List Dependents

Find all components that depend on a specific component:

atmos describe dependents vpc -s tenant1-ue1-dev --pager off

> atmos describe dependents vpc -s tenant1-ue1-dev --pager off
[
{
"component": "subnet",
"component_type": "terraform",
"stack": "tenant1-ue1-dev",
"stack_slug": "tenant1-ue1-dev-subnet"
},
{
"component": "security-group",
"component_type": "terraform",
"stack": "tenant1-ue1-dev",
"stack_slug": "tenant1-ue1-dev-security-group"
}
]

List Affected Components

Find all components affected by changes in a branch:

atmos describe affected --ref refs/heads/main

> atmos describe affected --ref refs/heads/main
[
{
"component": "vpc",
"stack": "tenant1-ue1-dev",
"affected": "component"
},
{
"component": "subnet",
"stack": "tenant1-ue1-dev",
"affected": "folder"
}
]

Best Practices

  1. Declare All Dependencies - Be explicit about dependencies, even if the order seems obvious
  2. Avoid Circular Dependencies - Component A cannot depend on B if B depends on A
  3. Use Templates for Cross-Stack - Use {{ .vars.tenant }}-{{ .vars.environment }}-{{ .vars.stage }} instead of hardcoded stack names
  4. Combine with YAML Functions - Use !terraform.output to pass data between dependent components
  5. Test with describe affected - Verify your dependencies work correctly in CI/CD

Migration from settings.depends_on

If you're using the legacy settings.depends_on format:

Old format (deprecated)

settings:
depends_on:
1:
component: vpc
2:
component: rds
stage: prod

New format (recommended)

dependencies:
components:
- component: vpc
- component: rds
stack: "{{ .vars.tenant }}-{{ .vars.environment }}-prod"

Key Differences

Featuresettings.depends_ondependencies.components
FormatMap with numeric keysList
Merge behaviorDeep merge (complex)Append (simple)
LocationUnder settingsUnder dependencies
Cross-stacknamespace, tenant, environment, stage fieldsstack field only (use templates)
Cross-typeNot supportedUse kind field (terraform, helmfile, packer, etc.)
File/folder depsfile and folder fieldskind: file or kind: folder with path

Both formats continue to work. The new format is recommended for new configurations.