Update `atmos terraform generate planfile` and `atmos terraform plan-diff` commands. Update `depends_on` for component dependencies @aknysh (#1405)
what
-
Update
atmos terraform generate planfile
andatmos terraform plan-diff
commands. Process templates and Atmos YAML functions before executing the commands. -
Update
depends_on
for component dependencies. Addstack
attribute as one of the context variables independs_on
-
Update docs
-
Add tests
why
-
The
atmos terraform generate planfile
andatmos terraform plan-diff
commands did not process templates and Atmos YAML functions, but they should -
Add
stack
attribute as one of the context variables independs_on
to allow specifying an Atmos stack where the dependent component is provisioned
description
Atmos supports configuring the relationships between components in the same or different stacks. You can define dependencies between components to ensure that components are deployed in the correct order.
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 or numbering so that people can understand what the dependencies are about.
If component
is specified, you can provide the other context variables to define an Atmos stack other than the current stack.
For example, you can specify:
stack
if thecomponent
is from a different Atmos stacknamespace
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
)
NOTE:
If stack
is specified, it's processed first and the namespace
, tenant
, environment
and stage
attributes are ignored.
NOTE:
You can use Atmos Stack Manifest Templating in depends_on
.
Atmos processes the templates first, and then detects all the dependencies, allowing you to provide the parameters to
depends_on
dynamically.
In the following example, we specify that the component1
component depends on the following:
- The
component2
component in the same Atmos stack ascomponent1
- The
component3
component from theprod
stage - The
component4
component from thetenant1
tenant,ue2
environment andstaging
stage (tenant1-ue2-staging
Atmos stack) - The
component5
component from thetenant1-ue2-prod
Atmos stack - The
component6
component from the same Atmos stack ascomponent1
- The
component7
component from the same tenant and stage ascomponent1
, butuw2
environment
vars:
tenant: "tenant1"
environment: "ue1"
stage: "dev"
components:
terraform:
component1:
settings:
depends_on:
1:
# If the context (`stack`, `namespace`, `tenant`, `environment`, `stage`) is not
# provided, the `component` is from the same Atmos stack as `component1`
component: "component2"
2:
# `component1` (in any stage) depends on `component3`
# from the `prod` stage (in any `environment` and any `tenant`)
component: "component3"
stage: "prod"
3:
# `component1` depends on `component4`
# from the the `tenant1` tenant, `ue2` environment and `staging` stage
# (`tenant1-ue2-staging` Atmos stack)
component: "component4"
tenant: "tenant1"
environment: "ue2"
stage: "staging"
4:
# `component1` depends on `component5`
# from the `tenant1-ue2-prod` Atmos stack
component: "component5"
stack: "tenant1-ue2-prod"
5:
# `component1` depends on `component6`
# from the same Atmos stack
component: "component6"
stack: "{{ .vars.tenant }}-{{ .vars.environment }}-{{ .vars.stage }}"
6:
# `component1` depends on `component7`
# from the same tenant and stage as `component1`, but `uw2` environment
component: "component7"
stack: "{{ .vars.tenant }}-uw2-{{ .vars.stage }}"
vars:
enabled: true
Specifying stack
The stack
attribute has higher precedence than the other context variables.
If stack
is specified, the namespace
, tenant
, environment
and stage
attributes are ignored.
As you can see in the examples above, we can use Atmos Stack Manifest Templating in the stack
attribute to dynamically specify the stack.
This is useful when configuring
stacks.name_template
in atmos.yaml
to define and refer to stacks. In this case, you can't use the context variables namespace
, tenant
, environment
and stage
in depends_on
.
For example, in atmos.yaml
, we specify stacks.name_template
to define Atmos stacks, and enable templating:
stacks:
base_path: "stacks"
name_template: "{{ .settings.context.tenant }}-{{ .settings.context.environment }}-{{ .settings.context.stage }}"
# `Go` templates in Atmos manifests
templates:
settings:
enabled: true
NOTE:
In this example, stacks are defined by the settings.context
section, not vars
.
In the tenant1-uw2-dev
Atmos stack, we can use the following depends_on
configuration to define the component dependencies:
settings:
context:
tenant: "tenant1"
environment: "uw2"
stage: "dev"
components:
terraform:
vpc:
vars:
enabled: true
tgw/attachment:
settings:
depends_on:
1:
# `tgw/attachment` depends on the `vpc` component
# from the same Atmos stack (same tenant, account and region)
component: vpc
# NOTE: The same stack can be specified by using exactly the same template as in
# `stacks.name_template` in `atmos.yaml`, but it's not required and not recommended.
# If the dependent component is from the same stack, just omit the `stack` attribute completely.
# stack: "{{ .settings.context.tenant }}-{{ .settings.context.environment }}-{{ .settings.context.stage }}"
2:
# `tgw/attachment` depends on the `tgw/hub` components
# from the same tenant and account, but in `us-east-1` region (`ue1` environment)
component: tgw/hub
stack: "{{ .settings.context.tenant }}-ue1-{{ .settings.context.stage }}"
tgw/cross-region-hub-connector:
settings:
depends_on:
1:
# `tgw/cross-region-hub-connector` depends on `tgw/hub` components
# in the same tenant and account, but in `us-east-1` region (`ue1` environment)
component: tgw/hub
stack: "{{ .settings.context.tenant }}-ue1-{{ .settings.context.stage }}"
Execute the following Atmos commands to see the component dependencies:
> atmos describe dependents vpc -s tenant1-uw2-dev --pager off
[
{
"component": "tgw/attachment",
"component_type": "terraform",
"stack": "tenant1-uw2-dev",
"stack_slug": "tenant1-uw2-dev-tgw-attachment"
}
]
> atmos describe dependents tgw/hub -s tenant1-ue1-dev --pager off
[
{
"component": "tgw/attachment",
"component_type": "terraform",
"stack": "tenant1-uw2-dev",
"stack_slug": "tenant1-uw2-dev-tgw-attachment"
},
{
"component": "tgw/cross-region-hub-connector",
"component_type": "terraform",
"stack": "tenant1-uw2-dev",
"stack_slug": "tenant1-uw2-dev-tgw-cross-region-hub-connector"
}
]
Add `!store.get` YAML function for arbitrary key retrieval @jamengual (#1352)
what
- Add the
!store.get
YAML function, enabling retrieval of arbitrary keys from any supported store (Azure Key Vault, AWS SSM, Redis, Google Secret Manager, Artifactory)
why
- Unlike the existing
!store
function,!store.get
does not require keys to follow the Atmos stack/component/key naming pattern. Users can retrieve any key by specifying its exact name or path.
usage examples
# Retrieve a key from Redis by its exact name
my_config: !store.get redis global-config
# Retrieve a secret from Azure Key Vault by its name
my_secret: !store.get azure-keyvault my-arbitrary-secret
# Retrieve a parameter from AWS SSM by its full path
ssm_value: !store.get aws-ssm-parameter-store /custom/path/to/parameter
Notable Differences from !store
!store.get
does not construct keys using stack/component/key; it expects the full key or path.- Useful for retrieving values stored outside of Atmos or not following the standard naming convention.