Skip to main content

GitHub Action: atmos-affected

A GitHub Action to get a list of affected atmos stacks for a pull request

Introduction

This is a GitHub Action to get a list of affected atmos stacks for a pull request. It optionally installs atmos and jq and runs atmos describe affected to get the list of affected stacks. It provides the raw list of affected stacks as an output as well as a matrix that can be used further in GitHub action jobs.

Usage

Config

important

Please note! This GitHub Action only works with atmos >= 1.99.0. If you are using atmos >= 1.80.0, < 1.99.0 please use v5 version of this action. If you are using atmos >= 1.63.0, < 1.80.0 please use v3 or v4 version of this action. If you are using atmos < 1.63.0 please use v2 version of this action.

The action expects the atmos configuration file atmos.yaml to be present in the repository.

The action supports AWS and Azure to store Terraform plan files. You can read more about plan storage in the cloudposse/github-action-terraform-plan-storage documentation. Depends of cloud provider the following fields should be set in the atmos.yaml:

AWS

The config should have the following structure:

integrations:
github:
gitops:
opentofu-version: 1.7.3
terraform-version: 1.5.2
infracost-enabled: false
artifact-storage:
region: us-east-2
bucket: cptest-core-ue2-auto-gitops
table: cptest-core-ue2-auto-gitops-plan-storage
role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-core-ue2-auto-gitops-gha
role:
plan: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
# Set `apply` empty if you don't want to assume IAM role before terraform apply
apply: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
matrix:
sort-by: .stack_slug
group-by: .stack_slug | split("-") | [.[0], .[2]] | join("-")

Azure

The config should have the following structure:

integrations:
github:
gitops:
opentofu-version: 1.7.3
terraform-version: 1.5.2
infracost-enabled: false
artifact-storage:
plan-repository-type: azureblob
blob-account-name: tfplans
blob-container-name: plans
metadata-repository-type: cosmos
cosmos-container-name: terraform-plan-storage
cosmos-database-name: terraform-plan-storage
cosmos-endpoint: "https://my-cosmo-account.documents.azure.com:443/"
# We remove the `role` section as it is AWS specific
matrix:
sort-by: .stack_slug
group-by: .stack_slug | split("-") | [.[0], .[2]] | join("-")

Stack level configuration

important

Wherever it is possible to specify integration.github.gitops on stack level it is required to define default values in atmos.yaml

It is possible to override integration settings on a stack level by defining settings.integrations.

components:
terraform:
foobar:
settings:
integrations:
github:
gitops:
artifact-storage:
bucket: cptest-plat-ue2-auto-gitops
table: cptest-plat-ue2-auto-gitops-plan-storage
role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-plat-ue2-auto-gitops-gha
role:
# Set `plan` empty if you don't want to assume IAM role before terraform plan
plan: arn:aws:iam::yyyyyyyyyyyy:role/cptest-plat-gbl-identity-gitops
apply: arn:aws:iam::yyyyyyyyyyyy:role/cptest-plat-gbl-identity-gitops

Support OpenTofu

This action supports OpenTofu.

important

Please note! OpenTofu supported by Atmos >= 1.73.0. For details read

To enable OpenTofu add the following settings to atmos.yaml

  • Set the opentofu-version in the atmos.yaml to the desired version
  • Set components.terraform.command to tofu

Example


components:
terraform:
command: tofu

...

integrations:
github:
gitops:
opentofu-version: 1.7.3
...

Workflow example

name: Pull Request
on:
pull_request:
branches: [ 'main' ]
types: [opened, synchronize, reopened, closed, labeled, unlabeled]

jobs:
atmos-affected:
runs-on: ubuntu-latest
steps:
- id: affected
uses: cloudposse/github-action-atmos-affected-stacks@v6
with:
atmos-config-path: ./rootfs/usr/local/etc/atmos/
atmos-version: 1.99.0
nested-matrices-count: 1

outputs:
matrix: ${{ steps.affected.outputs.matrix }}
has-affected-stacks: ${{ steps.affected.outputs.has-affected-stacks }}

# This job is an example how to use the affected stacks with the matrix strategy
atmos-plan:
needs: ["atmos-affected"]
if: ${{ needs.atmos-affected.outputs.has-affected-stacks == 'true' }}
name: Plan ${{ matrix.stack_slug }}
runs-on: ubuntu-latest
strategy:
max-parallel: 10
fail-fast: false # Don't fail fast to avoid locking TF State
matrix: ${{ fromJson(needs.atmos-affected.outputs.matrix) }}
## Avoid running the same stack in parallel mode (from different workflows)
concurrency:
group: ${{ matrix.stack_slug }}
cancel-in-progress: false
steps:
- name: Plan Atmos Component
uses: cloudposse/github-action-atmos-terraform-plan@v4
with:
component: ${{ matrix.component }}
stack: ${{ matrix.stack }}
atmos-config-path: ./rootfs/usr/local/etc/atmos/
atmos-version: 1.99.0

Migrating from v5 to v6

