| name | developing-stacks |
| description | Use when deploying components via Atmos stacks, configuring stack YAML, or understanding inheritance patterns. Covers catalog defaults, abstract components, stack imports, and how to wire components into target stacks. |
Developing Stacks
Scope: This skill is specific to the acme infrastructure repository. It documents the
stack structure, naming conventions, and deployment patterns used here. For generic component development, see
developing-components.
Guide for configuring Atmos stacks to deploy Terraform components across environments.
Stack Architecture Overview
This repository uses a multi-tenant, multi-stage stack structure:
stacks/
āāā orgs/acme/ # Organization root (namespace: acme)
ā āāā _defaults.yaml # Org-wide defaults (namespace, backend, account_map)
ā āāā core/ # Core tenant (shared infrastructure)
ā ā āāā _defaults.yaml # Tenant defaults (tenant: core)
ā ā āāā root/ # Root account stage
ā ā ā āāā _defaults.yaml # Stage defaults + auth identity
ā ā ā āāā global-region/ # Global region (us-east-1)
ā ā ā āāā foundation.yaml
ā ā āāā auto/ # Automation account
ā ā āāā artifacts/ # Artifacts account (ECR, S3)
ā ā āāā audit/ # Audit/logging account
ā ā āāā network/ # Network account (TGW, VPN, DNS)
ā ā āāā security/ # Security account
ā āāā plat/ # Platform tenant (workloads)
ā āāā _defaults.yaml # Tenant defaults (tenant: plat)
ā āāā dev/ # Dev stage
ā ā āāā _defaults.yaml # Stage defaults + auth identity
ā ā āāā global-region/ # Global resources (IAM)
ā ā ā āāā foundation.yaml
ā ā āāā us-east-1/ # Primary region
ā ā āāā foundation.yaml # VPC, networking
ā ā āāā platform.yaml # ECS/EKS, databases
ā ā āāā app.yaml # Application resources
ā āāā staging/ # Staging stage
ā āāā prod/ # Production stage
ā āāā sandbox/ # Sandbox stage
āāā catalog/ # Component defaults library
ā āāā vpc/defaults.yaml
ā āāā ecs/defaults.yaml
ā āāā eks/cluster/defaults.yaml
ā āāā ...
āāā mixins/ # Reusable fragments
āāā region/us-east-1.yaml
āāā stage/dev.yaml
Stack name format: {namespace}-{tenant}-{region_short}-{stage}
Examples for this repository:
acme-core-use1-root - Core root account in us-east-1
acme-plat-use1-dev - Platform dev in us-east-1
acme-plat-use1-prod - Platform prod in us-east-1
Core Patterns
1. Catalog Defaults (Recommended Starting Point)
Define component defaults in stacks/catalog/<component>/defaults.yaml. These are imported into target stacks.
components:
terraform:
vpc/defaults:
metadata:
type: abstract
vars:
name: vpc
availability_zones: ["a", "b", "c"]
public_subnets_enabled: true
nat_gateway_enabled: true
max_subnet_count: 3
Key points:
- Use
type: abstract to prevent accidental deployment of the base configuration
- Name the component with a
/defaults suffix (e.g., vpc/defaults) to indicate it's a base
- Define sensible defaults that work across most environments
2. Inheriting into Target Stacks
Import the catalog and inherit from the abstract component in your target stack:
import:
- orgs/acme/plat/dev/_defaults
- mixins/region/us-east-1
- catalog/vpc/defaults
components:
terraform:
vpc:
metadata:
component: vpc
inherits:
- vpc/defaults
vars:
ipv4_primary_cidr_block: 10.2.0.0/16
Inheritance merging:
vars, settings, env, backend are deep-merged
- Later values override earlier ones
- The component's own
vars override inherited vars
3. Abstract Components
Abstract components (type: abstract) serve as base configurations that cannot be deployed directly.
vpc/defaults:
metadata:
type: abstract
vars:
nat_gateway_enabled: true
vpc:
metadata:
component: vpc
inherits:
- vpc/defaults
vars:
ipv4_primary_cidr_block: 10.0.0.0/16
Use abstract components when:
- Creating reusable base configurations
- Defining organization-wide defaults
- Building component "archetypes" (e.g.,
s3-bucket/logging, s3-bucket/public)
4. Multiple Inheritance
Components can inherit from multiple bases. Order matters - later items override earlier ones.
components:
terraform:
my-ecs-service:
metadata:
component: ecs-service
inherits:
- ecs-service/defaults
- ecs-service/web
vars:
service_name: my-app
5. Stack Defaults Hierarchy
The _defaults.yaml files create an inheritance chain:
vars:
namespace: acme
terraform:
backend_type: s3
backend:
s3:
bucket: acme-core-use1-root-tfstate
import:
- orgs/acme/_defaults
vars:
tenant: plat
import:
- orgs/acme/plat/_defaults
- mixins/stage/dev
auth:
identities:
plat-dev/terraform:
default: true
Deploying a Component
Step 1: Check if Catalog Defaults Exist
ls stacks/catalog/<component>/
If defaults exist, skip to Step 3.
Step 2: Create Catalog Defaults (if needed)
components:
terraform:
<component>/defaults:
metadata:
type: abstract
vars:
enabled: true
Step 3: Add to Target Stack
Edit the appropriate stack file (foundation.yaml, platform.yaml, app.yaml, etc.):
import:
- catalog/<component>/defaults
components:
terraform:
<component>:
metadata:
component: <component>
inherits:
- <component>/defaults
vars:
Step 4: Validate and Plan
atmos validate stacks
atmos describe component <component> -s acme-plat-use1-dev
atmos terraform plan <component> -s acme-plat-use1-dev
Stack File Organization
Stack files are organized by layer:
| File | Purpose | Examples |
|---|
foundation.yaml | Core infrastructure (VPC, DNS, TGW) | vpc, dns-delegated, bastion |
platform.yaml | Platform services (ECS, RDS, monitoring) | ecs, aurora-postgres, alb |
app.yaml | Application-specific resources | ecs-service, s3-bucket |
network.yaml | Network-specific (routes, peering) | vpc-routes, tgw-attachment |
monitor.yaml | Observability (CloudWatch, Grafana) | managed-grafana, alarms |
Common Patterns
Catalog Organization for Multiple Purposes
When deploying multiple instances of the same component for different purposes, organize the catalog with abstract
defaults and purpose-specific files that inherit from them:
stacks/catalog/
āāā <component>/
āāā defaults.yaml # Abstract base component (not deployed directly)
āāā <purpose>.yaml # Purpose-specific configuration
Abstract defaults file (stacks/catalog/<component>/defaults.yaml):
components:
terraform:
<component>/defaults:
metadata:
type: abstract
component: <component>
vars:
enabled: true
Purpose-specific catalog file (stacks/catalog/<component>/<purpose>.yaml):
import:
- catalog/<component>/defaults
components:
terraform:
<component>/<purpose>:
metadata:
component: <component>
inherits:
- <component>/defaults
vars:
name: <purpose>-specific-name
some_setting: override-value
Import in target stack:
import:
- catalog/<component>/<purpose>
Deploy:
atmos terraform plan <component>/<purpose> -s acme-plat-use1-dev
Environment-Specific CIDR Blocks
components:
terraform:
vpc/defaults:
metadata:
type: abstract
vars:
components:
terraform:
vpc:
metadata:
inherits: [vpc/defaults]
vars:
ipv4_primary_cidr_block: 10.2.0.0/16
components:
terraform:
vpc:
metadata:
inherits: [vpc/defaults]
vars:
ipv4_primary_cidr_block: 10.0.0.0/16
Cross-Component Dependencies
Use !terraform.state to wire outputs between components:
components:
terraform:
ecs/defaults:
metadata:
type: abstract
vars:
vpc_id: !terraform.state vpc vpc_id
subnet_ids: !terraform.state vpc private_subnet_ids
See the atmos-functions skill for more details.
Multiple Instances of a Component
Deploy multiple instances by using different component names:
components:
terraform:
vpc:
metadata:
component: vpc
inherits: [vpc/defaults]
vars:
ipv4_primary_cidr_block: 10.0.0.0/16
vpc/isolated:
metadata:
component: vpc
inherits: [vpc/defaults]
vars:
name: vpc-isolated
ipv4_primary_cidr_block: 10.100.0.0/16
Debugging Stack Configuration
atmos describe component <component> -s acme-plat-use1-dev
atmos describe stacks -s acme-plat-use1-dev
atmos validate stacks
For more debugging techniques, see the debugging-atmos skill.
References