Create Atmos Stacks
In the previous step, we've configured the Terraform components and described how they can be vendored into the repository.
Next step is to create and configure Atmos stacks.
Create Catalog for Components
Atmos supports the Catalog pattern to configure default settings for Atmos components.
All the common default settings for each Atmos component should be in a separate file in the stacks/catalog
directory.
The file then gets imported into the parent Atmos stacks.
This makes the stack configurations DRY by reusing the component's config that is common for all environments.
Refer to Stack Imports for more details on Atmos imports.
In the stacks/catalog/vpc-flow-logs-bucket/defaults.yaml
file, add the following manifest for the vpc-flow-logs-bucket
Atmos component:
stacks/catalog/vpc-flow-logs-bucket/defaults.yaml
In the stacks/catalog/vpc/defaults.yaml
file, add the following manifest for the vpc
Atmos component:
stacks/catalog/vpc.yaml
In the stacks/catalog/vpc/ue2.yaml
file, add the following manifest for the vpc
Atmos component:
stacks/catalog/vpc/ue2.yaml
In the stacks/catalog/vpc/uw2.yaml
file, add the following manifest for the vpc
Atmos component:
stacks/catalog/vpc/uw2.yaml
In the stacks/catalog/vpc/dev.yaml
file, add the following manifest for the vpc
Atmos component:
stacks/catalog/vpc/dev.yaml
In the stacks/catalog/vpc/staging.yaml
file, add the following manifest for the vpc
Atmos component:
stacks/catalog/vpc/staging.yaml
In the stacks/catalog/vpc/prod.yaml
file, add the following manifest for the vpc
Atmos component:
stacks/catalog/vpc/prod.yaml
These Atmos component manifests will be imported into the top-level Atmos stacks. The default variables (in the vars
sections)
can be overridden in the derived Atmos components by using Atmos Component Inheritance.
Atmos Top-level Stacks
When executing the CLI commands, Atmos does not use the stack file names and their filesystem locations to search for the stack
where the component is defined. Instead, Atmos uses the context variables (namespace
, tenant
, environment
, stage
) to search for the stack. The
stack config file names (stack manifest names) can be anything, and they can be in any folder in any sub-folder in the stacks
directory.
For example, when executing the atmos terraform apply vpc -s plat-ue2-dev
command, the Atmos stack plat-ue2-dev
is specified by the -s
flag. By looking at name_pattern: "{tenant}-{environment}-{stage}"
(see Configure CLI) and processing the tokens, Atmos knows that the first part of the stack name is tenant
, the second
part is environment
, and the third part is stage
. Then Atmos searches for the top-level stack manifest (in the stacks
directory)
where tenant: plat
, environment: ue2
and stage: dev
are defined (inline or via imports).
Atmos top-level stacks can be configured using a Basic Layout or a Hierarchical Layout.
The Basic Layout can be used when you have a very simple configuration using just a few accounts and regions. The Hierarchical Layout should be used when you have a very complex organization, for example, with many AWS Organizational Units (which Atmos refers to as tenants) and dozens of AWS accounts and regions.
Basic Layout
A basic form of stack organization is to follow the pattern of naming where each $environment-$stage.yaml
is a file. This works well until you have
so many environments and stages.
For example, $environment
might be ue2
(for us-east-2
) and $stage
might be prod
which would result in stacks/ue2-prod.yaml
Some resources, however, are global in scope. For example, Route53 and IAM might not make sense to tie to a region. These are what we call "global
resources". You might want to put these into a file like stacks/global-region.yaml
to connote that they are not tied to any particular region.
In our example, the filesystem layout for the stacks Basic Layout using dev
, staging
and prod
accounts and us-east-2
and us-west-2
regions
would look like this:
infra-live/
Hierarchical Layout
We recommend using a hierarchical layout that follows the way AWS thinks about infrastructure. This works very well when you may have dozens or hundreds of accounts and regions that you operate in.
Create Top-level Stacks
Although in this Quick Start guide we use just a few Terraform components which we want to provision into three AWS accounts in just two AWS regions (which could be considered basic), we will use the Hierarchical Layout to show how the Atmos stacks can be configured for very complex organizations and infrastructures.
We will assume we are using just one Organization acme
and just one AWS Organizational Unit (OU) plat
. But as you will notice, the layout
can be easily extended to support many AWS Organizations and Organizational Units.
Create the following filesystem layout (which will be the final layout for this Quick Start guide):
infra-live/
Configure Region and Stage Mixins
Mixins are a special kind of "import". It's simply a convention we recommend to distribute reusable snippets of configuration that alter the behavior in some deliberate way. Mixins are not handled in any special way. They are technically identical to all other imports.
In stacks/mixins/tenant/core.yaml
, add the following config:
stacks/mixins/tenant/core.yaml
In stacks/mixins/tenant/plat.yaml
, add the following config:
stacks/mixins/tenant/plat.yaml
In stacks/mixins/region/us-east-2.yaml
, add the following config:
stacks/mixins/region/us-east-2.yaml
In stacks/mixins/region/us-west-2.yaml
, add the following config:
stacks/mixins/region/us-west-2.yaml
In stacks/mixins/stage/dev.yaml
, add the following config:
stacks/mixins/stage/dev.yaml
In stacks/mixins/stage/prod.yaml
, add the following config:
stacks/mixins/stage/prod.yaml
In stacks/mixins/stage/staging.yaml
, add the following config:
stacks/mixins/stage/staging.yaml
As we can see, in the tenant, region and stage mixins, besides some other common variables, we are defining the global context
variables tenant
, environment
and stage
, which Atmos uses when searching for a component in a stack. These mixins then get imported into the
parent Atmos stacks without defining the context variables in each top-level stack, making the configuration DRY.
Configure Defaults for Organization, OU and accounts
The _defaults.yaml
files contain the default settings for the Organization(s), Organizational Units and accounts.
In stacks/orgs/acme/_defaults.yaml
, add the following config:
stacks/orgs/acme/_defaults.yaml
The file defines the context variable namespace
for the entire acme
Organization.
In stacks/orgs/acme/core/_defaults.yaml
, add the following config for the core
OU (tenant):
stacks/orgs/acme/core/_defaults.yaml
In stacks/orgs/acme/plat/_defaults.yaml
, add the following config for the plat
OU (tenant):
stacks/orgs/acme/plat/_defaults.yaml
In the stacks/orgs/acme/plat/_defaults.yaml
file, we import the defaults for the Organization and for the plat
tenant (which
corresponds to the plat
Organizational Unit). When Atmos processes this stack config, it will import and deep-merge all the variables defined in the
imported files and inline. All imports are processed in the order they are defined.
In stacks/orgs/acme/plat/dev/_defaults.yaml
, add the following config for the dev
account:
stacks/orgs/acme/plat/dev/_defaults.yaml
In the file, we import the mixin for the plat
tenant (which, as was described above, imports the defaults for the Organization), and then the mixin
for the dev
account (which defines stage: dev
variable). After processing all these imports, Atmos determines the values for the three context
variables namespace
, tenant
and stage
, which it then sends to the Terraform components as Terraform variables. We are using hierarchical imports
here.
Similar to the dev
account, add the following configs for the prod
and staging
accounts:
stacks/orgs/acme/plat/prod/_defaults.yaml
stacks/orgs/acme/plat/staging/_defaults.yaml
Configure Top-level Stacks
After we've configured the catalog for the components, the mixins for the tenants, regions and stages, and the defaults for the Organization, OU and accounts, the final step is to configure the Atmos root (top-level) stacks and the Atmos components in the stacks.
In stacks/orgs/acme/plat/dev/us-east-2.yaml
, add the following config:
stacks/orgs/acme/plat/dev/us-east-2.yaml
In the file, we import the region mixin and the defaults for the Organization, OU and account (using hierarchical imports).
Similarly, create the top-level Atmos stack for the dev
account in us-west-2
region:
stacks/orgs/acme/plat/dev/us-west-2.yaml
In stacks/orgs/acme/plat/staging/us-east-2.yaml
, add the following config:
stacks/orgs/acme/plat/staging/us-east-2.yaml
Similarly, create the top-level Atmos stack for the staging
account in us-west-2
region:
stacks/orgs/acme/plat/staging/us-west-2.yaml
In stacks/orgs/acme/plat/prod/us-east-2.yaml
, add the following config:
stacks/orgs/acme/plat/prod/us-east-2.yaml
In the file, we import the region mixin and the defaults for the Organization, OU and account (using hierarchical imports).
Similarly, create the top-level Atmos stack for the prod
account in us-west-2
region: