Skip to main content

Component Overrides

Atmos Design Pattern

The Component Overrides pattern lets you apply configuration to a specific group of components without affecting other components in the same stack.

The Problem

When you set vars at the stack level, it applies to every component in the final merged stack:

stacks/deploy/prod.yaml
import:
- teams/platform # imports: vpc, eks, rds
- teams/security # imports: waf, security-groups

vars:
environment: prod
# This tag applies to ALL components (vpc, eks, rds, waf, security-groups)
tags:
Team: Platform

But what if the Platform team and Security team each want their own Team tag? You can't use regular vars because it applies globally.

The Solution: Overrides

The overrides section is scoped to the current file and its imports. It doesn't leak into sibling imports or get inherited by files that import this one.

Key Insight

Overrides are file-scoped and don't get inherited. They only apply to components visible from that file's import tree.

stacks/teams/platform.yaml

import:
- catalog/vpc/defaults
- catalog/eks/defaults
- catalog/rds/defaults

# Only applies to vpc, eks, rds (not security team's components)
terraform:
overrides:
vars:
tags:
Team: Platform

stacks/teams/security.yaml

import:
- catalog/waf/defaults
- catalog/security-groups/defaults

# Only applies to waf, security-groups (not platform team's components)
terraform:
overrides:
vars:
tags:
Team: Security

stacks/deploy/prod.yaml

import:
- teams/platform # vpc, eks, rds get Team: Platform
- teams/security # waf, security-groups get Team: Security
- mixins/stage/prod

vars:
environment: prod

Now each team's components get their own Team tag, even though they're all in the same final stack.

When to Use Overrides

ScenarioUse varsUse overrides
Setting values for ALL components
Setting values for a SUBSET of components
Team-specific configuration
Layer-specific settings (network, data, compute)

Overrides vs Vars

Aspectvarsoverrides
ScopeFinal merged stack (global)Current file + its imports only
InheritanceGets inherited by importing filesDoes NOT get inherited
VisibilityAffects ALL componentsOnly affects components "visible" from this file

Think of it this way:

  • vars = "Apply this to the final result"
  • overrides = "Apply this only to what I can see from here"
platform.yaml
├── imports: vpc, eks, rds
├── overrides: Team=Platform ← only sees vpc, eks, rds

security.yaml
├── imports: waf, firewall
├── overrides: Team=Security ← only sees waf, firewall

prod.yaml
├── imports: platform.yaml, security.yaml
├── vars: env=prod ← sees ALL components (vpc, eks, rds, waf, firewall)

Example: Layer-Based Overrides

When using Layered Stack Configuration, overrides let each layer tag its components:

stacks/layers/network.yaml

import:
- catalog/vpc/defaults
- catalog/transit-gateway/defaults

terraform:
overrides:
vars:
tags:
Layer: network

stacks/layers/data.yaml

import:
- catalog/rds/defaults
- catalog/elasticache/defaults

terraform:
overrides:
vars:
tags:
Layer: data

What You Can Override

The overrides section supports:

  • vars - Input variables
  • env - Environment variables
  • settings - Component settings
  • command - The executable to use (e.g., tofu instead of terraform)
  • providers - Terraform provider configuration
  • hooks - Lifecycle hooks
terraform:
overrides:
vars:
tags:
Team: Platform
settings:
spacelift:
autodeploy: true
command: tofu # Use OpenTofu for these components

References