# 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:

**File:** `stacks/dev.yaml`

```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
```

**File:** `stacks/staging.yaml`

```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**

**File:** `stacks/_defaults/vpc-base.yaml`

```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**

**File:** `stacks/dev.yaml`

```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.

**File:** `Base component`

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

**File:** `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`
  .

**File:** `Abstract component (blueprint)`

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

**File:** `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
```

**File:** `stacks/_defaults/vpc-base.yaml`

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

**File:** `stacks/prod.yaml`

```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

**File:** `Base component`

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

**File:** `Dev uses small instance`

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

**File:** `Prod uses large instance`

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

### 2. Feature Flags

**File:** `Base component`

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

**File:** `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

**File:** `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"
```

**File:** `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:**

```yaml
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 values**
✅ **Use 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:

- **[Organize your Stacks](/learn/organizing-stacks)** - Catalogs, defaults, and naming
- **[Connect Components](/learn/connecting-components)** - Share data between components
- **[Advanced Inheritance](/howto/inheritance)** - Multiple inheritance, mixins, and more
