Inheritance and Deep-Merge Reference
This reference covers Atmos deep-merge algorithm, component inheritance via metadata fields, multiple inheritance, and the override precedence order.
Deep-Merge Algorithm
Atmos uses recursive deep-merging to combine configuration from multiple sources (imports, inheritance, inline definitions). The merge rules are:
Scalar Values (strings, numbers, booleans)
Later values replace earlier values. The higher-priority source wins.
# From imported defaultsvars:instance_type: t3.microenabled: false# From component definition (higher priority)vars:instance_type: t3.large # Replaces t3.microenabled: true # Replaces false
Maps / Objects
Maps are recursively merged. Keys from both sources are combined. When both sources define the same key, the higher-priority value wins for that key, but other keys from the lower-priority source are preserved.
# From base componentvars:tags:ManagedBy: AtmosTeam: Platform# From derived component (higher priority)vars:tags:Environment: ProductionTeam: SRE # Overrides "Platform"# Result (deep-merged)vars:tags:ManagedBy: Atmos # Preserved from baseTeam: SRE # Overridden by derivedEnvironment: Production # Added by derived
Lists / Arrays
Lists are NOT merged -- the higher-priority list entirely replaces the lower-priority list. This is a critical distinction from map merge behavior.
# From base componentvars:availability_zones:- us-east-1a- us-east-1b- us-east-1c# From derived component (higher priority)vars:availability_zones:- us-west-2a- us-west-2b# Result (replaced, NOT appended)vars:availability_zones:- us-west-2a- us-west-2b
Override Precedence Order
When computing the final configuration for a component, Atmos merges from multiple sources in a defined order. Lower-numbered sources have lower priority; higher-numbered sources override them:
- Global scope --
vars:,env:,settings:,hooks:at the top level of any imported file - Component-type scope --
terraform.vars:,terraform.env:, etc. - Inherited base components -- Configuration from
metadata.inheritslist, processed in list order (later entries override earlier entries) - Component inline definition --
components.terraform.<name>.vars:etc. - Overrides --
overrides:,terraform.overrides:,helmfile.overrides:(highest priority for the sections they affect)
Within each level, imports are processed in the order they appear in the import list. Later imports override earlier imports.
Precedence Example
# stacks/catalog/vpc/_defaults.yaml (imported first)vars:tags:Team: Platform # Priority 1: global scope from importterraform:vars:terraform_version: "1.5" # Priority 2: component-type scopecomponents:terraform:vpc/defaults:metadata:type: abstractvars:enabled: true # Priority 3: base componentmax_subnets: 3# stacks/orgs/acme/plat/prod/us-east-1.yaml (top-level stack)import:- catalog/vpc/_defaultsvars:stage: prod # Priority 1: global scope (merged with import)components:terraform:vpc:metadata:inherits:- vpc/defaults # Priority 3: inheritedvars:max_subnets: 6 # Priority 4: inline (overrides inherited value)vpc_cidr: "10.0.0.0/16"
Component Inheritance
Component inheritance allows one Atmos component to inherit configuration from another using metadata.inherits.
Single Inheritance
components:terraform:vpc/defaults:metadata:type: abstractcomponent: vpcvars:enabled: truenat_gateway_enabled: truemax_subnet_count: 3vpc:metadata:inherits:- vpc/defaultsvars:max_subnet_count: 2 # Overrides the inherited value
The vpc component receives all configuration from vpc/defaults, then its own inline values are deep-merged on top. Only max_subnet_count differs.
metadata.component
The metadata.component field specifies which Terraform root module the Atmos component maps to. This allows the Atmos component name to differ from the Terraform module directory name:
components:terraform:vpc-prod:metadata:component: vpc # Points to components/terraform/vpc/vars:environment: prodvpc-staging:metadata:component: vpc # Same Terraform module, different configvars:environment: staging
Both vpc-prod and vpc-staging use components/terraform/vpc/ as their Terraform root module but maintain separate state and configurations.
metadata.inherits
The metadata.inherits field is a list of component names from which to inherit configuration. The base components must be defined in the same stack (either inline or via imports).
components:terraform:vpc:metadata:inherits:- vpc/defaults
Inherited sections include vars, env, settings, hooks, backend, backend_type, providers, and command. The metadata section itself is NOT inherited (except metadata.custom when configured).
Multiple Inheritance
A component can inherit from multiple base components. The inherits list is processed in order, with later entries overriding earlier entries:
components:terraform:# Abstract trait: defaultsbase/defaults:metadata:type: abstractvars:enabled: truetags:managed_by: atmos# Abstract trait: loggingbase/logging:metadata:type: abstractvars:logging_enabled: truelog_retention_days: 30# Abstract trait: production settingsbase/production:metadata:type: abstractvars:multi_az: truedeletion_protection: truetags:environment: production# Concrete component inheriting from all threerds:metadata:component: rdsinherits:- base/defaults # Applied first- base/logging # Applied second- base/production # Applied third (highest precedence among bases)vars:name: my-database # Inline values have highest precedence
The merge order for this component:
base/defaultsvarsbase/loggingvars deep-merged on topbase/productionvars deep-merged on top- Inline
rdsvars deep-merged on top (highest priority)
Result:
vars:enabled: true # from base/defaultstags:managed_by: atmos # from base/defaults (preserved)environment: production # from base/production (deep-merged)logging_enabled: true # from base/logginglog_retention_days: 30 # from base/loggingmulti_az: true # from base/productiondeletion_protection: true # from base/productionname: my-database # from inline
Abstract vs Real Components
Abstract Components
Marked with metadata.type: abstract. They serve as blueprints and cannot be deployed:
components:terraform:vpc/defaults:metadata:type: abstractvars:enabled: true
Attempting to deploy an abstract component produces an error:
abstract component 'vpc/defaults' cannot be provisioned since it's explicitlyprohibited from being deployed by 'metadata.type: abstract' attribute
Real Components (Default)
If metadata.type is not specified, the component defaults to real and can be deployed with atmos terraform apply.
The Overrides Section
The overrides section is a special mechanism that applies configuration changes only to components defined in the current manifest and its imports, not to all components in the top-level stack.
This is critical for team-based organization where different teams manage different sets of components:
# stacks/teams/testing.yamlimport:- catalog/terraform/test-component- catalog/terraform/test-component-overrideoverrides:env:TEST_ENV_VAR1: "overridden-value"vars:custom_tag: override-valueterraform:overrides:settings:validation:check-cidr:schema_path: schemas/vpc-override.jsoncommand: tofu
The overrides in testing.yaml affect only components from test-component and test-component-override. Components from other team manifests imported into the same top-level stack are unaffected.
Overrides Scope Rules
overrides:at global scope affects all component types in the current manifest and its imports.terraform.overrides:affects only Terraform components in the current manifest. Deep-merged with global overrides, withterraform.overridestaking higher priority.helmfile.overrides:affects only Helmfile components, similarly deep-merged with global overrides.- Overrides defined inline in a manifest take precedence over imported overrides.
- The order of imports matters: overrides from an imported manifest only affect components imported AFTER the overrides manifest in the import list. However, overrides defined inline in the manifest affect ALL components, including those imported before the overrides.
Debugging Inheritance and Merge Results
Use atmos describe component to see the fully resolved configuration including inheritance chain:
atmos describe component vpc -s plat-ue2-prod
The output includes the overrides section (showing what overrides were applied), the final merged vars, env, settings, and the metadata showing the inheritance chain.
Use atmos describe stacks with filters to compare configurations across stacks:
atmos describe stacks --components vpc --sections vars,metadata