Gergő Nagy

Gergő Nagy

  · 4 min read

We Tried Atmos: From DevOps to SweetOps?

The article explains how Atmos works, when it’s beneficial to use, and how it can be applied within the SweetOps ecosystem.

The article explains how Atmos works, when it’s beneficial to use, and how it can be applied within the SweetOps ecosystem.

At Code Factory, we have been using Terragrunt for our Infrastructure as Code projects for several years. We most often rely on community modules available in the Terraform Registry, including those developed by the Cloudposse team. Since the stack structure recommended by Gruntwork did not seem convincing enough for us, we decided to try Cloudposse’s own orchestration tool, Atmos.

What is Atmos?

Terraform code can quickly become cumbersome as our infrastructure grows. Atmos is a robust CLI tool that offers an alternative solution, enabling us to conveniently and efficiently manage large infrastructures, even across multiple accounts and environments.

What Can Atmos Do?

Like the Terragrunt Stack, Atmos is built on Terraform modules, but it refers to them as components. It also includes a very useful feature called vendor, which comes with a separate configuration file and API. Using the vendor, we can import components into our project based on their version.

Atmos vendor command
Atmos vendor command

Components are used within stack, which Atmos names according to our configured atmos.yaml file. Additionally, it provides a modern, user-friendly CLI that can manage the infrastructure at the command, stack, and component levels.

Atmos Command Line Interface
Atmos Command Line Interface

For Terragrunt, we use the mise tool to wrap commands and manage tool versions. In Atmos, all of this is available natively: we can define workflows—for example, deploying all components and dependencies of an EKS module with a single command. Moreover, we can create custom commands directly in the atmos.yaml file.

What is the concept behind Atmos?

The core principle of Atmos is DRY (Don’t Repeat Yourself).

This philosophy is implemented through imports and merges. Every YAML configuration file can be imported into another, and the order of imports determines the hierarchy. The last imported value (or the last one listed in the import key) becomes part of the final stack. The merge strategy can also be set in the atmos.yaml file.

A common best practice is to create default configurations, which define shared values for stages (dev, prod, etc.), such as remote state or default catalog settings. Individual stacks can then simply import the default and override or extend it as needed.

Similar to OOP, Cloudposse introduces an inheritance model called COP (Component Oriented Programming). This allows a hierarchical structure between components.

A component can even be marked as abstract, meaning it cannot be instantiated directly. It can only be used if its type is overridden in another file or if the inheritance is defined in the YAML configuration.

.
├── atmos.yaml
├── components
│   └── terraform
│       ├── account
│       │   └── *.tf
│       ├── account-map
│       │   └── *.tf
│       ├── eks
│       │   └── *.tf
│       ├── tfstate-backend
│       │   └── *.tf
│       └── vpc
│           └── *.tf
├── stacks
│   ├── catalog
│   │   ├── account
│   │   │   └── defaults.yaml
│   │   ├── account-map
│   │   │   └── defaults.yaml
│   │   ├── tfstate-backend
│   │   │   └── defaults.yaml
│   │   └── vpc
│   │       ├── defaults.yaml
│   │       ├── dev.yaml
│   │       └── prod.yaml
│   ├── mixins
│   │   ├── region
│   │   │   ├── eu-central-1.yaml
│   │   │   └── global-region.yaml
│   │   └── stage
│   │       ├── dev.yaml
│   │       ├── prod.yaml
│   │       └── root.yaml
│   └── orgs
│       └── acme
│           ├── _defaults.yaml
│           ├── core
│           │   ├── _defaults.yaml
│           │   └── root.yaml
│           └── plat
│               ├── _defaults.yaml
│               └── dev
│                   ├── _defaults.yaml
│                   └── eu-central-1.yaml
└── vendor.yaml
Repository - File structure

Disadvantages

In our experience, Atmos works best when strictly following the management conventions defined by Cloudposse. However, this requires using the Account and Account-Map components, which create strong dependencies on other modules. Consequently, the solution is not very suitable for brownfield projects — I, for example, could only use it in greenfield environments with AWS root access.

Proper operation also requires using the full SweetOps ecosystem (Atmos, Geodesic, Cloudposse components, and the null-label modul).

Our Impression of Atmos

Cloudposse implements many logical and forward-thinking ideas. The import and merge mechanism is relatively easy to grasp, but the methodology is currently tightly coupled with the Cloudposse ecosystem, leading to significant dependencies.

Trying a proof of concept is also challenging because there is no publicly available complete example repository, and the documentation is incomplete or unclear in several areas.

Thank you for reading this article!

Are you interested in this topic? Do you have any questions about the article? Book a free consultation and let’s see how the Code Factory team can help you! You can find a list of our services here!

Sources
Back to Blog