Component Library
A component library is how you organize the reusable components that make up your infrastructure. It brings together Terraform or OpenTofu root modules, Helm charts, and other component types so teams can find, maintain, and reuse them across environments.
The library holds the implementations; stacks configure their deployments. Build your own components or use vendoring to bring existing components into your library.
What are Components?
In Atmos, a component consists of two parts:
- Implementation — The infrastructure or application definition, such as a root module, chart, manifest, image, or playbook
- Configuration — The settings that customize how the component is deployed in each environment
This separation of concerns is fundamental to Atmos. You write the implementation once, then configure it differently for each environment through stacks.
Component Configuration
Components are configured in the components section of stack files. Here's what component configuration looks like:
Each component configuration includes:
| Section | Purpose |
|---|---|
metadata | Component location, inheritance, and Atmos behavior |
vars | Input variables passed to the component |
settings | Atmos and integration settings (not passed to the component) |
Component Instances
A component instance is a specific deployment of a component in a stack. The same component implementation can have many instances across your infrastructure:
# Same "vpc" component, different instances
components:
terraform:
# Instance: "vpc" in prod/us-east-1
vpc:
vars:
cidr_block: "10.0.0.0/16"
# Instance: "vpc-secondary" in prod/us-east-1 (using same component)
vpc-secondary:
metadata:
component: vpc # Same implementation
vars:
cidr_block: "10.1.0.0/16"
Each instance:
- Has its own Terraform state (or Helmfile release, Packer build)
- Can have different variable values
- Is independently deployable
Implementation vs Configuration
| Aspect | Implementation | Configuration |
|---|---|---|
| Location | components/terraform/vpc/ | stacks/prod/us-east-1.yaml |
| Contains | Terraform code, resources, modules | Variables, settings, metadata |
| Changes | When infrastructure logic changes | When environment needs differ |
| Reuse | Single implementation | Many configurations |
This separation allows you to:
- Write a component once and deploy it across many environments
- Customize behavior through configuration, not code duplication
- Maintain consistency while supporting environment-specific requirements
- Update all instances by changing the implementation
Component Types
Atmos natively supports 8 component types:
| Type | Implementation | Description |
|---|---|---|
| Terraform/OpenTofu | Terraform root modules | Configure Terraform and OpenTofu components in Atmos stacks. |
| Kubernetes | Kubernetes manifests and Kustomize overlays | Configure Kubernetes-native components in Atmos stack manifests. |
| Helm | Local, repository, or OCI Helm charts | Configure native Helm components in Atmos stack manifests. |
| Helmfile | Helmfile configurations | Deploy and coordinate Helm releases using shared Atmos stack configuration. |
| Packer | Packer templates | Build consistent machine images using shared Atmos stack configuration. |
| Ansible | Ansible playbooks | Run Ansible playbooks with the same stack-based configuration used for Terraform and Helmfile. Stack variables are automatically passed via --extra-vars. |
| Container | Container images and services | Run local development services with shared Atmos stack configuration, inherited defaults, secrets, and compositions. |
| Emulator | Stack config via components.emulator.*.driver; no component directory | Run local cloud-API, Kubernetes, and backing-service emulators as stack-scoped components, so the rest of your stack runs offline with no cloud account. |
Each type has its own configuration schema, but they share common patterns for metadata and settings.
Beyond the native types, you can define custom component types to manage any tool—AWS CDK, CloudFormation, Pulumi, Bicep, database migrations, and more—with the same stack-based configuration.
Directory Structure
Your component library typically lives in your project's components/ directory, organized by component type. Within each type, group related implementations into folders:
components/
├── terraform/ # Terraform root modules
│ ├── vpc/
│ ├── eks/
│ │ └── cluster/
│ └── rds/
├── helmfile/ # Helmfile configurations
│ ├── nginx-ingress/
│ └── cert-manager/
├── packer/ # Packer templates
│ └── ubuntu-base/
├── ansible/ # Ansible playbooks
│ └── webserver/
└── container/ # Container build contexts
└── api/
Get a head start by utilizing Cloud Posse's free Terraform components for AWS, available on GitHub.
Use-cases
- Developer Productivity Create a component library of vetted terraform root modules that should be used by teams anytime they need to spin up infrastructure for VPCs, clusters, and databases.
- Compliance and Governance: Establish a component library to enforce infrastructure standards, security policies, and compliance requirements. By using pre-approved modules, organizations can maintain control over their infrastructure's configuration, reducing the risk of non-compliance.
- Rapid Prototyping and Scalability: Utilize a component library to quickly prototype and scale applications. Pre-built modules for common infrastructure patterns allow teams to focus on application development rather than infrastructure setup, accelerating time-to-market and ensuring scalability from the outset.
Organizing Components
There's no "one way" to organize your components—it's configurable based on your needs. Here's a simple example organizing by toolchain:
For detailed guidance on folder structure including multi-cloud layouts, version management strategies, and enterprise patterns, see Project Layout.
Terraform Conventions
For terraform, we recommend placing the terraform "root" modules in the components/terraform folder. If the root modules depend on other child modules that are not hosted by a registry, we recommend placing them in a subfolder called modules/.
Make your Terraform components small, so they are easily reusable, but not so small that they only do to provide a single resource, which results in large, complicated configurations. A good rule of thumb is they should do one thing well. For example, provision a VPC along with all the subnets, NAT gateways, Internet gateways, NACLs, etc.
Use multiple component to break infrastructure apart into smaller pieces based on how their lifecycles are connected. For example, a single component seldom provides a VPC and a Kubernetes cluster. That's because we should be able to destroy the Kubernetes cluster without destroying the VPC and all the other resources provisioned inside of the VPC (e.g. databases). The VPC, Kubernetes cluster and Databases all have different lifecycles. Similarly, we should be able to deploy a database and destroy it without also destroying all associated backups. Therefore the backups of a database should be a separate component from the database itself.
Describing Components
When working with complex configurations that use imports and inheritance, it can be challenging to understand the final deep-merged configuration for a component. Use the atmos describe component command to view the fully resolved configuration:
atmos describe component vpc -s ue2-prod
This is especially helpful when:
- Debugging configuration issues
- Understanding inherited values
- Developing validation policies
- Verifying the final configuration before deployment
For more powerful filtering options, consider describing stacks instead.
Next Steps
Configure Terraform and OpenTofu components in Atmos stacks.
Configure Kubernetes-native components in Atmos stack manifests.
Configure native Helm components in Atmos stack manifests.
Deploy and coordinate Helm releases using shared Atmos stack configuration.
Build consistent machine images using shared Atmos stack configuration.
Run Ansible playbooks with the same stack-based configuration used for Terraform and Helmfile. Stack variables are automatically passed via --extra-vars.
Run local development services with shared Atmos stack configuration, inherited defaults, secrets, and compositions.
Run local cloud-API, Kubernetes, and backing-service emulators as stack-scoped components, so the rest of your stack runs offline with no cloud account.
Bring any tool—AWS CDK, CloudFormation, Pulumi, Bicep, database migrations, and more—under the same stack-based configuration used for Terraform, Helmfile, and Packer.