Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Atmos Go template functions. Add atmos.Component function to read values from other Atmos components including outputs (remote state) #628

Merged
merged 38 commits into from
Jun 15, 2024

Conversation

aknysh
Copy link
Member

@aknysh aknysh commented Jun 15, 2024

what

why

description

The atmos.Component template function allows you to read 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.

    NOTE: Using the outputs section in the atmos.Component command is an alternative way to read the outputs (remote state) of a component in a stack directly in Atmos stack manifests instead of 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

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

  • 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:

      components:
        terraform:
          tgw:
            vars:
              vpc_id: '{{ (atmos.Component "vpc" "plat-ue2-prod").outputs.vpc_id }}'
  • Use the .stack (or .atmos_stack) template identifier to specify the same stack as the current component (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 the printf template function to construct stack names using static strings and dynamic identifiers:

      {{ (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):

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

    NOTE: 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 }}'

@aknysh aknysh added the minor New features that do not break anything label Jun 15, 2024
@aknysh aknysh requested a review from osterman June 15, 2024 18:35
@aknysh aknysh self-assigned this Jun 15, 2024
@aknysh aknysh requested review from a team as code owners June 15, 2024 18:35
@aknysh aknysh requested review from hans-d and jamengual June 15, 2024 18:35
@aknysh aknysh merged commit 5b406c1 into main Jun 15, 2024
14 checks passed
@aknysh aknysh deleted the atmos-template-functions-2 branch June 15, 2024 23:40
Copy link

These changes were released in v1.81.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
minor New features that do not break anything
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants