# Configure Component Metadata

The `metadata` section configures how Atmos interprets and manages a component. Unlike other sections, `metadata` is only valid within component definitions (`components.terraform.<name>.metadata`), not at the global or component-type level.

## Use Cases

- **Component Mapping:** Specify which Terraform root module a component uses.
- **Inheritance:** Define which components a component inherits from.
- **Abstract Components:** Mark components as templates that cannot be deployed directly.
- **Component Control:** Enable, disable, or lock components.

## Configuration Scope

The `metadata` section is **only valid inside component definitions**:

```yaml
components:
  terraform:
    vpc:
      metadata:
        component: vpc/network
        inherits:
          - vpc/defaults
```

It cannot be used at the global level or under `terraform:` / `helmfile:` / `packer:` defaults.

## Metadata Fields

### `component`

Specifies the path to the Terraform root module, relative to your components directory:

```yaml
components:
  terraform:
    vpc-prod:
      metadata:
        component: vpc  # Uses components/terraform/vpc
      vars:
        environment: prod
```

This allows multiple stack components to share the same Terraform root module with different configurations.

### `name`

Provides a stable logical identity for the component, used to generate the backend `workspace_key_prefix`. This is especially important when using [versioned component folders](/design-patterns/version-management/folder-based-versioning):

```yaml
components:
  terraform:
    vpc:
      metadata:
        name: vpc              # Stable logical identity
        component: vpc/v2      # Physical version path
```

**Why this matters:** Without `name`, the `workspace_key_prefix` is auto-generated from `component`, which includes the version (`vpc-v2`). When you upgrade to `vpc/v3`, the workspace key prefix changes, creating a new state file and losing your existing infrastructure state.

**With `metadata.name`:** The workspace key prefix stays stable (`vpc`) across version upgrades, so your Terraform state path remains `vpc/{workspace}/terraform.tfstate` regardless of which version you're running.