The notable changes in v6 are:

  • v6 works only with atmos >= 1.99.0
  • v6 allow to skip internal checkout with skip-checkout input

The only required migration step is updating atmos version to >= 1.80.0

Migrating from v4 to v5

The notable changes in v5 are:

  • v5 works only with atmos >= 1.80.0
  • v5 supports atmos templating

The only required migration step is updating atmos version to >= 1.80.0

Migrating from v3 to v4

The notable changes in v4 are:

  • v4 perform aws authentication assuming integrations.github.gitops.role.plan IAM role

No special migration steps required

Migrating from v2 to v3

The notable changes in v3 are:

  • v3 works only with atmos >= 1.63.0
  • v3 drops install-terraform input because terraform is not required for affected stacks call
  • v3 drops atmos-gitops-config-path input and the ./.github/config/atmos-gitops.yaml config file. Now you have to use GitHub Actions environment variables to specify the location of the atmos.yaml.

The following configuration fields now moved to GitHub action inputs with the same names

name
atmos-version
atmos-config-path

The following configuration fields moved to the atmos.yaml configuration file.

nameYAML path in atmos.yaml
aws-regionintegrations.github.gitops.artifact-storage.region
terraform-state-bucketintegrations.github.gitops.artifact-storage.bucket
terraform-state-tableintegrations.github.gitops.artifact-storage.table
terraform-state-roleintegrations.github.gitops.artifact-storage.role
terraform-plan-roleintegrations.github.gitops.role.plan
terraform-apply-roleintegrations.github.gitops.role.apply
terraform-versionintegrations.github.gitops.terraform-version
enable-infracostintegrations.github.gitops.infracost-enabled
sort-byintegrations.github.gitops.matrix.sort-by
group-byintegrations.github.gitops.matrix.group-by

For example, to migrate from v2 to v3, you should have something similar to the following in your atmos.yaml:

./.github/config/atmos.yaml

# ... your existing configuration

integrations:
github:
gitops:
terraform-version: 1.5.2
infracost-enabled: false
artifact-storage:
region: us-east-2
bucket: cptest-core-ue2-auto-gitops
table: cptest-core-ue2-auto-gitops-plan-storage
role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-core-ue2-auto-gitops-gha
role:
plan: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
apply: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
matrix:
sort-by: .stack_slug
group-by: .stack_slug | split("-") | [.[0], .[2]] | join("-")

.github/workflows/main.yaml

  - id: affected
uses: cloudposse/github-action-atmos-affected-stacks@v3
with:
atmos-config-path: ./rootfs/usr/local/etc/atmos/
atmos-version: 1.63.0

This corresponds to the v2 configuration (deprecated) below.

The v2 configuration file ./.github/config/atmos-gitops.yaml looked like this:

atmos-version: 1.45.3
atmos-config-path: ./rootfs/usr/local/etc/atmos/
terraform-state-bucket: cptest-core-ue2-auto-gitops
terraform-state-table: cptest-core-ue2-auto-gitops
terraform-state-role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-core-ue2-auto-gitops-gha
terraform-plan-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
terraform-apply-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
terraform-version: 1.5.2
aws-region: us-east-2
enable-infracost: false
sort-by: .stack_slug
group-by: .stack_slug | split("-") | [.[0], .[2]] | join("-")

And the v2 GitHub Action Workflow looked like this.

.github/workflows/main.yaml

  - id: affected
uses: cloudposse/github-action-atmos-affected-stacks@v2
with:
atmos-gitops-config-path: ./.github/config/atmos-gitops.yaml

Migrating from v1 to v2

v2 moves most of the inputs to the Atmos GitOps config path ./.github/config/atmos-gitops.yaml. Simply create this file, transfer your settings to it, then remove the corresponding arguments from your invocations of the cloudposse/github-action-atmos-affected-stacks action.

name
atmos-version
atmos-config-path
terraform-state-bucket
terraform-state-table
terraform-state-role
terraform-plan-role
terraform-apply-role
terraform-version
aws-region
enable-infracost

If you want the same behavior in v2 as in v1 you should create config ./.github/config/atmos-gitops.yaml with the same variables as in v1 inputs.

  - name: Determine Affected Stacks
uses: cloudposse/github-action-atmos-affected-stacks@v2
id: affected
with:
atmos-gitops-config-path: ./.github/config/atmos-gitops.yaml
nested-matrices-count: 1

Which would produce the same behavior as in v1, doing this:

  - name: Determine Affected Stacks
uses: cloudposse/github-action-atmos-affected-stacks@v1
id: affected
with:
atmos-version: 1.45.3
atmos-config-path: ./rootfs/usr/local/etc/atmos/
terraform-state-bucket: cptest-core-ue2-auto-gitops
terraform-state-table: cptest-core-ue2-auto-gitops
terraform-state-role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-core-ue2-auto-gitops-gha
terraform-plan-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
terraform-apply-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
terraform-version: 1.5.2
aws-region: us-east-2
enable-infracost: false