github cloudposse/atmos v1.181.0

latest releases: v1.189.0-rc.0, v1.188.0, v1.188.0-test.2...
2 months ago
Terraform/OpenTofu Multi-Component Commands (Filtered/Bulk Operations) @aknysh (#1327)

what

  • Add Terraform/OpenTofu Multi-Component Commands (Filtered/Bulk Operations)
    • atmos terraform plan/apply/deploy --all
    • atmos terraform plan/apply/deploy --all --stack <stack>
    • atmos terraform plan/apply/deploy --affected
    • atmos terraform plan/apply/deploy --affected --stack <stack>
    • atmos terraform plan/apply/deploy --affected --include-dependents
    • atmos terraform plan/apply/deploy --affected --stack <stack> --include-dependents
    • atmos terraform plan/apply/deploy --components <component1>,<component2>
    • atmos terraform plan/apply/deploy --components <component1>,<component2> --stack <stack>
    • atmos terraform plan/apply/deploy --query <yq-expression>
    • atmos terraform plan/apply/deploy --query <yq-expression> --stack <stack>
  • Add unit tests
  • Update docs

why

  • Allow Terraform/Opentofu operations (plan, apply, deploy) on a set of components in all stacks or a specific stack depending on stack, set of components, query, or filters

description

Atmos Terraform/OpenTofu commands fall into two categories:

  • Single-Component: Run Terraform for one component at a time

  • Multi-Component (Filtered/Bulk): Run Terraform across multiple components using stack names, selectors, or change detection

Single-Component Commands Usage

# Execute `terraform <command>` on a `component` in a `stack`
atmos terraform <command> <component> -s <stack> [options]
atmos terraform <command> <component> --stack <stack> [options]

Multi-Component Commands (Bulk Operations) Usage

# Execute `terraform <command>` on all components in the stack `prod`
atmos terraform <command> --stack prod

# Execute `terraform <command>` on components `component-1` and `component-2` in all stacks
atmos terraform <command> --components component-1,component-2

# Execute `terraform <command>` on components `component-1` and `component-2` in the stack `prod`
atmos terraform <command> --stack prod --components component-1,component-2

# Execute `terraform <command>` on all components in all stacks
atmos terraform <command> --all

# Execute `terraform <command>` on all components in the stack `prod`
atmos terraform <command> --all --stack prod

# Execute `terraform <command>` on all the directly affected components in all stacks in dependency order
# (if component dependencies are configured)
atmos terraform <command> --affected

# Execute `terraform <command>` on all the directly affected components in the `prod` stack in dependency order
# (if component dependencies are configured)
atmos terraform <command> --affected --stack prod

# Execute `terraform <command>` on all the directly affected components in all stacks in dependency order.
# For each directly affected component, detect the dependent components and process them in dependency order, recursively.
# Dependents are components that are indirectly affected, meaning that nothing in the current branch modifies their code
# or configs, but they are configured as dependencies of the components that are modified
atmos terraform <command> --affected --include-dependents

# Execute `terraform <command>` on all the directly affected components in the `prod` stack in dependency order.
# For each directly affected component, detect the dependent components and process them in dependency order, recursively.
atmos terraform <command> --affected --include-dependents --stack prod

# Execute `terraform <command>` on all components that have `vars.tags.team == "data"`, in all stacks
atmos terraform <command> --query '.vars.tags.team == "data"'

# Execute `terraform <command>` on all components that have `vars.tags.team == "eks"`, in the stack `prod`
atmos terraform <command> --query '.vars.tags.team == "eks"' --stack prod

# Execute `terraform <command>` on all components that have `settings.context.account_id == 12345`, in all stacks
atmos terraform <command> --query '.settings.context.account_id == 12345'

Multi-Component Commands (Bulk Operations) Examples

Let's assume that we have the following Atmos stack manifests in the prod and nonprod stacks,
with dependencies between the components:

components:
  terraform:
    vpc:
      vars:
        tags:
          # Team `network` manages the `vpc` component
          team: network
    eks/cluster:
      vars:
        tags:
          # Team `eks` manages the `eks/cluster` component
          team: eks
      settings:
        depends_on:
          # `eks/cluster` depends on the `vpc` component
          1:
            component: vpc
    eks/external-dns:
      vars:
        tags:
          # Team `eks` manages the `eks/external-dns` component
          team: eks
      settings:
        depends_on:
          # `eks/external-dns` depends on the `eks/cluster` component
          1:
            component: eks/cluster
    eks/karpenter:
      vars:
        tags:
          # Team `eks` manages the `eks/karpenter` component
          team: eks
      settings:
        depends_on:
          # `eks/karpenter` depends on the `eks/cluster` component
          1:
            component: eks/cluster
    eks/karpenter-node-pool:
      vars:
        tags:
          # Team `eks` manages the `eks/karpenter-node-pool` component
          team: eks
      settings:
        # `eks/karpenter-node-pool` depends on the `eks/cluster` and `eks/karpenter` components
        depends_on:
          1:
            component: eks/cluster
          2:
            component: eks/karpenter
    eks/istio/base:
      vars:
        tags:
          # Team `istio` manages the `eks/istio/base` component
          team: istio
      settings:
        # `eks/istio/base` depends on the `eks/cluster` component
        depends_on:
          1:
            component: eks/cluster
    eks/istio/istiod:
      vars:
        tags:
          # Team `istio` manages the `eks/istio/istiod` component
          team: istio
      settings:
        # `eks/istio/istiod` depends on the `eks/cluster` and `eks/istio/base` components
        depends_on:
          1:
            component: eks/cluster
          2:
            component: eks/istio/base
    eks/istio/test-app:
      vars:
        tags:
          # Team `istio` manages the `eks/istio/test-app` component
          team: istio
      settings:
        # `eks/istio/test-app` depends on the `eks/cluster`, `eks/istio/istiod` and `eks/istio/base` components
        depends_on:
          1:
            component: eks/cluster
          2:
            component: eks/istio/istiod
          3:
            component: eks/istio/base

Let's run the following Multi-Component commands in dry-run mode and review the output to understand what each command executes:

# Execute the `terraform apply` command on all components in all stacks

> atmos terraform apply --all --dry-run

Executing command="atmos terraform apply vpc -s nonprod"
Executing command="atmos terraform apply eks/cluster -s nonprod"
Executing command="atmos terraform apply eks/external-dns -s nonprod"
Executing command="atmos terraform apply eks/istio/base -s nonprod"
Executing command="atmos terraform apply eks/istio/istiod -s nonprod"
Executing command="atmos terraform apply eks/istio/test-app -s nonprod"
Executing command="atmos terraform apply eks/karpenter -s nonprod"
Executing command="atmos terraform apply eks/karpenter-node-pool -s nonprod"

Executing command="atmos terraform apply vpc -s prod"
Executing command="atmos terraform apply eks/cluster -s prod"
Executing command="atmos terraform apply eks/external-dns -s prod"
Executing command="atmos terraform apply eks/istio/base -s prod"
Executing command="atmos terraform apply eks/istio/istiod -s prod"
Executing command="atmos terraform apply eks/istio/test-app -s prod"
Executing command="atmos terraform apply eks/karpenter -s prod"
Executing command="atmos terraform apply eks/karpenter-node-pool -s prod"
# Execute the `terraform apply` command on all components in the `prod` stack

> atmos terraform apply --all --stack prod --dry-run

Executing command="atmos terraform apply vpc -s prod"
Executing command="atmos terraform apply eks/cluster -s prod"
Executing command="atmos terraform apply eks/external-dns -s prod"
Executing command="atmos terraform apply eks/istio/base -s prod"
Executing command="atmos terraform apply eks/istio/istiod -s prod"
Executing command="atmos terraform apply eks/istio/test-app -s prod"
Executing command="atmos terraform apply eks/karpenter -s prod"
Executing command="atmos terraform apply eks/karpenter-node-pool -s prod"
# Execute the `terraform apply` command on all components in the `prod` stack

> atmos terraform apply --stack prod --dry-run

Executing command="atmos terraform apply vpc -s prod"
Executing command="atmos terraform apply eks/cluster -s prod"
Executing command="atmos terraform apply eks/external-dns -s prod"
Executing command="atmos terraform apply eks/istio/base -s prod"
Executing command="atmos terraform apply eks/istio/istiod -s prod"
Executing command="atmos terraform apply eks/istio/test-app -s prod"
Executing command="atmos terraform apply eks/karpenter -s prod"
Executing command="atmos terraform apply eks/karpenter-node-pool -s prod"
# Execute the `terraform apply` command on the `vpc` and `eks/cluster` components
# in all stacks.

> atmos terraform apply --components vpc,eks/cluster --dry-run

Executing command="atmos terraform apply vpc -s nonprod"
Executing command="atmos terraform apply eks/cluster -s nonprod"

Executing command="atmos terraform apply vpc -s prod"
Executing command="atmos terraform apply eks/cluster -s prod"
# Execute the `terraform apply` command on the `vpc` and `eks/cluster` components
# in the `prod` stack.

> atmos terraform apply --stack prod --components vpc,eks/cluster --dry-run

Executing command="atmos terraform apply vpc -s prod"
Executing command="atmos terraform apply eks/cluster -s prod"
# Execute the `terraform apply` command on the components filtered by the query expression,
# in all stacks.

> atmos terraform apply --query '.vars.tags.team == "eks"' --dry-run

Skipping the component because the query criteria not satisfied command="atmos terraform apply vpc -s nonprod" query=".vars.tags.team == \"eks\""
Executing command="atmos terraform apply eks/cluster -s nonprod"
Executing command="atmos terraform apply eks/external-dns -s nonprod"
Skipping the component because the query criteria not satisfied command="atmos terraform apply eks/istio/base -s nonprod" query=".vars.tags.team == \"eks\""
Skipping the component because the query criteria not satisfied command="atmos terraform apply eks/istio/istiod -s nonprod" query=".vars.tags.team == \"eks\""
Skipping the component because the query criteria not satisfied command="atmos terraform apply eks/istio/test-app -s nonprod" query=".vars.tags.team == \"eks\""
Executing command="atmos terraform apply eks/karpenter -s nonprod"
Executing command="atmos terraform apply eks/karpenter-node-pool -s nonprod"

Skipping the component because the query criteria not satisfied command="atmos terraform apply vpc -s prod" query=".vars.tags.team == \"eks\""
Executing command="atmos terraform apply eks/cluster -s prod"
Executing command="atmos terraform apply eks/external-dns -s prod"
Skipping the component because the query criteria not satisfied command="atmos terraform apply eks/istio/base -s prod" query=".vars.tags.team == \"eks\""
Skipping the component because the query criteria not satisfied command="atmos terraform apply eks/istio/istiod -s prod" query=".vars.tags.team == \"eks\""
Skipping the component because the query criteria not satisfied command="atmos terraform apply eks/istio/test-app -s prod" query=".vars.tags.team == \"eks\""
Executing command="atmos terraform apply eks/karpenter -s prod"
Executing command="atmos terraform apply eks/karpenter-node-pool -s prod"
# Execute the `terraform apply` command on the components filtered by the query expression,
# in the `prod` stack.

> atmos terraform apply --query '.vars.tags.team == "eks"' --stack prod --dry-run

Skipping the component because the query criteria not satisfied command="atmos terraform apply vpc -s prod" query=".vars.tags.team == \"eks\""
Executing command="atmos terraform apply eks/cluster -s prod"
Executing command="atmos terraform apply eks/external-dns -s prod"
Skipping the component because the query criteria not satisfied command="atmos terraform apply eks/istio/base -s prod" query=".vars.tags.team == \"eks\""
Skipping the component because the query criteria not satisfied command="atmos terraform apply eks/istio/istiod -s prod" query=".vars.tags.team == \"eks\""
Skipping the component because the query criteria not satisfied command="atmos terraform apply eks/istio/test-app -s prod" query=".vars.tags.team == \"eks\""
Executing command="atmos terraform apply eks/karpenter -s prod"
Executing command="atmos terraform apply eks/karpenter-node-pool -s prod"
# Execute the `terraform apply` command on all components affected by the changes
# in the current branch, in all stacks, in dependency order.
# Assume that the components `vpc` and `eks/cluster` in all stacks are affected (e.g. just added).

> atmos terraform apply --affected --dry-run

Executing command="atmos terraform apply vpc -s nonprod"
Executing command="atmos terraform apply eks/cluster -s nonprod"

Executing command="atmos terraform apply vpc -s prod"
Executing command="atmos terraform apply eks/cluster -s prod"
# Execute the `terraform apply` command on all components affected by the changes
# in the current branch, in the `prod` stack, in dependency order.
# Assume that the components `vpc` and `eks/cluster` in the `prod` stack are affected (e.g. just added).

> atmos terraform apply --affected --stack prod --dry-run

Executing command="atmos terraform apply vpc -s prod"
Executing command="atmos terraform apply eks/cluster -s prod"
# Execute the `terraform apply` command on all the components affected by the changes
# in the current branch, in all stacks.
# For each directly affected component, detect the dependent components and process
# them in dependency order, recursively.
# Dependents are components that are indirectly affected, meaning that nothing in the
# current branch modifies their code or configs, but they are configured as
# dependencies of the components that are modified.

> atmos terraform apply --affected --include-dependents --dry-run

Executing command="atmos terraform apply vpc -s nonprod"
Executing command="atmos terraform apply eks/cluster -s nonprod" dependency of component=vpc in stack=nonprod
Executing command="atmos terraform apply eks/karpenter -s nonprod" dependency of component=eks/cluster in stack=nonprod
Executing command="atmos terraform apply eks/karpenter-node-pool -s nonprod" dependency of component=eks/karpenter in stack=nonprod
Executing command="atmos terraform apply eks/external-dns -s nonprod" dependency of component=eks/cluster in stack=nonprod
Executing command="atmos terraform apply eks/istio/base -s nonprod" dependency of component=eks/cluster in stack=nonprod
Executing command="atmos terraform apply eks/istio/istiod -s nonprod" dependency of component=eks/istio/base in stack=nonprod
Executing command="atmos terraform apply eks/istio/test-app -s nonprod" dependency of component=eks/istio/istiod in stack=nonprod

Executing command="atmos terraform apply vpc -s prod"
Executing command="atmos terraform apply eks/cluster -s prod" dependency of component=vpc in stack=prod
Executing command="atmos terraform apply eks/external-dns -s prod" dependency of component=eks/cluster in stack=prod
Executing command="atmos terraform apply eks/istio/base -s prod" dependency of component=eks/cluster in stack=prod
Executing command="atmos terraform apply eks/istio/istiod -s prod" dependency of component=eks/istio/base in stack=prod
Executing command="atmos terraform apply eks/istio/test-app -s prod" dependency of component=eks/istio/istiod in stack=prod
Executing command="atmos terraform apply eks/karpenter -s prod" dependency of component=eks/cluster in stack=prod
Executing command="atmos terraform apply eks/karpenter-node-pool -s prod" dependency of component=eks/karpenter in stack=prod
# Execute the `terraform apply` command on all the components affected by the changes
# in the current branch, in the `prod` stack.
# For each directly affected component, detect the dependent components and process
# them in dependency order, recursively.
# Dependents are components that are indirectly affected, meaning that nothing in the
# current branch modifies their code or configs, but they are configured as
# dependencies of the components that are modified.

> atmos terraform apply --affected --stack prod --include-dependents --dry-run

Executing command="atmos terraform apply vpc -s prod"
Executing command="atmos terraform apply eks/cluster -s prod" dependency of component=vpc in stack=prod
Executing command="atmos terraform apply eks/external-dns -s prod" dependency of component=eks/cluster in stack=prod
Executing command="atmos terraform apply eks/istio/base -s prod" dependency of component=eks/cluster in stack=prod
Executing command="atmos terraform apply eks/istio/istiod -s prod" dependency of component=eks/istio/base in stack=prod
Executing command="atmos terraform apply eks/istio/test-app -s prod" dependency of component=eks/istio/istiod in stack=prod
Executing command="atmos terraform apply eks/karpenter -s prod" dependency of component=eks/cluster in stack=prod
Executing command="atmos terraform apply eks/karpenter-node-pool -s prod" dependency of component=eks/karpenter in stack=prod
Add Azure Key Vault support for Atmos Stores @jamengual (#963)

what

why

  • Support Azure Key Vault in Atmos hooks and !store YAML function
Add pager to describe workflow @samtholiya (#1266)

what

  • Updated describe workflows with pager
    image

why

  • Makes easier for users to view the content
Go releaser config support draft mode @goruha (#1353)

what

  • Go releaser config support draft mode

why

  • Increase velocity for feature releases
Fix `--sections` flag in `atmos describe stacks` @samtholiya (#1313)

what

  • Fix --sections flag in atmos describe stacks

why

  • The functionality was inadvertently broken in the last release

Don't miss a new atmos release

NewReleases is sending notifications on new releases.