See [Workspace Key Management](/design-patterns/version-management/folder-based-versioning#workspace-key-management) for more details.

### `inherits`

Defines a list of components from which this component inherits configuration:

```yaml
components:
  terraform:
    vpc/defaults:
      metadata:
        type: abstract
      vars:
        enable_dns_hostnames: true
        enable_dns_support: true

    vpc-prod:
      metadata:
        inherits:
          - vpc/defaults
      vars:
        vpc_cidr: "10.0.0.0/16"
```

Inheritance is processed in order, with later items and the component's own values taking precedence. For detailed inheritance behavior, see [Inheritance](/howto/inheritance).

### `type`

Marks a component as `abstract` or `real` (default):

```yaml
components:
  terraform:
    vpc/base:
      metadata:
        type: abstract  # Cannot be deployed directly
      vars:
        enable_dns_hostnames: true
```

**Abstract components:**

- Serve as templates for other components to inherit from
- Cannot be deployed with `atmos terraform apply`
- Do not appear in `atmos describe stacks` output by default
- Are useful for DRY configuration patterns

### `enabled`

Controls whether a component is active:

```yaml
components:
  terraform:
    monitoring:
      metadata:
        enabled: false  # Component is disabled
      vars:
        # ...
```

When `enabled: false`:

- The component is skipped during `atmos terraform apply`
- The component does not appear in active stack listings
- Useful for conditionally disabling components per environment

### `locked`

Prevents modifications to a component:

```yaml
components:
  terraform:
    core-network:
      metadata:
        locked: true  # Prevent changes
      vars:
        # ...
```

When `locked: true`:

- Atmos will warn or prevent changes to the component
- Useful for protecting critical infrastructure components

### `terraform_workspace`

Overrides the Terraform workspace name with a literal string value:

```yaml
components:
  terraform:
    vpc:
      metadata:
        terraform_workspace: "custom-workspace-name"
```

By default, Atmos calculates workspace names automatically based on the stack name. Use this field when you need explicit control over the workspace name.

For detailed information about how Atmos manages Terraform workspaces, see [Workspaces](/components/terraform/workspaces).

### `terraform_workspace_pattern`

Overrides the Terraform workspace name using a pattern with context tokens:

```yaml
components:
  terraform:
    vpc:
      metadata:
        terraform_workspace_pattern: "{tenant}-{environment}-{stage}"
```

Supported tokens:

- `{namespace}` - The namespace from context variables
- `{tenant}` - The tenant from context variables
- `{environment}` - The environment from context variables
- `{region}` - The region from context variables
- `{stage}` - The stage from context variables
- `{attributes}` - The attributes from context variables
- `{component}` - The Atmos component name
- `{base-component}` - The base component name (from `metadata.component`)

For detailed information about workspace patterns and examples, see [Workspaces](/components/terraform/workspaces).

### `custom`

A user extension point for storing arbitrary metadata that Atmos preserves but does not interpret:

```yaml
components:
  terraform:
    vpc:
      metadata:
        custom:
          owner: platform-team
          cost_center: "12345"
          tier: critical
```

Use `custom` for:

- Storing metadata for external tooling to consume (CI/CD pipelines, dashboards)
- Adding labels or annotations readable via `atmos describe stacks`
- Custom categorization that doesn't affect Atmos behavior

:::note
The `custom` section is inherited from base components when `stacks.inherit.metadata` is enabled (the default). Like other metadata fields, values from derived components override inherited values, and nested maps are deep-merged.
:::

## Examples

### Multiple Instances from One Module

Deploy the same VPC module in different configurations:

**File:** `stacks/orgs/acme/plat/prod/us-east-1.yaml`

```yaml
components:
  terraform:
    vpc-main:
      metadata:
        component: vpc
      vars:
        vpc_cidr: "10.0.0.0/16"
        name: main

    vpc-isolated:
      metadata:
        component: vpc
      vars:
        vpc_cidr: "10.1.0.0/16"
        name: isolated
        enable_internet_gateway: false
```

Both `vpc-main` and `vpc-isolated` use the same `components/terraform/vpc` root module but with different configurations.

### Abstract Base with Concrete Implementations

**File:** `stacks/catalog/vpc/_defaults.yaml`

```yaml
components:
  terraform:
    vpc/defaults:
      metadata:
        type: abstract
        component: vpc
      vars:
        enable_dns_hostnames: true
        enable_dns_support: true
        enable_nat_gateway: true
        single_nat_gateway: false
```

**File:** `stacks/orgs/acme/plat/prod/us-east-1.yaml`

```yaml
import:
  - catalog/vpc/_defaults

components:
  terraform:
    vpc:
      metadata:
        inherits:
          - vpc/defaults
      vars:
        vpc_cidr: "10.0.0.0/16"
        availability_zones:
          - us-east-1a
          - us-east-1b
          - us-east-1c
```

### Environment-Specific Component Control

**File:** `stacks/orgs/acme/plat/dev/us-east-1.yaml`

```yaml
components:
  terraform:
    expensive-feature:
      metadata:
        enabled: false  # Disabled in dev to save costs
      vars:
        # ...
```

**File:** `stacks/orgs/acme/plat/prod/us-east-1.yaml`

```yaml
components:
  terraform:
    expensive-feature:
      metadata:
        enabled: true   # Enabled in production
      vars:
        # ...
```

### Multi-Level Inheritance

**File:** `stacks/catalog/components.yaml`

```yaml
components:
  terraform:
    # Level 1: Base defaults
    base/defaults:
      metadata:
        type: abstract
      vars:
        tags:
          ManagedBy: Atmos

    # Level 2: VPC defaults inheriting from base
    vpc/defaults:
      metadata:
        type: abstract
        component: vpc
        inherits:
          - base/defaults
      vars:
        enable_dns_hostnames: true

    # Level 3: Production VPC inheriting from vpc/defaults
    vpc/prod:
      metadata:
        type: abstract
        inherits:
          - vpc/defaults
      vars:
        enable_nat_gateway: true
        multi_az: true
```

## Best Practices

1. **Use Abstract Components:** Create abstract base components for shared configuration to keep your stacks DRY.

2. **Meaningful Component Names:** Use descriptive names that indicate the component's purpose and any specialization (e.g., `vpc/prod`, `vpc/isolated`).

3. **Document Inheritance:** Keep inheritance chains shallow (2-3 levels) and well-documented for maintainability.

4. **Protect Critical Components:** Use `locked: true` for infrastructure components that should not change without careful review.

5. **Use `enabled` for Environment Differences:** Rather than duplicating component definitions, use `enabled` to control which components are active per environment.

## Related

- [Inheritance](/howto/inheritance)
- [Catalogs](/howto/catalogs)
- [Overrides](/stacks/overrides)
- [Variables (vars)](/stacks/vars)
- [Terraform Components](/stacks/components/terraform)
