Atmos Pro Logo

Atmos Pro

ProductPricingDocsBlogChangelog
⌘K
Create Workspace
Atmos Pro Logo

Atmos Pro

ProductPricingDocsBlogChangelog
What is Atmos Pro?
Installation
How it Works
Workspaces
Authentication
Ordered Deployments
Deployment Approvals
Deployment Locking
Drift Detection
Event Triggers
Workflow Dispatches
Repository Permissions
Audit Log
Troubleshooting
Workspaces
Atmos Stacks
Atmos CI
Atmos Toolchain
Cloud Authentication
GitHub Repository
GitHub Workflows
GitHub Environments
Deployment Locking
Drift Detection
Webhooks
AWS
Reference
Atmos Docs
Example Repository
What is Atmos Pro?
Installation
How it Works
Workspaces
Authentication
Ordered Deployments
Deployment Approvals
Deployment Locking
Drift Detection
Event Triggers
Workflow Dispatches
Repository Permissions
Audit Log
Troubleshooting
Workspaces
Atmos Stacks
Atmos CI
Atmos Toolchain
Cloud Authentication
GitHub Repository
GitHub Workflows
GitHub Environments
Deployment Locking
Drift Detection
Webhooks
AWS
Reference
Atmos Docs
Example Repository

AWS: GitHub OIDC and IAM Roles

Set up keyless GitHub Actions authentication to AWS using OIDC, IAM roles, Atmos auth profiles, and GitHub workflows.


This guide walks you through setting up keyless authentication between GitHub Actions and AWS for Terraform CI/CD. By the end, your GitHub Actions workflows will authenticate to AWS using short-lived OIDC tokens — no static credentials required.
  1. 1
    GitHub OIDC Identity Provider — Create the trust relationship between GitHub and your AWS account.
  2. 2
    IAM Roles — Create IAM roles that GitHub Actions assumes to run Terraform, scoped to your repository.
  3. 3
    Atmos Auth Profiles — Configure the Atmos CLI to use the OIDC provider and roles at runtime.
  4. 4
    GitHub Workflows — Wire up your GitHub Actions workflows to use the auth profiles.
Everything is defined inline using Atmos source provisioning — no pre-vendored components or imports required.
Curious how all the pieces connect? Jump to How It All Fits Together.
The OIDC provider tells AWS to trust tokens issued by GitHub Actions. Deploy this once per AWS account.
stacks/catalog/github-ci.yaml
components:
  terraform:
    github-oidc-provider:
      source:
        uri: github.com/cloudposse-terraform-components/aws-github-oidc-provider.git//src
        version: v1.535.1
      provision:
        workdir:
          enabled: true
      vars:
        enabled: true
atmos terraform apply github-oidc-provider --stack dev
After deploying, note the provider ARN from the Terraform output — you'll need it for the IAM roles in the next step.
Create IAM roles that GitHub Actions assumes via the OIDC provider. The role's trust policy ensures only your repository can assume it.
One role with full access for both terraform plan and terraform apply. Best for small teams or single-account setups.
stacks/catalog/github-ci.yaml
components:
  terraform:
    iam-role/terraform:
      metadata:
        component: iam-role
      source:
        uri: github.com/cloudposse-terraform-components/aws-iam-role.git//src
        version: v1.537.0
      provision:
        workdir:
          enabled: true
      vars:
        enabled: true
        name: terraform
        role_description: |
          IAM role for GitHub Actions CI/CD.
          Trusts the GitHub OIDC provider for keyless authentication.
 
        managed_policy_arns:
          - arn:aws:iam::aws:policy/AdministratorAccess
 
        # GitHub OIDC trust
        github_oidc_provider_enabled: true
        github_oidc_provider_arn: arn:aws:iam::111111111111:oidc-provider/token.actions.githubusercontent.com  # Replace with your OIDC provider ARN
        trusted_github_org: acme                  # Replace with your GitHub org
        trusted_github_repos:
          - "acme/infra-live"                     # Replace with your repo
 
        policy_statements:
          TerraformStateBackendAssumeRole:
            effect: "Allow"
            actions:
              - "sts:AssumeRole"
              - "sts:TagSession"
              - "sts:SetSourceIdentity"
            resources:
              - arn:aws:iam::111111111111:role/my-tfstate-role  # Replace with your TF state backend role ARN
