# Configuring Components in Stacks

Components are the building blocks of your infrastructure, defined in the
`components` section of stack manifests. Each component represents
infrastructure-as-code or deployment logic (Terraform, Helmfile, Kubernetes,
Packer, or Ansible) combined with its configuration. This page covers how to
configure components in stacks and the common attributes available across all
component types.

## Supported Component Types

## Component Schema

A component consists of infrastructure-as-code business logic (e.g., a Terraform root module) combined with its configuration in a stack manifest.

:::info Disambiguation

- **Terraform Component** is simply a [Terraform Root Module](https://developer.hashicorp.com/terraform/language/modules#the-root-module)
  that consists of the resources defined in the `.tf` files in a working directory
  (e.g. [components/terraform/infra/vpc](https://github.com/cloudposse/atmos/tree/main/tests/fixtures/scenarios/complete/components/terraform/infra/vpc))

- **Component Configuration** provides configuration (variables and other settings) for a type of component (e.g. a Terraform component)
  and is defined in one or more YAML stack config files (which are called [Atmos stacks](/learn/stacks))

:::

## Common Configuration Sections

All component types support these configuration sections:

- **[`vars`](/stacks/vars)**
  Variables passed to the component. Use 
  [component validation](/validation/validating)
   to enforce policies.
- **[`locals`](/stacks/locals)**

  File-scoped temporary variables for DRY configuration within a single
  manifest.
- **[`env`](/stacks/env)**
  Environment variables set during execution.
- **[`settings`](/stacks/settings)**
  Integrations and custom metadata.
- **[`metadata`](/stacks/components/component-metadata)**

  Component behavior and inheritance. See [Metadata
  Attributes](#metadata-attributes) below.
- **[`command`](/stacks/command)**
  Override the default executable.
- **[`hooks`](/stacks/hooks)**
  Lifecycle event handlers.

## Basic Component Structure

Components are defined in stack manifests under the `components` section, organized by type:

```yaml
components:
  terraform:
    vpc:
      vars:
        vpc_cidr: "10.0.0.0/16"

  helmfile:
    nginx:
      vars:
        replicas: 3

  kubernetes:
    argocd:
      provider: kustomize
      paths:
        - overlays/dev

  packer:
    ami-builder:
      vars:
        base_ami: ami-12345678

  ansible:
    webserver:
      vars:
        app_name: myapp
```

## Metadata Attributes

The `metadata` section controls component behavior, inheritance, and type.

### Component Types (`metadata.type`)

The `metadata.type` parameter defines how a component behaves—whether it can be deployed directly or serves as a base configuration:

- **`real`**
  A 
  `real`
   component is fully configured and ready to be provisioned. Think of it as a "concrete" class that can create resources directly in your infrastructure. This is the default type.
- **`abstract`**
  An 
  `abstract`
   component is a blueprint that can't be deployed on its own. It defines reusable configurations that must be inherited by other components, similar to an 
  abstract base class
   in programming.

### Disabling Components (`metadata.enabled`)

The `metadata.enabled` parameter controls whether a component is included in deployment. By default, components are enabled. Setting `metadata.enabled` to `false` skips the component entirely—no workspace is created, and no Terraform commands are executed.

:::info
Disabling a component does not cause deletion. It signals that the component is no longer managed by Atmos.
:::

```yaml
components:
  terraform:
    vpc:
      metadata:
        type: real
        enabled: false
      vars:
        name: primary-vpc
```

### Locking Components (`metadata.locked`)

The `metadata.locked` parameter prevents changes to a component while still allowing read operations. When locked, operations that would modify infrastructure (like `terraform apply`) are blocked, while read-only operations (like `terraform plan`) remain available.

```yaml
components:
  terraform:
    rds:
      metadata:
        locked: true
      vars:
        name: production-database
```

:::info
Locking a component does not affect the Terraform state. It's intended to communicate intention and prevent accidental changes to sensitive infrastructure.
:::

### Component Versioning (`metadata.component`)

The `metadata.component` parameter specifies which component implementation to use. This is how you manage component versions in Atmos—by pointing to different component folders.

By default, if `metadata.component` is not specified, Atmos uses the component's name as the path. You can explicitly reference different versions or implementations:

### Continuous Deployment

All environments point to the same component folder, with versions rolled out through release controls in your deployment pipeline:

```yaml
# All environments use components/terraform/vpc/
components:
  terraform:
    vpc:
      vars:
        name: my-vpc
```

### Release Channels

Environments subscribe to named release channels:

```yaml
# stacks/dev/us-east-1.yaml
components:
  terraform:
    vpc:
      metadata:
        component: alpha/vpc # Subscribe to alpha track
```

```yaml
# stacks/prod/us-east-1.yaml
components:
  terraform:
    vpc:
      metadata:
        component: prod/vpc # Subscribe to production track
```

### Version Pinning

Explicit version pinning using major.minor versioning:

```yaml
# stacks/prod/us-east-1.yaml
components:
  terraform:
    vpc:
      metadata:
        component: vpc/1.2 # Pinned version
      vars:
        name: prod-vpc
```

:::tip Version Management Patterns
The `metadata.component` parameter is the foundation of [Version Management Patterns](/design-patterns/version-management) in Atmos. See [Version Management Patterns](/design-patterns/version-management) to learn how to choose and implement the right versioning strategy.
:::

## Type-Specific Configuration

Each component type has additional configuration options:

### Terraform-Specific

- `backend` / `backend_type` - State storage configuration
- `remote_state_backend` / `remote_state_backend_type` - Remote state access
- `providers` - Provider configuration
- `terraform_workspace` / `terraform_workspace_pattern` - Workspace settings

See [Terraform Components](/stacks/components/terraform) for details.

### Helmfile-Specific

Helmfile components use the standard sections listed above. Helmfile-specific configuration is typically passed through `vars`.

See [Helmfile Components](/stacks/components/helmfile) for details.

### Packer-Specific

Packer components use the standard sections listed above. Packer-specific configuration is typically passed through `vars`.

See [Packer Components](/stacks/components/packer) for details.

### Ansible-Specific

Ansible components use the standard sections listed above, plus `settings.ansible.playbook` and `settings.ansible.inventory` for playbook configuration.

See [Ansible Components](/stacks/components/ansible) for details.

## Component-Type Defaults

You can define default settings for all components of a type at the root level:

```yaml
# Defaults for all Terraform components in this stack
terraform:
  vars:
    terraform_version: "1.5"
  env:
    TF_IN_AUTOMATION: "true"
  backend_type: s3
  backend:
    s3:
      bucket: my-terraform-state

# Defaults for all Helmfile components
helmfile:
  vars:
    timeout: 600
  env:
    HELM_CACHE_HOME: /tmp/helm-cache

# Defaults for all Ansible components
ansible:
  vars:
    managed_by: Atmos
  env:
    ANSIBLE_HOST_KEY_CHECKING: "false"

# Individual components inherit and can override these defaults
components:
  terraform:
    vpc:
      vars:
        vpc_cidr: "10.0.0.0/16"
```

## Component Directory Structure

Atmos looks for component implementations in directories configured in `atmos.yaml`:

```yaml
# atmos.yaml
components:
  terraform:
    base_path: components/terraform
  helmfile:
    base_path: components/helmfile
  packer:
    base_path: components/packer
  ansible:
    base_path: components/ansible
```

Your project structure would look like:

```
├── atmos.yaml
├── components/
│   ├── terraform/
│   │   ├── vpc/
│   │   │   ├── main.tf
│   │   │   ├── variables.tf
│   │   │   └── outputs.tf
│   │   └── eks/
│   ├── helmfile/
│   │   └── nginx/
│   │       └── helmfile.yaml
│   ├── packer/
│   │   └── ami-builder/
│   │       └── template.pkr.hcl
│   └── ansible/
│       └── webserver/
│           └── site.yml
└── stacks/
```

## Best Practices

1. **Use Abstract Components:** Create abstract base components in catalogs with common settings, then inherit from them in stack-specific components.

2. **Use Type Defaults:** Define common settings at the component-type level to keep individual component configurations focused on unique values.

3. **Organize by Purpose:** Group components logically in your directory structure (e.g., `networking/`, `databases/`, `monitoring/`).

4. **Share with Catalogs:** Create reusable component configurations in `stacks/catalog/` that can be imported across environments.

5. **Lock Critical Infrastructure:** Use `metadata.locked` to protect production databases and other sensitive components from accidental changes.

## Related

- [Stack Configuration Overview](/stacks)
- [Terraform Components](/stacks/components/terraform)
- [Helmfile Components](/stacks/components/helmfile)
- [Packer Components](/stacks/components/packer)
- [Ansible Components](/stacks/components/ansible)
- [Version Management Patterns](/design-patterns/version-management)
