Atmos
atmos is both a command-line tool and Golang module for provisioning, managing and orchestrating workflows across various toolchains including terraform and helmfile.
The atmos tool is part of the SweetOps toolchain and was built to make DevOps and Cloud automation easier across multiple tools. It has direct support for automating Terraform, Helmfile. By utilizing Stacks, atmos enable you to effortlessly manage your Terraform and Helmfile Components from your local machine, in your CI/CD pipelines, or using spacelift.
Problem
A modern infrastructure depends on lots of various tools like terraform, packer, helmfile, helm, kubectl, docker, etc. All these tools have varying degrees of configuration support, but most are not optimized for defining DRY configurations across dozens or hundreds of environments. Moreover, the configuration format is very different between the tools, but usually, boils down to some kind of key-value configuration in either JSON or YAML. This lack of configuration consistency poses a problem when we want to make it easy to declaratively define the settings that end-users should care about.
Solution
We defined a “universal” configuration format that works for all the tools we use. When using terarform, helmfile, etc we design our components as reusable building blocks that accept simple declarative parameters and offload all business logic to the tools themselves.
We designed this configuration schema in YAML and added convenient and robust deep-merging strategies that allow configurations to extend to other configurations. As part of this, we support OOP concepts of mixins, inheritance, and multiple inheritances - but all applied to the configuration. We support YAML anchors to clean up complex blocks of configuration, folder structures, environment variables, and all kinds of tool-specific settings.
Alternatives
There are a number of alternative tools to atmos, that accomplish some aspect of it.
| Tool | Description | Website |
|---|---|---|
| terragrunt | https://github.com/gruntwork-io/terragrunt | |
| astro | https://github.com/uber/astro | |
| terraspace | https://github.com/boltops-tools/terraspace | |
| leverage | The Leverage CLI intended to orchestrate Leverage Reference Architecture for AWS | https://github.com/binbashar/leverage |
| opta | The next generation of Infrastructure-as-Code. Work with high-level constructs instead of getting lost in low-level cloud configuration | https://github.com/run-x/optahttps://docs.opta.dev/ |
| pterradactyl | Pterradactyl is a library developed to abstract Terraform configuration from the Terraform environment setup. | https://github.com/nike-inc/pterradactyl |
| terramate | Terramate is a tool for managing multiple terraform stacks | https://github.com/mineiros-io/terramate |
make (honorable mention) | Many companies (including cloudposse) start by leveraging make with Makefile and targets to call terraform. This is a tried and true way, but at the scale we help our customer operate didn’t work. We know, because we tried it for ~3 years and suffocated under the weight of environment variables and stink of complexity only a mother could love. | https://www.gnu.org/software/make/ |
What atmos is not:
-
An alternative to chef, puppet, or ansible. Instead,
atmosis the type of tool that would call these tools. -
An alternative to CI or CD systems. If anything, those systems will call
atmos.
Design Considerations
-
Keep it strictly declarative (no concept of iterators or interpolations)
-
Offload all imperative design to the underlying tools
-
Do not write a programming language in YAML (e.g. CloudFormation) or JSON (e.g. terraform or JSONNET, KSONNET)
-
Do not use any esoteric expressions (e.g. JSONNET)
-
Keep it Simple Stupid (KISS)
-
Ensure compatibility with multiple tools, not just
terraform -
Define all configuration in files and not based on filesystem conventions.
Usage
atmos help (actually, we still need to implement this 😵 after porting to golang)
IMPORTANT
Atmos underwent a complete rewrite from an esoteric task runner framework called variant2 into native Golang as of version 1.0. The documentation is not updated everywhere. The interface is identical/backward compatible (and enhanced), but some references to variant2 are inaccurate. You can assume this documentation is for the latest version of atmos.
Subcommands are positional arguments passed to the atmos command.
Subcommand: version
Show the current version
Subcommand: describe
Show the deep-merged configuration for stacks and components.
Subcommand: terraform
-
Supports all built-in Terraform Subcommands (we essentially pass them through to the
terraformcommand) -
deployis equivalent toatmos terraform apply -auto-approve -
generate backendis used to generate the staticbackend.tf.jsonfile that should be committed to VCS -
generate varfile(deprecated command:write varfile) — This command generates a varfile for a terraform component:atmos terraform generate varfile <component> -s <stack> -f <file> -
cleandeletes any orphaned varfiles or planfiles
Subcommand: helmfile
-
Supports all
helmfilesubcommands -
describe -
generate varfile— This command generates a varfile for a helmfile component:atmos helmfile generate varfile <component> -s <stack> -f <file>
Subcommand: workflow
This subcommand is temporarily unavailable as a result of a major refactor from variant2 to golang. We will reintroduce the subcommand and it has not been officially deprecated.
https://github.com/cloudposse/atmos
Latest Releases
https://github.com/cloudposse/atmos/releases
Open Issues
https://github.com/cloudposse/atmos/issues
Examples
Provision Terraform Component
To provision a Terraform component using the atmos CLI, run the following commands in the geodesic container shell:
atmos terraform plan eks --stack=ue2-dev
atmos terraform apply eks --stack=ue2-dev
Where:
-
eksis the Terraform component to provision (from thecomponents/terraformfolder) that is defined in the stack. If the component is not defined in the stack, it will error. -
--stack=ue2-devis the stack to provision the component into (or in other words, where to read the configuration)
You can pass any argument supported by terraform and it will be passed through to the system call to terraform.
e.g. We can pass the -destroy flag to terraform plan by running atmos terraform plan -destroy --stack=uw2-dev
Short versions of the command-line arguments can also be used:
atmos terraform plan eks -s ue2-dev
atmos terraform apply eks -s ue2-dev
To execute plan and apply in one step, use terrafrom deploy command:
atmos terraform deploy eks -s ue2-dev
Provision Terraform Component with Planfile
You can use a terraform planfile (previously generated with atmos terraform plan) in atmos terraform apply/deploy commands by running the following:
atmos terraform plan test/test-component-override -s tenant1/ue2/dev
atmos terraform apply test/test-component-override -s tenant1-ue2-dev --from-plan
atmos terraform deploy test/test-component-override -s tenant1-ue2-dev --from-plan