Skip to main content

Inheritance Basics

Inheritance lets you create variations of a component without duplicating configuration. Define a base component once, then extend it with different settings for different use cases.

Think of it like classes in object-oriented programming: you create a base "class" (component) and then extend it with specialized "subclasses" (component instances).

The Problem Inheritance Solves

Let's say you need three VPCs:

  • Development VPC: Small CIDR, single NAT gateway
  • Staging VPC: Medium CIDR, redundant NAT gateways
  • Production VPC: Large CIDR, highly available NAT gateways, VPN

Without inheritance, you'd configure each one separately, copying most of the same settings:

stacks/dev.yaml

components:
terraform:
vpc-dev:
metadata:
component: vpc
vars:
name: dev-vpc
cidr_block: "10.0.0.0/16"
enable_dns_hostnames: true
enable_dns_support: true
enable_nat_gateway: true
single_nat_gateway: true

stacks/staging.yaml

components:
terraform:
vpc-staging:
metadata:
component: vpc
vars:
name: staging-vpc
cidr_block: "10.1.0.0/16"
enable_dns_hostnames: true # Duplicated
enable_dns_support: true # Duplicated
enable_nat_gateway: true # Duplicated
single_nat_gateway: false
# ...more settings

That's a lot of duplication! Let's fix it with inheritance.

Your First Inherited Component

Step 1: Define a base component with common settings

stacks/_defaults/vpc-base.yaml

components:
terraform:
vpc-base:
metadata:
component: vpc
type: abstract # This component isn't deployable on its own
vars:
# Common settings for all VPCs
enable_dns_hostnames: true
enable_dns_support: true
enable_nat_gateway: true

Step 2: Extend the base component

stacks/dev.yaml

import:
- _defaults/vpc-base

components:
terraform:
vpc-dev:
metadata:
component: vpc
inherits:
- vpc-base # Inherit all settings from vpc-base
vars:
# Only specify what's different
name: dev-vpc
cidr_block: "10.0.0.0/16"
single_nat_gateway: true

Now vpc-dev automatically has enable_dns_hostnames, enable_dns_support, and enable_nat_gateway from the base component—no duplication needed!

How Inheritance Works

When you use inherits, Atmos:

  1. Loads the base component's configuration
  2. Merges it with the current component's configuration
  3. Current component values override base values

The child component gets everything from the parent, and can override any setting.

Base component

components:
terraform:
vpc-base:
metadata:
type: abstract
vars:
enable_nat_gateway: true
single_nat_gateway: true

Child component

components:
terraform:
vpc-prod:
metadata:
inherits:
- vpc-base
vars:
single_nat_gateway: false # Overrides base setting
# enable_nat_gateway: true inherited from base

Abstract vs Real Components

Notice the type: abstract in the base component? This tells Atmos:

Abstract Components
Templates for inheritance. Cannot be deployed directly. Used as blueprints.
Real Components
Deployable infrastructure. Can be applied with atmos terraform apply.

Abstract component (blueprint)

components:
terraform:
vpc-base:
metadata:
component: vpc
type: abstract # Can't deploy this
vars:
enable_dns: true

Real component (deployable)

components:
terraform:
vpc-prod:
metadata:
component: vpc
inherits:
- vpc-base
vars:
cidr_block: "10.0.0.0/16"

Try to deploy the abstract component and Atmos will error. Only real components can be deployed.

Organizing Inherited Components

A common pattern is to keep base components in a _defaults/ directory or a catalog/:

stacks/
├── _defaults/
│ ├── vpc-base.yaml
│ ├── eks-base.yaml
│ └── rds-base.yaml
├── dev.yaml
├── staging.yaml
└── prod.yaml

stacks/_defaults/vpc-base.yaml

components:
terraform:
vpc-base:
metadata:
component: vpc
type: abstract
vars:
enable_dns_hostnames: true
enable_dns_support: true

stacks/prod.yaml

import:
- _defaults/vpc-base

components:
terraform:
vpc-prod:
metadata:
inherits:
- vpc-base
vars:
cidr_block: "10.0.0.0/16"

Common Inheritance Patterns

1. Environment-Specific Sizing

Base component

components:
terraform:
rds-base:
metadata:
component: rds
type: abstract
vars:
engine: postgres
engine_version: "14.7"

Dev uses small instance

components:
terraform:
rds-dev:
metadata:
inherits:
- rds-base
vars:
instance_class: db.t3.small

Prod uses large instance

components:
terraform:
rds-prod:
metadata:
inherits:
- rds-base
vars:
instance_class: db.r5.xlarge
multi_az: true

2. Feature Flags

Base component

components:
terraform:
app-base:
metadata:
component: application
type: abstract
vars:
enable_autoscaling: false
enable_monitoring: false

Production enables all features

components:
terraform:
app-prod:
metadata:
inherits:
- app-base
vars:
enable_autoscaling: true
enable_monitoring: true
enable_backup: true

3. Regional Defaults

Base for US regions

components:
terraform:
vpc-us-base:
metadata:
component: vpc
type: abstract
vars:
availability_zones: 3
cidr_block: "10.0.0.0/16"

Base for EU regions (different CIDR)

components:
terraform:
vpc-eu-base:
metadata:
component: vpc
type: abstract
vars:
availability_zones: 3
cidr_block: "10.100.0.0/16"

Inheritance vs Imports

Still confused about when to use each?

Imports
  • Bring entire stack files together
  • Share configuration across multiple stacks
  • Example: Global tags, regional settings
Inheritance
  • Create component variations
  • Share configuration within component definitions
  • Example: Base VPC → Dev VPC, Staging VPC, Prod VPC

You'll often use both together:

import:
- _defaults/globals # Import stack-level settings
- _defaults/vpc-base # Import base component

components:
terraform:
vpc-prod:
metadata:
inherits:
- vpc-base # Inherit component settings
vars:
cidr_block: "10.0.0.0/16"

Key Takeaways

Inheritance creates component variations without duplication ✅ Abstract components are blueprints for inheritance (not deployable) ✅ Real components can be deployed and can inherit from abstract ones ✅ Child components override parent valuesUse for component-level reuse (imports are for stack-level reuse)

What's Next

You've learned the basics of imports and inheritance. Now let's talk about organizing these files for real-world projects: