Releases: cloudposse/atmos
v1.33.2
what
- Rename
atmos describe dependants
toatmos describe dependents
- Add alias to allow
atmos describe dependants
why
- There are two acceptable ways to spell
dependent
depending (no pun intended) on whether you are speaking American English (dependent) or British English (dependant)
v1.33.1
v1.33.0
what
- Update Atmos logs
- Add
logs.file
andlogs.level
toatmos.yaml
- Update docs https://atmos.tools/cli/configuration
why
- Allow specifying a file for Atmos to write logs to
- Allow specifying a log level to control the amount of Atmos logging
Logs
Atmos logs are configured in the logs
section:
logs:
file: "/dev/stdout"
# Supported log levels: Trace, Debug, Info, Warning, Off (Off is the default and is used if logs.level is not set)
level: Info
-
logs.file
- the file to write Atmos logs to. Logs can be written to any file or any standard file descriptor, including/dev/stdout
,/dev/stderr
and/dev/null
). If omitted,/dev/stdout
will be used. The ENV variableATMOS_LOGS_FILE
can also be used to specify the log file -
logs.level
- Log level. Supported log levels areOff
,Trace
,Info
. If the log level is set toOff
, Atmos will not log any messages (note that this does not prevent other tools like Terraform from logging). The ENV variableATMOS_LOGS_LEVEL
can also be used to specify the log level
To prevent Atmos from logging any messages, you can do one of the following:
-
Set
logs.file
or the ENV variableATMOS_LOGS_FILE
to/dev/null
-
Set
logs.level
or the ENV variableATMOS_LOGS_LEVEL
toOff
v1.32.5
what && why
- Add docs for the new Atmos GitHub Actions
references
v1.32.4
what
- Update
atmos describe affected
command
why
- Check if not only the files in the component folder itself have changed, but also the files in all sub-folders at any level
test
For example, if we have the policies
sub-folder in the component folder components/terraform/top-level-component1
, and we have some files in the sub-folder (e.g. components/terraform/top-level-component1/policies/policy1.rego
), and if the files changed, atmos describe affected
would mark all Atmos components that use the components/terraform/top-level-component1
Terraform component as changed:
Cloning repo 'https://github.com/cloudposse/atmos' into the temp dir '/var/folders/g5/lbvzy_ld2hx4mgrgyp19bvb00000gn/T/16797114913176545339'
Checking out Git ref 'refs/heads/master' ...
Enumerating objects: 4320, done.
Counting objects: 100% (105/105), done.
Compressing objects: 100% (70/70), done.
Total 4320 (delta 39), reused 56 (delta 22), pack-reused 4215
Checked out Git ref 'refs/heads/master'
Current working repo HEAD: 2d995c21cb3fff46f39da1eeadb9d7b0f8faf72c refs/heads/update-describe-affected-2
Remote repo HEAD: 38b8fe6ca1221e16f0b969815bddfe98928cd1b5 refs/heads/master
Getting current working repo commit object...
Got current working repo commit object
Getting current working repo commit tree...
Got current working repo commit tree
Getting remote repo commit object...
Got remote repo commit object
Getting remote repo commit tree...
Got remote repo commit tree
Finding diff between the current working branch and remote target branch ...
Found diff between the current working branch and remote target branch
Changed files:
examples/complete/components/terraform/top-level-component1/policies/policy1.rego
Affected components and stacks:
- component: top-level-component1
component_type: terraform
component_path: examples/complete/components/terraform/top-level-component1
stack: tenant1-ue2-prod
stack_slug: tenant1-ue2-prod-top-level-component1
spacelift_stack: tenant1-ue2-prod-top-level-component1
atlantis_project: tenant1-ue2-prod-top-level-component1
affected: component
- component: top-level-component1
component_type: terraform
component_path: examples/complete/components/terraform/top-level-component1
stack: tenant2-ue2-staging
stack_slug: tenant2-ue2-staging-top-level-component1
spacelift_stack: tenant2-ue2-staging-top-level-component1
atlantis_project: tenant2-ue2-staging-top-level-component1
affected: component
- component: top-level-component1
component_type: terraform
component_path: examples/complete/components/terraform/top-level-component1
stack: tenant1-ue2-staging
stack_slug: tenant1-ue2-staging-top-level-component1
spacelift_stack: tenant1-ue2-staging-top-level-component1
atlantis_project: tenant1-ue2-staging-top-level-component1
affected: component
- component: top-level-component1
component_type: terraform
component_path: examples/complete/components/terraform/top-level-component1
stack: tenant1-ue2-test-1
stack_slug: tenant1-ue2-test-1-top-level-component1
spacelift_stack: tenant1-ue2-test-1-top-level-component1
atlantis_project: tenant1-ue2-test-1-top-level-component1
affected: component
- component: top-level-component2
component_type: terraform
component_path: examples/complete/components/terraform/top-level-component1
stack: tenant1-ue2-test-1
stack_slug: tenant1-ue2-test-1-top-level-component2
atlantis_project: tenant1-ue2-test-1-top-level-component2
affected: component
- component: top-level-component1
component_type: terraform
component_path: examples/complete/components/terraform/top-level-component1
stack: tenant2-ue2-dev
stack_slug: tenant2-ue2-dev-top-level-component1
spacelift_stack: tenant2-ue2-dev-top-level-component1
atlantis_project: tenant2-ue2-dev-top-level-component1
affected: component
- component: top-level-component1
component_type: terraform
component_path: examples/complete/components/terraform/top-level-component1
stack: tenant2-ue2-prod
stack_slug: tenant2-ue2-prod-top-level-component1
spacelift_stack: tenant2-ue2-prod-top-level-component1
atlantis_project: tenant2-ue2-prod-top-level-component1
affected: component
- component: top-level-component1
component_type: terraform
component_path: examples/complete/components/terraform/top-level-component1
stack: tenant1-ue2-dev
stack_slug: tenant1-ue2-dev-top-level-component1
spacelift_stack: tenant1-ue2-dev-top-level-component1
atlantis_project: tenant1-ue2-dev-top-level-component1
affected: component
- component: vpc
component_type: terraform
component_path: examples/complete/components/terraform/infra/vpc
stack: tenant1-ue2-dev
stack_slug: tenant1-ue2-dev-vpc
spacelift_stack: tenant1-ue2-dev-vpc
atlantis_project: tenant1-ue2-dev-vpc
affected: stack.vars
v1.32.3
v1.32.2
v1.32.1
what
- Update
atmos describe affected
command
why
- Handle
atmos
absolute base path when working with the cloned remote repo in thedescribe affected
command - Absolute base path can be set in the
base_path
attribute inatmos.yaml
, or using the ENV varATMOS_BASE_PATH
(as it's done ingeodesic
) - If the
atmos
base path is absolute, find the relative path between the local repo path and theatmos
base path. This relative path (the difference) is then used to join with the remote (cloned) repo path
v1.32.0
what
- Add
Hierarchical Inheritance
andMultilevel Inheritance
for Atmos Components - Update docs https://atmos.tools/core-concepts/components/inheritance
why
- Allow creating complex hierarchical stack configurations and make them DRY
- In Hierarchical Inheritance, every component can act as a base component for one or more child (derived) components, and each child component can inherit from one of more base components.
description
Multilevel Inheritance
Multilevel Inheritance is used when an Atmos component inherits from a base Atmos component, which in turn inherits from another base Atmos component.
In the diagram below, ComponentC
directly inherits from ComponentB
.
ComponentB
directly inherits from ComponentA
.
After this Multilevel Inheritance chain gets processed by Atmos, ComponentC
will inherit all the configurations (vars
, settings
, env
and other sections) from both ComponentB
and ComponentA
.
Note that ComponentB
overrides the values from ComponentA
. ComponentC
overrides the values from both ComponentB
and ComponentA
.
classDiagram
ComponentA --> ComponentB
ComponentB --> ComponentC
ComponentA : vars
ComponentA : settings
ComponentA : env
class ComponentB {
vars
settings
env
metadata:
inherits:
- ComponentA
}
class ComponentC {
vars
settings
env
metadata:
inherits:
- ComponentB
}
Hierarchical Inheritance
Hierarchical Inheritance is a combination of Multiple Inheritance and Multilevel Inheritance.
In Hierarchical Inheritance, every component can act as a base component for one or more child (derived) components, and each child component can inherit from one of more base components.
classDiagram
ComponentA --> ComponentB
ComponentA --> ComponentC
ComponentB --> ComponentD
ComponentB --> ComponentE
ComponentC --> ComponentF
ComponentC --> ComponentG
ComponentH --> ComponentE
ComponentI --> ComponentG
ComponentA : vars
ComponentA : settings
ComponentA : env
class ComponentB {
vars
settings
env
metadata:
inherits:
- ComponentA
}
class ComponentC {
vars
settings
env
metadata:
inherits:
- ComponentA
}
class ComponentD {
vars
settings
env
metadata:
inherits:
- ComponentB
}
class ComponentE {
vars
settings
env
metadata:
inherits:
- ComponentB
- ComponentH
}
class ComponentF {
vars
settings
env
metadata:
inherits:
- ComponentC
}
class ComponentG {
vars
settings
env
metadata:
inherits:
- ComponentI
- ComponentC
}
class ComponentH {
vars
settings
env
}
class ComponentI {
vars
settings
env
}
In the diagram above:
-
ComponentA
is the base component of the whole hierarchy -
ComponentB
andComponentC
inherit fromComponentA
-
ComponentD
inherits fromComponentB
directly, and fromComponentA
via Multilevel Inheritance -
ComponentE
is an example of using both Multiple Inheritance and Multilevel Inheritance.
It inherits fromComponentB
andComponentH
directly, and fromComponentA
via Multilevel Inheritance
For ComponentE
, the inherited components are processed and deep-merged in the order they are specified in the inherits
list:
-
ComponentB
overrides the configuration fromComponentA
-
ComponentH
overrides the configuration fromComponentB
andComponentA
(since it's defined afterComponentB
in theinherits
section) -
And finally,
ComponentE
overridesComponentH
,ComponentB
andComponentA
For ComponentG
:
-
ComponentI
is processed first (since it's the first item in theinherits
list) -
Then
ComponentA
is processed (since it's the base component forComponentC
which is the second item in theinherits
list) -
Then
ComponentC
is processed, and it overrides the configuration fromComponentA
andComponentI
-
And finally,
ComponentG
is processed, and it overridesComponentC
,ComponentA
andComponentI
Hierarchical Inheritance Example
Let's consider the following configuration for Atmos components base-component-1
, base-component-2
, derived-component-1
and derived-component-2
:
components:
terraform:
base-component-1:
metadata:
type: abstract
vars:
hierarchical_inheritance_test: "base-component-1"
base-component-2:
metadata:
type: abstract
vars:
hierarchical_inheritance_test: "base-component-2"
derived-component-1:
metadata:
component: "test/test-component"
inherits:
- base-component-1
vars: {}
derived-component-2:
metadata:
component: "test/test-component"
inherits:
- base-component-2
- derived-component-1
vars: {}
This configuration can be represented by the following diagram:
classDiagram
`base-component-1` --> `derived-component-1`
`derived-component-1` --> `derived-component-2`
`base-component-2` --> `derived-component-2`
class `base-component-1` {
settings
env
vars:
hierarchical_inheritance_test: base-component-1
}
class `base-component-2` {
settings
env
vars:
hierarchical_inheritance_test: base-component-2
}
class `derived-component-1` {
settings
env
vars
metadata:
inherits:
- base-component-1
}
class `derived-component-2` {
settings
env
vars
metadata:
inherits:
- base-component-2
- derived-component-1
}
In the configuration above, derived-component-1
inherits from base-component-1
.
derived-component-2
inherits from base-component-2
and derived-component-1
via Multiple Inheritance, and from base-component-1
via Multilevel Inheritance.
The derived-component-2
component is processed in the following order:
-
base-component-2
is processed first (since it's the first item in theinherits
list) -
Then
base-component-1
is processed (since it's the base component forderived-component-1
which is the second item in theinherits
list), and
it overrides the configuration frombase-component-2
-
Then
derived-component-1
is processed, and it overrides the configuration frombase-component-2
andbase-component-1
-
And finally,
derived-component-2
is processed, and it overridesderived-component-1
,base-component-1
andbase-component-2
When we run the following command to provision the derived-component-2
component:
atmos terraform plan derived-component-2 -s tenant1-ue2-test-1
Atmos will show the following output:
Variables for the component 'derived-component-2' in the stack 'tenant1-ue2-test-1':
environment: ue2
hierarchical_inheritance_test: base-component-1
namespace: cp
region: us-east-2
stage: test-1
tenant: tenant1
Command info:
Terraform binary: terraform
Terraform command: plan
Component: derived-component-2
Terraform component: test/test-component
Inheritance: derived-component-2 -> derived-component-1 -> base-component-1 -> base-component-2
Note that the hierarchical_inheritance_test
variable was inherited from base-component-1
because it overrode the configuration from base-component-2
.
If we change the order of the components in the inherits
list for derived-component-2
:
components:
terraform:
derived-component-2:
metadata:
component: "test/test-component"
inherits:
- derived-component-1
- base-component-2
vars: {}
base-component-2
will be processed after base-component-1
and derived-component-1
, and the hierarchical_inheritance_test
variable will be inherited from base-component-2
:
Variables for the component 'derived-component-2' in the stack 'tenant1-ue2-test-1':
environment: ue2
hierarchical_inheritance_test: base-component-2
namespace: cp
region: us-east-2
stage: test-1
tenant: tenant1
Command info:
Terraform binary: terraform
Terraform command: plan
Component: derived-component-2
Terraform component: test/test-component
Inheritance: derived-component-2 -> base-component-2 -> derived-component-1 -> base-component-1
v1.31.0
what
- Fix an issue when the terraform components were in subfolders in the
components/terraform
folder deeper than the second level - Add
atmos describe dependants
command - Update docs
why
-
Fix an issue when the terraform components were in subfolders in the
components/terraform
folder deeper than second level. For example:The component
test-component-2
is in the subfoldercomponents/terraform/test/test2
, for which the filesystem path to the generatedvarfile
was created incorrectly (when used justcomponents/terraform/test
subfolder, it was correct). The PR fixes the issue, and now components can be in any subfolder at any level. -
The
atmos describe dependants
command produces a list of Atmos components in Atmos stacks that depend on the provided Atmos component
description
In Atmos, you can define component dependencies by using the settings.depends_on
section. The section used to define all the Atmos components (in the same or different stacks) that the current component depends on.
The settings.depends_on
section is a map of objects. The map keys are just the descriptions of dependencies and can be strings or numbers. Provide meaningful descriptions so that people can understand what the dependencies are about.
Each object in the settings.depends_on
section has the following schema:
component
(required) - an Atmos component that the current component depends onnamespace
(optional) - thenamespace
where the Atmos component is provisionedtenant
(optional) - thetenant
where the Atmos component is provisionedenvironment
(optional) - theenvironment
where the Atmos component is provisionedstage
(optional) - thestage
where the Atmos component is provisioned
The component
attribute is required. The rest are the context variables and are used to define Atmos stacks other than the current stack. For example, you can specify:
namespace
if thecomponent
is from a different Organizationtenant
if thecomponent
is from a different Organizational Unitenvironment
if thecomponent
is from a different regionstage
if thecomponent
is from a different accounttenant
,environment
andstage
if the component is from a different Atmos stack (e.g.tenant1-ue2-dev
)
In the following example, we define that the top-level-component1
component depends on the following:
- The
test/test-component-override
component in the same Atmos stack - The
test/test-component
component in Atmos stacks identified by thedev
stage - The
my-component
component from thetenant1-ue2-staging
Atmos stack
components:
terraform:
top-level-component1:
settings:
depends_on:
1:
# If the `context` (namespace, tenant, environment, stage) is not provided,
# the `component` is from the same Atmos stack as this component
component: "test/test-component-override"
2:
# This component (in any stage) depends on `test/test-component`
# from the `dev` stage (in any `environment` and any `tenant`)
component: "test/test-component"
stage: "dev"
3:
# This component depends on `my-component`
# from the `tenant1-ue2-staging` Atmos stack
component: "my-component"
tenant: "tenant1"
environment: "ue2"
stage: "staging"
vars:
enabled: true
In the following example, we specify that the top-level-component2
component depends on the following:
- The
test/test-component
component in the same Atmos stack - The
test/test2/test-component-2
component in the same Atmos stack
components:
terraform:
top-level-component2:
metadata:
component: "top-level-component1"
settings:
depends_on:
1:
# If the `context` (namespace, tenant, environment, stage) is not provided,
# the `component` is from the same Atmos stack as this component
component: "test/test-component"
2:
# If the `context` (namespace, tenant, environment, stage) is not provided,
# the `component` is from the same Atmos stack as this component
component: "test/test2/test-component-2"
vars:
enabled: true
Having the top-level-component
and top-level-component2
components configured as shown above, we can now execute the following Atmos command to show all the components and stacks that are dependants of the test/test-component
component in the tenant1-ue2-dev
stack:
atmos describe dependants test/test-component -s tenant1-ue2-dev
[
{
"component": "top-level-component1",
"component_type": "terraform",
"component_path": "examples/complete/components/terraform/top-level-component1",
"namespace": "cp",
"tenant": "tenant1",
"environment": "ue2",
"stage": "dev",
"stack": "tenant1-ue2-dev",
"spacelift_stack": "tenant1-ue2-dev-top-level-component1",
"atlantis_project": "tenant1-ue2-dev-top-level-component1"
}
]
Similarly, the following Atmos command shows all the components and stacks that are dependants of the test/test-component
component in the tenant1-ue2-test-1
stack:
atmos describe dependants test/test-component -s tenant1-ue2-test-1
[
{
"component": "top-level-component1",
"component_type": "terraform",
"component_path": "examples/complete/components/terraform/top-level-component1",
"namespace": "cp",
"tenant": "tenant1",
"environment": "ue2",
"stage": "test-1",
"stack": "tenant1-ue2-test-1",
"spacelift_stack": "tenant1-ue2-test-1-top-level-component1",
"atlantis_project": "tenant1-ue2-test-1-top-level-component1"
},
{
"component": "top-level-component2",
"component_type": "terraform",
"component_path": "examples/complete/components/terraform/top-level-component1",
"namespace": "cp",
"tenant": "tenant1",
"environment": "ue2",
"stage": "test-1",
"stack": "tenant1-ue2-test-1",
"atlantis_project": "tenant1-ue2-test-1-top-level-component2"
}
]
After the test/test-component
has been provisioned, you can use the outputs to perform the following actions:
-
Provision the dependent components by executing the Atmos commands
atmos terraform apply top-level-component1 -s tenant1-ue2-test-1
andatmos terraform apply top-level-component2 -s tenant1-ue2-test-1
(on the command line or from a GitHub Action) -
Trigger the dependent Spacelift stack (from a GitHub Action by using the spacectl CLI, or by using an OPA Trigger policy, or by using the spacelift_stack_dependency resource)
-
Trigger the dependent Atlantis project