By default, trusted_github_repos: ["acme/infra-live"] trusts any workflow run from that repository — a pull request preview can assume the same role as a production deploy. To restrict which workflow contexts can assume a role, append a constraint suffix to the repo entry. The suffix maps to a match pattern used in the IAM trust policy's StringLike condition against the OIDC sub claim.
trusted_github_repos entryIAM sub match patternScopes to
"acme/infra-live"repo:acme/infra-live:*Any ref, PR, or environment
"acme/infra-live:main"repo:acme/infra-live:ref:refs/heads/mainmain branch only
"acme/infra-live:environment:production"repo:acme/infra-live:environment:productionGitHub Environment production only
"acme/infra-live:ref:refs/heads/release/*"repo:acme/infra-live:ref:refs/heads/release/*Any release/* branch
"acme/infra-live:ref:refs/tags/v*"repo:acme/infra-live:ref:refs/tags/v*Any v* tag
For the Advanced setup with separate plan and apply roles, this means:
  • The planner role can stay broadly scoped — it's read-only, so it's safe for any PR or branch
  • The terraform (apply) role should be scoped to a GitHub Environment like production, so only workflows running in that environment can assume it
# Planner: broadly scoped (read-only, safe for any PR)
trusted_github_repos:
  - "acme/infra-live"
 
# Terraform: scoped to the 'production' GitHub Environment
trusted_github_repos:
  - "acme/infra-live:environment:production"
For this to work, your apply workflow must set the job's environment to the matching GitHub Environment name — this is what causes GitHub to include environment:production in the OIDC token's sub claim. The environment is typically passed as a workflow input (e.g., github_environment) so the workflow stays reusable across stages. See Step 4 for the workflow configuration.
Verify your OIDC setup with a minimal workflow
Before configuring Atmos profiles and workflows, you can test that your OIDC provider and IAM role are working with a minimal workflow that just calls sts get-caller-identity:
.github/workflows/test-oidc.yaml
name: Test AWS OIDC
 
on:
  workflow_dispatch:
 
permissions:
  id-token: write
  contents: read
 
jobs:
  test:
    runs-on: ubuntu-latest
 
    steps:
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::111111111111:role/acme-gbl-dev-terraform # Replace with your role ARN
          aws-region: us-east-2 # Replace with your region
 
      - name: Verify Identity
        run: aws sts get-caller-identity
Run this workflow manually from the Actions tab. If the output shows your assumed role ARN, the OIDC trust is working correctly and you can proceed to configure Atmos.
Auth profiles tell the Atmos CLI how to obtain cloud credentials at runtime. Set ATMOS_PROFILE in your workflow to activate a profile.
Each identity in a profile has a name like acme/admin or acme/planner. These names appear in your stack configuration when selecting which identity a component should use, so choose a convention that is clear and consistent.
Name identities after permission boundaries, not deployment contexts. The profile already captures the context (e.g., github for CI, local for development) — the identity name should describe what level of access is being granted, not where it's being used. This keeps identity names stable across profiles: acme/admin means the same thing whether you're authenticating via GitHub OIDC or local SSO.
We recommend the pattern {org}/{boundary}:
IdentityPermission boundaryTypical use
acme/adminFull administrative accessTerraform apply, infrastructure changes
acme/plannerRead-only accessTerraform plan, drift detection
acme/networkScoped to networking resourcesNetwork-specific components
This convention makes stack configuration self-documenting — when you see a component selecting acme/planner, you immediately know it only needs read-only access, regardless of which profile is active.
A single profile used for both plan and apply:
profiles/github/atmos.yaml
auth:
  providers:
    github-oidc:
      kind: github/oidc
      region: us-east-2                # Replace with your region
      spec:
        audience: sts.amazonaws.com
 
  identities:
    acme/admin:
      default: true
      kind: aws/assume-role
      via:
        provider: github-oidc
      principal:
        assume_role: arn:aws:iam::111111111111:role/acme-gbl-dev-terraform  # Replace with your role ARN
Wire up your GitHub Actions workflows to use the auth profiles. The key requirements are:
  • permissions: id-token: write so GitHub issues OIDC tokens
  • ATMOS_PROFILE environment variable to activate the correct auth profile
The examples below focus on the plan and apply workflows that use OIDC authentication. A complete Atmos Pro setup also requires workflows for detecting affected stacks and uploading instances. For the full set of workflows, see Configure GitHub Workflows.
With a single profile, both plan and apply workflows use the same ATMOS_PROFILE:
.github/workflows/atmos-terraform-plan.yaml
name: Atmos Terraform Plan
 
on:
  workflow_dispatch:
    inputs:
      component:
        description: "Component"
        required: true
        type: string
      stack:
        description: "Stack"
        required: true
        type: string
 
permissions:
  id-token: write
  contents: read
 
jobs:
  plan:
    runs-on: ubuntu-latest
 
    container:
      image: ghcr.io/cloudposse/atmos:${{ vars.ATMOS_VERSION }}
 
    defaults:
      run:
        shell: bash
 
    steps:
      - uses: actions/checkout@v6
 
      - name: Terraform Plan
        env:
          ATMOS_PROFILE: github
          COMPONENT: ${{ inputs.component }}
          STACK: ${{ inputs.stack }}
        run: |
          atmos terraform plan "${COMPONENT}" -s "${STACK}"
The GitHub OIDC Identity Provider is deployed once per AWS account. It establishes a trust relationship so AWS accepts tokens issued by GitHub Actions.
IAM roles reference that OIDC provider and include a trust policy scoped to one or more specific repositories. Only workflows running in those repositories can assume the role.
Atmos auth profiles tell the Atmos CLI how to exchange a GitHub OIDC token for temporary AWS credentials by assuming a specific IAM role. You use multiple profiles so the same Atmos configuration works in different contexts — a developer profile for local usage and a CI profile for GitHub Actions.
In your GitHub Actions workflows, the permissions block is what enables the token exchange:
permissions:
  id-token: write
  contents: read
Setting id-token: write tells GitHub to issue a short-lived OIDC token for the workflow run. The Atmos CLI picks up that token automatically and uses the active auth profile to assume the corresponding IAM role.
Finally, identities in the auth profile determine which IAM role is assumed. When an identity has default: true, it is used automatically for all components:
profiles/github/atmos.yaml (excerpt)
identities:
  acme/admin:
    default: true # Used for all components unless overridden
    kind: aws/assume-role
    via:
      provider: github-oidc
    principal:
      # This is the IAM role you provisioned with the iam-role component in Step 2
      assume_role: arn:aws:iam::111111111111:role/acme-gbl-dev-terraform
Identities follow the Atmos inheritance model, so you can override them at any level when specific components need different credentials.
This guide covers the OIDC and IAM foundation. To complete your Atmos Pro setup, you'll also need to:
  • Import your repositories into Atmos Pro so it can monitor pull requests and dispatch workflows
  • Configure repository permissions in Atmos Pro to control who can approve and apply changes
  • Set up the remaining GitHub workflows — the examples above cover plan and apply, but you also need workflows for detecting affected stacks and uploading instances

Next: Configure GitHub Workflows

Set up the complete set of workflows including affected stacks detection, plan, apply, and instance uploads.

Configure GitHub WorkflowsCloud Authentication for Azure & GCP

WebhooksAtmos Docs
Atmos Pro Logo

Atmos Pro

The fastest way to deploy your apps on AWS with Terraform and GitHub Actions.

GitHubTwitterLinkedInYouTubeSlack

For Developers

  • Quick Start
  • Example Workflows
  • Atmos Documentation

Community

  • Register for Office Hours
  • Join the Slack Community
  • Try our Newsletter

Company

  • About Cloud Posse
  • Security
  • Pricing
  • Blog
  • Media Kit

Legal

  • SaaS Agreement
  • Terms of Use
  • Privacy Policy
  • Disclaimer
  • Cookie Policy

© 2026 Cloud Posse, LLC. All rights reserved.

Checking status...