github cloudposse/atmos v1.187.0

latest releases: v1.190.0-rc.0, v1.189.0, v1.189.0-test.0...
17 days ago
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 and atmos terraform plan-diff commands. Process templates and Atmos YAML functions before executing the commands.

  • Update depends_on for component dependencies. Add stack attribute as one of the context variables in depends_on

  • Update docs

  • Add tests

why

  • The atmos terraform generate planfile and atmos terraform plan-diff commands did not process templates and Atmos YAML functions, but they should

  • Add stack attribute as one of the context variables in depends_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 the component is from a different Atmos stack
  • namespace if the component is from a different Organization
  • tenant if the component is from a different Organizational Unit
  • environment if the component is from a different region
  • stage if the component is from a different account
  • tenant, environment and stage 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 as component1
  • The component3 component from the prod stage
  • The component4 component from the tenant1 tenant, ue2 environment and staging stage (tenant1-ue2-staging Atmos stack)
  • The component5 component from the tenant1-ue2-prod Atmos stack
  • The component6 component from the same Atmos stack as component1
  • The component7 component from the same tenant and stage as component1, but uw2 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.
Move `github.event.release.prerelease` logic to shared workflows @goruha (#1400)

what

  • Move github.event.release.prerelease logic to shared workflows

why

  • Having a single point responsible for the conditions

Don't miss a new atmos release

NewReleases is sending notifications on new releases.