Configure Project Repository
Atmos supports both the monorepo and polyrepo architectures when managing the configurations for components and stacks.
A "monorepo" is a version-controlled repository that stores all the code, configurations and scripts for the entire infrastructure composed of individual components with independent lifecycles. Monorepos usually improve collaboration, CI/CD build speed, and overall productivity. A monorepo should not be confused with a monolith, which is a single, often large, codebase for an application.
Polyrepo architectures consists of several version-controlled repositories for code, configurations and scripts for different parts of the
infrastructure. For example, depending on various requirements (including security, lifecycle management, access control, audit, etc.), separate repositories can be used to manage infrastructure per account (e.g. dev, staging, prod), per service, or per team.
In this Quick Start guide, we will be using a monorepo to provision the following resources into multiple AWS accounts (dev, staging, prod)
and regions (us-east-2 and us-west-2):
Common Directories and Files
Atmos requires a few common directories and files, which need to be configured in the infrastructure repo:
componentsdirectory (required) - contains centralized component configurationsstacksdirectory (required) - contains centralized stack configurationsatmos.yaml(required) - CLI config filevendor.yaml(optional) - Atmos vendor config fileMakefile(optional)Dockerfile(optional)rootfsdirectory (optional) - root filesystem for the Docker image (ifDockerfileis used)
Atmos separates code from configuration (separation of concerns). The code is in the components directories and the configurations for different environments are in the stacks directory. This allows the code (Terraform and Helmfile components) to be environment-agnostic, meaning the components don't know and don't care how and where they will be provisioned. They can be provisioned into many accounts and regions - the configurations for different environments are defined in the stacks directory.
While it's recommended to use the directory names as shown above, the stacks and components directory names and filesystem locations are
configurable in the atmos.yaml CLI config file. Refer to Configure CLI for more details.
The following example provides the simplest filesystem layout that Atmos can work with:
│ # Centralized stacks configuration
├── stacks/
│ ├── <stack_1>.yaml
│ ├── <stack_2>.yaml
│ └── <stack_3>.yaml
│
│ # Centralized components configuration. Components are broken down by tool
├── components/
│ ├── terraform/ # Terraform components (Terraform root modules)
│ │ ├── <terraform_component_1>/
│ │ ├── <terraform_component_2>/
│ │ └── <terraform_component_3>/
│ └── helmfile/ # Helmfile components are organized by Helm chart
│ ├── <helmfile_component_1>/
│ ├── <helmfile_component_2>/
│ └── <helmfile_component_3>/
│
│ # Atmos CLI configuration
├── atmos.yaml
│ # Atmos vendoring configuration
└── vendor.yaml
atmos.yaml CLI Config File Location
While placing atmos.yaml at the root of the repository will work for the atmos CLI, it will not work
for Component Remote State because it uses
the terraform-provider-utils Terraform provider. Terraform executes the provider from the
component's folder (e.g. components/terraform/vpc), and we don't want to replicate atmos.yaml into every component's folder.
Both the atmos CLI and terraform-provider-utils Terraform provider use the same Go code,
which try to locate the CLI config atmos.yaml file before parsing and processing Atmos stacks.
This means that atmos.yaml file must be at a location in the file system where all processes can find it.
atmos.yaml is loaded from the following locations (from lowest to highest priority):
- System dir (
/usr/local/etc/atmos/atmos.yamlon Linux,%LOCALAPPDATA%/atmos/atmos.yamlon Windows) - Home dir (
~/.atmos/atmos.yaml) - Current directory
- ENV var
ATMOS_CLI_CONFIG_PATH
Initial Atmos configuration can be controlled by these ENV vars:
-
ATMOS_CLI_CONFIG_PATH- where to findatmos.yaml. Path to a folder where theatmos.yamlCLI config file is located (just the folder without the file name) -
ATMOS_BASE_PATH- base path tocomponentsandstacksfolders
For this to work for both the atmos CLI and the Terraform provider, we recommend doing one of the following:
-
Put
atmos.yamlat/usr/local/etc/atmos/atmos.yamlon local host and set the ENV varATMOS_BASE_PATHto point to the absolute path of the root of the repo -
Put
atmos.yamlinto the home directory (~/.atmos/atmos.yaml) and set the ENV varATMOS_BASE_PATHpointing to the absolute path of the root of the repo -
Put
atmos.yamlat a location in the file system and then set the ENV varATMOS_CLI_CONFIG_PATHto point to that location. The ENV var must point to a folder without theatmos.yamlfile name. For example, ifatmos.yamlis at/atmos/config/atmos.yaml, setATMOS_CLI_CONFIG_PATH=/atmos/config. Then set the ENV varATMOS_BASE_PATHpointing to the absolute path of the root of the repo -
When working in a Docker container, place
atmos.yamlin therootfsdirectory at /rootfs/usr/local/etc/atmos/atmos.yaml and then copy it into the container's file system in the Dockerfile by executing theCOPY rootfs/ /Docker command. Then in the Dockerfile, set the ENV varATMOS_BASE_PATHpointing to the absolute path of the root of the repo. Note that the Atmos Quick Start example uses Geodesic as the base Docker image. Geodesic sets the ENV varATMOS_BASE_PATHautomatically to the absolute path of the root of the repo on the local host
Final Filesystem Layout
Taking into account all the above, we can place atmos.yaml at /usr/local/etc/atmos/atmos.yaml on the local host and use the following filesystem
layout:
│ # Centralized stacks configuration
├── stacks/
│ ├── <stack_1>.yaml
│ ├── <stack_2>.yaml
│ └── <stack_3>.yaml
│
│ # Centralized components configuration. Components are broken down by tool
└── components/
└── terraform/ # Terraform components (Terraform root modules)
├── vpc/
└── vpc-flow-logs-bucket/
For a Quick Start example, refer to Atmos Quick Start