GitHub Actions Workflows
Create the GitHub Actions workflows that Atmos Pro dispatches to plan, apply, and detect drift on your infrastructure.
Atmos Pro orchestrates your deployments by dispatching GitHub Actions workflows that you define. For security, Atmos Pro only dispatches workflows against your repository's default branch. This ensures your branch protection rules guard against manipulation — workflows must be merged before they take effect.
You'll create the following workflows in your repository:
- 1Affected Stacks — Runs on every pull request to detect which stacks changed
- 2Plan — Dispatched by Atmos Pro to run
atmos terraform planfor each affected stack - 3Apply — Dispatched by Atmos Pro when a plan is approved
- 4Upload Instances — Runs on merge to the default branch and on a schedule to power drift detection
The workflows below call Atmos commands directly, uploading results to Atmos Pro via the
--upload and --upload-status flags. Drop these into your repo to get started.This workflow runs on every pull request event against the main branch. It uses
atmos describe affected to determine which stacks changed and uploads the results to Atmos Pro.name: 👽 Atmos Pro
run-name: 👽 Atmos Pro
on:
pull_request:
types:
- opened
- synchronize
- reopened
- closed
branches:
- main
concurrency:
group: "${{ github.ref }}"
cancel-in-progress: false
permissions:
id-token: write
contents: read
checks: write
jobs:
affected:
name: Trigger Affected Stacks
runs-on:
- "ubuntu-latest"
container:
image: ghcr.io/cloudposse/atmos:${{ vars.ATMOS_VERSION }}
defaults:
run:
shell: bash
if: |
!contains(github.event.pull_request.labels.*.name, 'no-apply') &&
(github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged == true))
steps:
- name: Checkout
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Configure Git Safe Directory
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Determine Affected Stacks
env:
ATMOS_PRO_WORKSPACE_ID: ${{ vars.ATMOS_PRO_WORKSPACE_ID }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ATMOS_PROFILE: github
run: |
atmos describe affected --uploadThe
ATMOS_VERSION GitHub Actions variable should be set to a version without the v prefix (e.g.,
1.175.0, not v1.x.x), since Docker image tags do not use the v prefix.All workflows use GitHub OIDC to authenticate with the Atmos Pro API, eliminating the need for long-lived API tokens. Workflows run wherever your GitHub Actions run, whether on GitHub-hosted runners or your own self-hosted runners.
Atmos uses Auth to manage how the CLI obtains cloud credentials. Because you typically have different identities depending on context — OIDC in CI versus single sign-on locally — we recommend using profiles. Profiles let you define separate auth configurations for each context (e.g.,
profiles/github/atmos.yaml for GitHub Actions, profiles/local/atmos.yaml for local development).In your workflows, set the
ATMOS_PROFILE environment variable to load the right profile:env:
ATMOS_PROFILE: githubThe plan and apply workflows use
workflow_dispatch so Atmos Pro can trigger them at the right time in the right order. Atmos Pro passes the following inputs:sha(required)- The commit SHA to check out. Since
workflow_dispatchdoesn't have pull request context, Atmos Pro passes the SHA explicitly. component(required)- The Atmos component to run the workflow on.
stack(required)- The Atmos stack to run the workflow on.
github_environment(required for apply)- The GitHub Environment to use for the workflow run. This ties into GitHub's native approval gates — configure environment protection rules to require manual approval before applies run. We recommend defining environments along permission boundaries, typically by stage (e.g.,
dev,staging,production), the same way you separate cloud accounts or roles. Atmos Pro reads this value from your stack configuration and passes it automatically.
Each workflow YAML file must declare a
permissions block so the GitHub Actions runner token has the access it needs:permissions:
id-token: write # Required for OIDC token generation
contents: read # Required for checking out code
checks: write # Required for creating/updating GitHub Checks
statuses: write # Required for posting commit status contextsThe
checks and statuses permissions are needed because the Atmos CLI (via Native CI) writes status checks and commit statuses directly from your workflow runs — for example, reporting how many resources a Terraform plan will create, update, or destroy. Atmos Pro orchestrates when workflows run, but the CLI itself is what posts these details back to GitHub.The
ATMOS_PRO_WORKSPACE_ID variable tells Atmos Pro which workspace a pull request or event belongs to. Set it as a GitHub Actions variable in your repository or organization settings. Your current workspace ID is ws_xxxxxxxxxxxxxxxxxxxxxxxxxxxx — you can always find this in the Workspace Settings page. The GITHUB_TOKEN is automatically provided by GitHub Actions.Here's how it looks in your workflow YAML — reference the variable using
vars.ATMOS_PRO_WORKSPACE_ID:env:
ATMOS_PRO_WORKSPACE_ID: ${{ vars.ATMOS_PRO_WORKSPACE_ID }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ATMOS_PROFILE: githubThe
env block in the workflows is a GitHub Actions workflow env
block, not the Atmos
env configuration section. It sets environment variables for the runner so the Atmos CLI can authenticate with Atmos
Pro.Atmos Pro uses the workflow filename to determine what command each deployment represents. This lets the dashboard show the correct badge and filter deployments by command type.
Recommended workflow filenames:
| Command | Filename | Description |
|---|---|---|
| Affected | atmos-pro.yaml | Runs atmos describe affected --upload |
| Plan | atmos-terraform-plan.yaml | Runs atmos terraform plan |
| Apply | atmos-terraform-apply.yaml | Runs atmos terraform apply |
| Upload Instances | atmos-pro-upload-instances.yaml | Runs atmos list instances --upload |
Atmos Pro checks if the filename contains keywords like
plan, apply, affected, or instances (case-insensitive). If the filename doesn't contain a recognizable keyword, the command is determined later when the Atmos CLI reports back the actual command that was executed.The workflow filename is a best-effort heuristic. The canonical command comes from the Atmos CLI callback after the
workflow runs. If the CLI reports a different command than what the filename suggests, the CLI value takes precedence.
You may have noticed how simple these workflows are — that's by design. Atmos Native CI handles all the undifferentiated heavy lifting so your workflows can focus on running Atmos commands. Out of the box, Native CI takes care of:
- Toolchain installation — Atmos, Terraform/OpenTofu, and dependencies
- Authentication — OIDC token exchanges and cloud credential management
- Terraform backend provisioning — Automatic setup of state storage
- Status checks — Reporting plan/apply results back to GitHub
- Job summaries — Rich workflow run summaries in GitHub Actions
Coming soon, Native CI will also handle plan file storage, GitHub PR comments, GitHub commit status checks, passing Terraform outputs to other workflow steps, and more.
Learn about Atmos Native CI
Ready to get started?
Install the Atmos Pro GitHub App to get started, or explore a complete working example.