!store
The !store YAML function allows reading the values from a remote store
(e.g. SSM Parameter Store, Artifactory, Redis, etc.) for an Atmos component in a stack 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.yamlfile) 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
!storewith secrets can expose sensitive data to standard output (stdout) in any commands that describe stacks or components. - When using
!storewithatmos 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
!storefunction call will fail unless you provide a default value with| default.