!store
The !store
YAML function allows reading the values from a remote store
(e.g. SSM Parameter Store, Artifactory, Redis, etc.) into Atmos stack manifests.
Usage
The !store
function can be called with either two, three, or four parameters, and optionally a default value and
a YQ query expression:
!store <store_name> <stack> <component> <key> | default <default-value> | query <yq-expression>
Usage examples:
# Get the `key` from the store of a `component` in the current stack
!store <store_name> <component> <key>
# Get the `key` from the store of a `component` in the current stack,
# and retrieve an individual value from the result using the YQ expression
!store <store_name> <component> <key> | query <yq-expression>
# Get the `key` from the store of a `component` in a different stack
!store <store_name> <stack> <component> <key>
# Get the `key` from the store of a `component` in a different stack,
# and retrieve an individual value from the result using the YQ expression
!store <store_name> <stack> <component> <key> | query <yq-expression>
# Get the `key` from the store of a `component` in a different stack, with a default value
!store <store_name> <stack> <component> <key> | default <default-value>
Arguments
store_name
- The name of the store to read from (as defined in the
atmos.yaml
file) stack
- (optional) Atmos stack name
component
- Atmos component name
key
- The key to read from the store
default-value
- (optional) The default value to return if the key is not found in the store
yq-expression
- (optional) YQ expression to retrieve individual values from the result
You can use Atmos Stack Manifest Templating in the !store
YAML function expressions.
Atmos processes the templates first, and then executes the !store
function, allowing you to provide the parameters to
the function dynamically.
Using YQ Expressions to retrieve individual values
To retrieve individual values from complex types such as maps and lists, or do any kind of filtering or querying, you can utilize YQ expressions.
For example:
- Retrieve the first item from a list
subnet_id1: !store <store_name> <stack> <component> <key> | query .private_subnet_ids[0]
- Read a key from a map
username: !store <store_name> <stack> <component> <key> | query .config_map.username
For more details, review the following docs:
Examples
stack.yaml
Specifying Atmos stack
If you call the !store
function with three parameters, you need to specify the stack as the second argument.
There are multiple ways you can specify the Atmos stack parameter in the !terraform.output
function.
Hardcoded Stack Name
Use it if you want to get a value from the store for a component from a different (well-known and static) stack.
For example, you have a tgw
component in a stack plat-ue2-dev
that requires the vpc_id
key from the vpc
component from the stack plat-ue2-prod
:
components:
terraform:
tgw:
vars:
vpc_id: !store prod/ssm plat-ue2-prod vpc vpc_id
Reference the Current Stack Name
Use the .stack
(or .atmos_stack
) template identifier to specify the same stack as the current component is in
(for which the !store
function is executed):
!store <store_name> {{ .stack }} <component> <key>
!store <store_name> {{ .atmos_stack }} <component> <key>
For example, you have a tgw
component that requires the vpc_id
key from the store for the vpc
component in the same stack:
components:
terraform:
tgw:
vars:
vpc_id: !store prod/ssm {{ .stack }} vpc vpc_id
.stack
or .atmos_stack
template identifiers to specify the stack is the same as calling the!store
function with two parameters without specifying the current stack, but without using Go
templates. If you
need to get a value from the store from a component in the current stack, using the !store
function with two
parameters is preferred because it has a simpler syntax and executes faster.
Use a Format Function
Use the printf
template function to construct stack names using static strings and dynamic identifiers.
This is convenient when you want to override some identifiers in the stack name:
!store <store_name> {{ printf "%s-%s-%s" .vars.tenant .vars.environment .vars.stage }} <component> <key>
!store <store_name> {{ printf "plat-%s-prod" .vars.environment }} <component> <key>
!store <store_name> {{ printf "%s-%s-%s" .settings.context.tenant .settings.context.region .settings.context.account }} <component> <key>
<component>
- Placeholder for an actual component name (e.g.
vpc
) <key>
- Placeholder for an actual key (e.g.
subnet_ids
)
For example, you have a tgw
component deployed in the stack plat-ue2-dev
. The tgw
component requires the
vpc_id
key from the store for the vpc
component from the same environment (ue2
) and same stage (dev
), but from a different
tenant net
(instead of plat
):
components:
terraform:
tgw:
vars:
vpc_id: !store prod/ssm {{ printf "net-%s-%s" .vars.environment .vars.stage }} vpc vpc_id
By using the printf "%s-%s-%s"
function, you are constructing stack names using the stack context variables/identifiers.
For more information on Atmos stack names and how to define them, refer to stacks.name_pattern
and stacks.name_template
sections in atmos.yaml
CLI config file
Considerations
- Using
!store
with secrets can expose sensitive data to standard output (stdout) in any commands that describe stacks or components. - When using
!store
withatmos describe affected
, Atmos requires access to all referenced stores. If you operate with limited permissions (e.g., scoped todev
) and reference production stacks, the command will fail. - Be mindful of disaster recovery (DR) implications when using it across regions.
- Consider cold-start scenarios: if the dependent component has not yet been provisioned, the value in the store may not
yet be available and the
!store
function call will fail unless you provide a default value with|default
.