Inline Configuration
Inline Configuration patterns define components directly within stack manifests. This includes both fully inline configurations (no imports) and inline customizations of imported defaults.
If you're starting with Atmos, inline configurations are the easiest to understand until you need more advanced features.
Fully Inline Configuration
The simplest approach: define all component configuration directly in each stack manifest without importing any base configurations.
Use-cases
Use fully inline configuration when:
-
You have a very simple organizational structure, e.g. one OU, one or a few accounts, one region
-
You have a component that is provisioned only in one stack (e.g. only in the
devaccount). In this case, the component is configured inline in the stack manifest and is not used in other stacks -
For testing or development purposes
Benefits
-
Very simple stack and component configurations
-
Define all components in just one place (in one stack manifest) so it's easier to see what and where everything is provisioned
Example
Suppose you need a simple setup with only dev, staging and prod stages (accounts). Here's how you might organize the stacks and
inline-component configuration for the vpc and vpc-flow-logs-bucket components.
│ # Centralized stacks configuration (stack manifests)
├── stacks
│ ├── dev.yaml
│ ├── staging.yaml
│ └── prod.yaml
│
│ # Centralized components configuration
└── components
└── terraform # Terraform components (a.k.a Terraform "root" modules)
├── vpc
├── vpc-flow-logs-bucket
├── < other components >
Add the following minimal configuration to atmos.yaml CLI config file :
components:
terraform:
base_path: "components/terraform"
stacks:
base_path: "stacks"
name_template: "{{.vars.stage}}"
Add the following component configurations to the stacks/dev.yaml stack manifest:
vars:
stage: dev
components:
terraform:
vpc-flow-logs-bucket:
metadata:
# Point to the Terraform component
component: vpc-flow-logs-bucket
vars:
enabled: true
name: "vpc-flow-logs"
traffic_type: "ALL"
force_destroy: true
lifecycle_rule_enabled: false
vpc:
metadata:
# Point to the Terraform component
component: vpc
settings:
# All validation steps must succeed to allow the component to be provisioned
validation:
validate-vpc-component-with-jsonschema:
schema_type: jsonschema
schema_path: "vpc/validate-vpc-component.json"
description: Validate 'vpc' component variables using JSON Schema
check-vpc-component-config-with-opa-policy:
schema_type: opa
schema_path: "vpc/validate-vpc-component.rego"
# An array of filesystem paths (folders or individual files) to the additional modules for schema validation
# Each path can be an absolute path or a path relative to `schemas.opa.base_path` defined in `atmos.yaml`
# In this example, we have the additional Rego modules in `stacks/schemas/opa/catalog/constants`
module_paths:
- "catalog/constants"
description: Check 'vpc' component configuration using OPA policy
vars:
enabled: true
name: "common"
max_subnet_count: 3
map_public_ip_on_launch: true
assign_generated_ipv6_cidr_block: false
nat_gateway_enabled: true
nat_instance_enabled: false
vpc_flow_logs_enabled: true
vpc_flow_logs_traffic_type: "ALL"
vpc_flow_logs_log_destination_type: "s3"
nat_eip_aws_shield_protection_enabled: false
subnet_type_tag_key: "acme/subnet/type"
ipv4_primary_cidr_block: 10.9.0.0/18
To provision the components, execute the following commands:
# `dev` stack
atmos terraform apply vpc-flow-logs-bucket -s dev
atmos terraform apply vpc -s dev
Limitations
-
If you have more than one stack (e.g.
dev,staging,prod), then the component definitions would be repeated in the stack manifests, which makes them not reusable and the entire stack configuration not DRY -
Should be used only for specific use-cases (e.g. you have just one stack, or you are designing and testing the components)
Inline Customization of Imported Defaults
A more powerful approach: define default component configurations in separate manifests, import them into top-level stacks, and customize inline as needed.
Use-cases
Use inline customization when:
-
You have components that are provisioned in multiple stacks (e.g.
dev,staging,prodaccounts) with different configurations for each stack -
You need to make the components' default/baseline configurations reusable across different stacks
-
You want to keep the configurations DRY
Benefits
-
The defaults for the components are defined in just one place making the entire configuration DRY
-
The defaults for the components are reusable across many stacks
-
Simple stack and component configurations
Example
Suppose you need a simple setup with only dev, staging and prod stages (accounts). Here's how you might organize the stacks and
component configurations for the vpc and vpc-flow-logs-bucket components, and then customize the components in the stacks.
│ # Centralized stacks configuration (stack manifests)
├── stacks
│ ├── defaults # component-specific defaults
│ │ ├── vpc-flow-logs-bucket.yaml
│ │ └── vpc.yaml
│ ├── dev.yaml
│ ├── staging.yaml
│ └── prod.yaml
│
│ # Centralized components configuration
└── components
└── terraform # Terraform components (a.k.a Terraform "root" modules)
├── vpc
├── vpc-flow-logs-bucket
├── < other components >
Add the following minimal configuration to atmos.yaml CLI config file :
components:
terraform:
base_path: "components/terraform"
stacks:
base_path: "stacks"
name_template: "{{.vars.stage}}"
excluded_paths:
# Tell Atmos that the `defaults` folder and all sub-folders don't contain top-level stack manifests
- "defaults/**/*"
Add the following default configuration to the stacks/defaults/vpc-flow-logs-bucket.yaml manifest:
components:
terraform:
vpc-flow-logs-bucket:
metadata:
# Point to the Terraform component
component: vpc-flow-logs-bucket
vars:
enabled: true
name: "vpc-flow-logs"
traffic_type: "ALL"
force_destroy: true
lifecycle_rule_enabled: false
Add the following default configuration to the stacks/defaults/vpc.yaml manifest:
components:
terraform:
vpc:
metadata:
# Point to the Terraform component
component: vpc
settings:
# All validation steps must succeed to allow the component to be provisioned
validation:
validate-vpc-component-with-jsonschema:
schema_type: jsonschema
schema_path: "vpc/validate-vpc-component.json"
description: Validate 'vpc' component variables using JSON Schema
check-vpc-component-config-with-opa-policy:
schema_type: opa
schema_path: "vpc/validate-vpc-component.rego"
# An array of filesystem paths (folders or individual files) to the additional modules for schema validation
# Each path can be an absolute path or a path relative to `schemas.opa.base_path` defined in `atmos.yaml`
# In this example, we have the additional Rego modules in `stacks/schemas/opa/catalog/constants`
module_paths:
- "catalog/constants"
description: Check 'vpc' component configuration using OPA policy
vars:
enabled: true
name: "common"
max_subnet_count: 3
map_public_ip_on_launch: true
assign_generated_ipv6_cidr_block: false
nat_gateway_enabled: true
nat_instance_enabled: false
vpc_flow_logs_enabled: true
vpc_flow_logs_traffic_type: "ALL"
vpc_flow_logs_log_destination_type: "s3"
nat_eip_aws_shield_protection_enabled: false
subnet_type_tag_key: "acme/subnet/type"
ipv4_primary_cidr_block: 10.9.0.0/18
Configure the stacks/dev.yaml top-level stack manifest:
vars:
stage: dev
# Import the component default configurations
import:
- defaults/vpc
components:
terraform:
# Customize the `vpc` component for the `dev` account
# You can define variables or override the imported defaults
vpc:
vars:
max_subnet_count: 2
vpc_flow_logs_enabled: false
Configure the stacks/staging.yaml top-level stack manifest:
vars:
stage: staging
# Import the component default configurations
import:
- defaults/vpc-flow-logs-bucket
- defaults/vpc
components:
terraform:
# Customize the `vpc` component for the `staging` account
# You can define variables or override the imported defaults
vpc:
vars:
map_public_ip_on_launch: false
vpc_flow_logs_traffic_type: "REJECT"
Configure the stacks/prod.yaml top-level stack manifest:
vars:
stage: prod
# Import the component default configurations
import:
- defaults/vpc-flow-logs-bucket
- defaults/vpc
components:
terraform:
# Customize the `vpc` component for the `prod` account
# You can define variables or override the imported defaults
vpc:
vars:
map_public_ip_on_launch: false
To provision the components, execute the following commands:
# `dev` stack
atmos terraform apply vpc -s dev
# `staging` stack
atmos terraform apply vpc-flow-logs-bucket -s staging
atmos terraform apply vpc -s staging
# `prod` stack
atmos terraform apply vpc-flow-logs-bucket -s prod
atmos terraform apply vpc -s prod
Limitations
-
The pattern is useful to customize components per account or region, but if you have more than one Organization, Organizational Unit (OU) or region, then the inline customizations would be repeated in the stack manifests, making the entire stack configuration not DRY
-
Should be used only for specific use-cases, e.g. when you use just one region, Organization or Organizational Unit (OU)
When to Use Each Approach
| Scenario | Recommended Approach |
|---|---|
| Learning Atmos or prototyping | Fully inline |
| Single environment deployment | Fully inline |
| Few environments, some shared config | Inline customization |
| Multi-region, multi-account | Consider Configuration Catalog |