Skip to main content

atmos.Component

The atmos.Component template function allows reading any Atmos section or any attribute from a section for an Atmos component in a stack, and use it in Go templates in Atmos component configurations.

Usage

  {{ (atmos.Component "<component>" "<stack>").<section>.<attribute> }}

Arguments

component
Atmos component name
stack
Atmos stack name
section
Atmos section name. Any section returned by the CLI command atmos describe component can be used. A special outputs section is also supported to get the outputs (remote state) of Terraform/OpenTofu components.
outputs
Using the outputs section in the atmos.Component command is an convenient way to read the outputs (remote state) of a component in a stack directly in Atmos stack manifests. It is an alternative to using the remote-state module and configuring Terraform/OpenTofu components to use the remote-state module as described in Component Remote State
attribute

Attribute name (field) from the section. attribute is optional, you can use the section itself if it's a simple type (e.g. string). Any number of attributes can be chained using the dot (.) notation. For example, if the first two attributes are maps, you can chain them and get a field from the last map:

{{ (atmos.Component "<component>" "<stack>").<section>.<attribute1>.<attribute2>.<field1> }}

Specifying Atmos stack

There are multiple ways you can specify the Atmos stack parameter in the atmos.Component function.

The stack argument is the second argument of the atmos.Component function, and it can be specified in a few different ways:

Hardcoded Stack Name

Hardcoded stack name. Use it if you want to get an output from 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 output from the vpc component from the stack plat-ue2-prod:

plat-ue2-dev
  components:
terraform:
tgw:
vars:
vpc_id: '{{ (atmos.Component "vpc" "plat-ue2-prod").outputs.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 atmos.Component function is executed):

  {{ (atmos.Component "<component>" .stack).<section>.<attribute> }}
{{ (atmos.Component "<component>" .atmos_stack).<section>.<attribute> }}

For example, you have a tgw component that requires the vpc_id output from the vpc component in the same stack:

  components:
terraform:
tgw:
vars:
vpc_id: '{{ (atmos.Component "vpc" .stack).outputs.vpc_id }}'

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:

  {{ (atmos.Component "<component>" (printf "%s-%s-%s" .vars.tenant .vars.environment .vars.stage)).<section>.<attribute> }}

{{ (atmos.Component "<component>" (printf "plat-%s-prod" .vars.environment)).<section>.<attribute> }}

{{ (atmos.Component "<component>" (printf "%s-%s-%s" .settings.context.tenant .settings.context.region .settings.context.account)).<section>.<attribute> }}

For example, you have a tgw component deployed in the stack plat-ue2-dev. The tgw component requires the vpc_id output from the vpc component from the same environment (ue2) and same stage (dev), but from a different tenant net (instead of plat):

plat-ue2-dev
  components:
terraform:
tgw:
vars:
vpc_id: '{{ (atmos.Component "vpc" (printf "net-%s-%s" .vars.environment .vars.stage)).outputs.vpc_id }}'
Important

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

Examples

The following configurations show different ways of using the atmos.Component template function to read values from different Atmos sections directly in Atmos stack manifests, including the outputs of other (already provisioned) components.

# Global `settings` section
# It will be added and deep-merged to the `settings` section of all components
settings:
test: true

components:
terraform:
test:
metadata:
# Point to the Terraform/OpenTofu component
component: "test"
vars:
name: "test"

test1:
metadata:
# Point to the Terraform/OpenTofu component
component: "test1"
vars:
name: "test1"

test2:
metadata:
# Point to the Terraform/OpenTofu component
component: "test2"
vars:
name: "test2"
# Use the `atmos.Component` function to get the outputs of the Atmos component `test1`
# The `test1` component must be already provisioned and its outputs stored in the Terraform/OpenTofu state
# Atmos will execute `terraform output` on the `test1` component in the same stack to read its outputs
test1_id: '{{ (atmos.Component "test1" .stack).outputs.test1_id }}'
tags:
# Get the `settings.test` field from the `test` component in the same stack
test: '{{ (atmos.Component "test" .stack).settings.test }}'
# Get the `metadata.component` field from the `test` component in the same stack
test_terraform_component: '{{ (atmos.Component "test" .stack).metadata.component }}'
# Get the `vars.name` field from the `test1` component in the same stack
test1_name: '{{ (atmos.Component "test1" .stack).vars.name }}'

Caching the result of atmos.Component function

Atmos caches (in memory) the results of atmos.Component template function execution. If you call the function for the same component in a stack more than once, the first call will produce the result and cache it, and all the consecutive calls will just use the cached data. This is useful when you use the atmos.Component function for the same component in a stack in multiple places in Atmos stack manifests. It will speed up the function execution and stack processing.

For example:

components:
terraform:
test2:
vars:
tags:
test: '{{ (atmos.Component "test" .stack).outputs.id }}'
test2: '{{ (atmos.Component "test" .stack).outputs.id }}'
test3: '{{ (atmos.Component "test" .stack).outputs.id }}'

In the example, the test2 Atmos component uses the outputs (remote state) of the test Atmos component from the same stack. The template function {{ atmos.Component "test" .stack }} is executed three times (once for each tag).

After the first execution, Atmos caches the result in memory (all the component sections, including the outputs), and reuses it in the next two calls to the function. The caching makes the stack processing about three times faster in this particular example. In a production environment where many components are used, the speedup can be even more significant.