Affected Stacks
The Atmos Affected Stacks GitHub Action makes it easy to identify the affected atmos stacks for a pull request. Use it to build a matrix so you can run other actions based on what was affected.
This GitHub Action installs Atmos, then runs atmos describe affected, and outputs a comprehensive list of affected stacks, both as raw output and as a matrix to be used in subsequent GitHub action jobs.
Discover more details, including the full list of inputs and outputs, in the GitHub Action repository on GitHub.
How it works
The describe affected command works by comparing two different Git commits to generate a list of affected Atmos components and stacks. It assumes that the current repo root is a Git checkout and accepts a parameter to specify the second commit.
Overall Process:
- Clone the target branch (
--ref), check out the commit, or use the pre-cloned target repository - Deep merge all stack configurations for the current working and remote target branches.
- Identify changes in the component directories.
- Compare each section of the stack configuration to detect differences.
- Output a matrix containing a list of affected components and stacks
Atmos checks component folders for changes first, marking all related components and stacks as affected when changes are detected. It then skips evaluating those stacks for differences, streamlining the process.
Deleted Component Detection
The describe affected command also detects components and stacks that have been deleted in the current branch compared to the target branch. This enables CI/CD pipelines to trigger terraform destroy workflows for removed infrastructure.
Deleted components are marked with:
deleted: true- Indicates the component was removeddeletion_type: componentordeletion_type: stack- Specifies whether just the component or the entire stack was deleted
You can filter the matrix output to separate apply and destroy workflows:
jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
modified: ${{ steps.affected.outputs.modified }}
deleted: ${{ steps.affected.outputs.deleted }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect affected
id: affected
run: |
atmos describe affected --format json > affected.json
# Separate modified and deleted components
jq '[.[] | select(.deleted != true)]' affected.json > modified.json
jq '[.[] | select(.deleted == true)]' affected.json > deleted.json
echo "modified=$(cat modified.json | jq -c)" >> $GITHUB_OUTPUT
echo "deleted=$(cat deleted.json | jq -c)" >> $GITHUB_OUTPUT
apply:
needs: detect-changes
if: needs.detect-changes.outputs.modified != '[]'
strategy:
matrix:
include: ${{ fromJson(needs.detect-changes.outputs.modified) }}
steps:
- uses: actions/checkout@v4
- uses: cloudposse/github-action-setup-atmos@v2
- run: atmos terraform apply ${{ matrix.component }} -s ${{ matrix.stack }}
destroy:
needs: detect-changes
if: needs.detect-changes.outputs.deleted != '[]'
environment: destroy-approval # Requires manual approval via GitHub Environment protection rules
strategy:
matrix:
include: ${{ fromJson(needs.detect-changes.outputs.deleted) }}
steps:
# IMPORTANT: Check out the BASE branch (target branch), not HEAD.
# The deleted component's configuration only exists in BASE.
- uses: actions/checkout@v4
with:
ref: ${{ github.base_ref }}
- uses: cloudposse/github-action-setup-atmos@v2
- run: atmos terraform destroy ${{ matrix.component }} -s ${{ matrix.stack }} --auto-approve
The example above uses environment: destroy-approval to require manual approval before destroying resources.
You must configure the environment
in your repository settings with required reviewers. The --auto-approve flag is used because approval
happens at the GitHub Actions level, not at the Terraform prompt.
Important: The destroy job must check out the BASE branch (target branch) rather than HEAD because
terraform destroy needs access to the component's stack configuration, which only exists in BASE.
Usage Example
atmos-terraform-plan.yaml
Requirements
This action has the requirements as Github Actions. Use the same config described there.