:wave: Hey all! We're evaluating Atmos (alongside ...
# atmos
o
👋 Hey all! We're evaluating Atmos (alongside some other tools/frameworks) for a pretty complex existing Terraform setup. We manage many deployments across cloud providers, accounts, regions, and tenancy models (multi/single-tenant). Each has a "type" with its own blueprint of Terraform code + a tfvars file per deployment. Works fine today, but only for monostates - so we are looking for something more flexible. We'd like a pattern like this: - A top-level stack per deployment (e.g.
mt-prod-us
,
lt-prod-us-customer1
) - Each top-level stack only needs two things: 1) an import for its deployment type, and 2) deployment-specific vars - Blueprints are composable - a blueprint imports layers, layers import components Example top-level stack:
Copy code
yaml
# stacks/mt/prod-us.yml
name: mt-prod-us

import:
  - catalog/blueprints/mt

vars:
  stage: prod
  region: us-east-1
  cidr_block: "1.1.1.0/24"
  rds_instance_type: "db.r5.12xlarge"
Blueprint stack:
Copy code
yaml
# catalog/blueprints/mt.yml
import:
  - catalog/layers/aws/networking
  - catalog/layers/aws/compute
  - catalog/layers/aws/storage
Each Layer would import some number of Components, such as vpc, subnets, etc. for the networking layer. This looks similar to the Layered Stack Configuration pattern in the docs. My main question is around var precedence: how do I set a default (e.g.
cidr_block: 192.168.0.0/24
) in a blueprint/layer/component, but allow a top-level stack to override it? Two options I see: 1. Drop the blueprint layer and list all layer imports directly in each top-level stack - but this risks drift between deployments over time, so probably a no-go for us 2. Use
overrides.vars
in the top-level stack instead of
vars
- seems to work in testing, but not sure if this is an anti-pattern Is option 2 the right approach here, or is there a better pattern for this? Thanks! 🙏
e
@Orion7X this is a perfect use case for Atmos. It's routinely used across multiple cloud providers such as Azure, GCP, AWS, and more.
We recently published the following page: https://atmos.tools/multi-cloud
https://atmos.tools/design-patterns/stack-organization/multi-cloud-configuration And it also lays out some design patterns for organizing your stacks.
My main question is around var precedence: how do I set a default (e.g.
cidr_block: 192.168.0.0/24
) in a blueprint/layer/component, but allow a top-level stack to override it?
This is the primary way all inheritance works that Atmos is optimized for.
Simply set your default CIDR range (whatever you want), or don't set it at all, in your catalog, in the stack configurations that you're going to import.
Then, in your deployment stacks, your top-level stacks, you're going to set the variable that you want. In general:
Copy code
# stacks/mt/prod-us.yml (this file)

import:
- something1.yaml # your defaults
- something2.yaml # this overrides something1 (deep merges on top of it)

# here's where you override anything you want after processing imports
components:
  terraform: 
    vpc:
      vars:
        cidr_block: 192.168.0.0/24 # this has highest presedence
In Atmos, the importing file’s values always override the imported file’s values — at the same YAML path.
o
Thanks for the thorough response, @Erik Osterman (Cloud Posse)! I did look at the Multi-Cloud related docs and those are really helpful. While pondering your response, I realize I made a mistake in my testing, which was causing my confusion. In the top-level stack, I set
cidr_block
in
vars.cidr_block
, but in the nested vpc defaults.yaml, I set
cidr_block
in
components.terraform.vpc.vars.cidr_block
, so the nested defaults were overriding my settings in the top-level stack file. After I put
cidr_block
in the component vars in the top-level file, the right value was applied. More specifically... What I was doing that wasn't working resulted in:
Copy code
❯ atmos describe component vpc -s mt-prod-us | yq .sources.vars.cidr_block
final_value: 192.168.55.0/24
name: cidr_block
stack_dependencies:
  - dependency_type: import
    stack_file: catalog/components/aws/vpc/defaults
    stack_file_section: components.terraform.vars
    variable_value: 192.168.55.0/24
  - dependency_type: inline
    stack_file: deploy/mt/prod-us
    stack_file_section: vars
    variable_value: 1.1.1.0/24
After correcting my mistage:
Copy code
❯ atmos describe component vpc -s mt-prod-us | yq .sources.vars.cidr_block
final_value: 1.1.1.0/24
name: cidr_block
stack_dependencies:
  - dependency_type: inline
    stack_file: deploy/mt/prod-us
    stack_file_section: components.terraform.vars
    variable_value: 1.1.1.0/24
  - dependency_type: import
    stack_file: catalog/components/aws/vpc/defaults
    stack_file_section: components.terraform.vars
    variable_value: 192.168.55.0/24
a
@Orion7X are you having any more issues? regarding to what Erik mentioned, please review https://atmos.tools/design-patterns/inline-component-configuration#inline-customization-of-imported-defaults
o
I'll be doing more testing over the next couple of weeks. I'll reach back out with any questions. Thanks for your support!
👍 1
Is this (screenshot) saying that using
depends_on
with the Github Actions workflow doesn't have any effect? If so, is there any sort of workaround? Thanks
e
There's no way to do this in GitHub Actions, because it's impossible to create dynamic job dependencies.
The good news, is you can install the Atmos Pro github app, which unlocks that.
👍 1
(note, we have some big improvements coming to this in the next week, including an entirely overhauled dashboard)
o
Thanks, I'll check it out!