Skip to main content
Latest Documentation
This is the latest documentation for the Cloud Posse Reference Architecture. To determine which version you're currently using, please see Version Identification.

Deploy Plan File Storage with Atmos and Terraform

Deploy the AWS infrastructure required for Atmos Pro using Atmos and Terraform. This guide walks through deploying the GitHub OIDC provider and IAM roles needed for GitHub Actions to authenticate with AWS, along with the S3 bucket and DynamoDB table for plan file storage.

GitOps Terminology

The workflows and components currently use "gitops" terminology. This will be updated to "atmos-pro" in a future release.

Before You Begin

Overview

Atmos Pro dispatches GitHub Actions workflows that run in your GitHub repository. These workflows require three categories of AWS infrastructure:

Plan File Storage

S3 bucket and DynamoDB table to store Terraform plan files between the plan and apply phases, plus an IAM role to access them:

s3-bucket/gitops
Stores plan files generated by GitHub Actions during terraform plan and retrieves them during terraform apply. This ensures the exact plan reviewed in a PR is what gets applied on merge. Created with the s3-bucket component.
dynamodb/gitops
Tracks plan file metadata and maps git SHAs to their corresponding plan files, ensuring the correct plan is retrieved for each apply. This guarantees that merging a PR applies exactly the plan that was reviewed, even if multiple plans exist. Created with the dynamodb component.
iam-role/gitops
Grants GitHub Actions permission to read and write plan files in S3 and DynamoDB. This role is assumed via OIDC and is deployed only in the account containing the plan storage resources. Created with the iam-role component.

Terraform Execution Roles

IAM roles deployed in every account that allow GitHub Actions to run Terraform plan and apply:

iam-role/planner
Read-only role for running terraform plan. Grants permissions to read Terraform state and AWS resources but not modify them. Used by plan workflows to safely preview changes without risk of accidental modifications. Created with the iam-role component.
iam-role/terraform
Write role for running terraform apply. Grants full permissions to create, modify, and delete AWS resources as defined in your Terraform configurations. Used by apply workflows after changes are approved and merged. Created with the iam-role component.
NOTE:

These roles are configured through Atmos Auth and deployed as part of the Identity layer.

GitHub OIDC Provider

Enables GitHub Actions to authenticate with AWS without long-lived credentials. The OIDC provider must be deployed in every account where GitHub Actions needs to assume roles.

github-oidc-provider
Establishes a trust relationship between GitHub and AWS, allowing GitHub Actions workflows to assume IAM roles without storing AWS credentials as secrets. GitHub's OIDC tokens are exchanged for temporary AWS credentials. Must be deployed in each account where roles will be assumed. Created with the github-oidc-provider component.
NOTE:

The GitHub OIDC provider is likely already deployed as part of the Identity layer.

Configuration

1 Deploy S3 Bucket and DynamoDB Table

The plan file storage requires an S3 bucket to store plan files and a DynamoDB table to track metadata and map git SHAs to plans.

NOTE:

Below is an example only. The latest version will be included with the reference architecture package.

stacks/catalog/gitops/defaults.yaml
components:
terraform:
# S3 Bucket for storing Terraform Plans
gitops/s3-bucket:
settings:
pro:
enabled: false
metadata:
component: s3-bucket
vars:
name: gitops-plan-storage
allow_encrypted_uploads_only: false

# DynamoDB table used to store metadata for Terraform Plans
gitops/dynamodb:
settings:
pro:
enabled: false
metadata:
component: dynamodb
vars:
name: gitops-plan-storage
# This key (case-sensitive) is required for the cloudposse/github-action-terraform-plan-storage action
hash_key: id
range_key: ""
# Only these 2 attributes are required for creating the GSI,
# but there will be several other attributes on the table itself
dynamodb_attributes:
- name: 'createdAt'
type: 'S'
- name: 'pr'
type: 'N'
# This GSI is used to Query the latest plan file for a given PR.
global_secondary_index_map:
- name: pr-createdAt-index
hash_key: pr
range_key: createdAt
projection_type: ALL
non_key_attributes: []
read_capacity: null
write_capacity: null
# Auto delete old entries
ttl_enabled: true
ttl_attribute: ttl

2 Configure GitHub Repository Trust

All IAM roles (both GitOps and Terraform execution) need to trust your GitHub repository.

NOTE:

Below is an example only. The latest version will be included with the reference architecture package.

stacks/catalog/iam-role/gitops.yaml
components:
terraform:
iam-role/gitops:
metadata:
component: iam-role
vars:
enabled: true
name: gitops
role_description: |
Role for GitHub Actions to access the GitOps resources, such as the S3 Bucket and DynamoDB Table.
# Grants access to GitHub Actions via OIDC
github_oidc_provider_enabled: true
github_oidc_provider_arn: !terraform.state github-oidc-provider oidc_provider_arn
trusted_github_org: acme
trusted_github_repos:
- acme/infrastructure
policy_statements:
AllowDynamodbAccess:
effect: "Allow"
actions:
- "dynamodb:List*"
- "dynamodb:DescribeReservedCapacity*"
- "dynamodb:DescribeLimits"
- "dynamodb:DescribeTimeToLive"
resources:
- "*"
AllowDynamodbTableAccess:
effect: "Allow"
actions:
- "dynamodb:BatchGet*"
- "dynamodb:DescribeStream"
- "dynamodb:DescribeTable"
- "dynamodb:Get*"
- "dynamodb:Query"
- "dynamodb:Scan"
- "dynamodb:BatchWrite*"
- "dynamodb:CreateTable"
- "dynamodb:Delete*"
- "dynamodb:Update*"
- "dynamodb:PutItem"
resources:
- !terraform.state gitops/dynamodb core-use2-auto ".table_arn + ""/*"""
- !terraform.state gitops/dynamodb core-use2-auto table_arn
AllowS3Actions:
effect: "Allow"
actions:
- "s3:ListBucket"
resources:
- !terraform.state gitops/s3-bucket core-use2-auto bucket_arn
AllowS3ObjectActions:
effect: "Allow"
actions:
- "s3:*Object"
resources:
- !terraform.state gitops/s3-bucket core-use2-auto ".bucket_arn + ""/*"""

The Terraform execution roles (iam-role/planner and iam-role/terraform) use the same trust pattern and are configured in the Identity layer.

3 Verify GitHub Workflow Permissions

Your GitHub Action workflows need specific permissions to authenticate via OIDC:

permissions:
id-token: write # Required for requesting the JWT
contents: read # Required for actions/checkout

These permissions are already configured in the reference architecture workflows.

Deployment

1 Vendor Components

The GitOps stacks depend on components that may already exist in your component library (s3-bucket and dynamodb) and adds new components for GitHub OIDC authentication. Vendor these components with the included Atmos workflow:

Loading workflow...

Alternatively, use Atmos Vendoring directly.

2 Deploy Infrastructure

Deploy the Atmos Pro infrastructure components:

Loading workflow...

This workflow deploys the Plan File Storage and GitHub OIDC integration:

  1. github-oidc-provider — Creates the OIDC provider in this account if not already deployed
  2. s3-bucket/gitops — S3 bucket for storing Terraform plan files
  3. dynamodb/gitops — DynamoDB table for plan file metadata and locking
  4. gitops-iam-policy — IAM policy granting access to plan storage resources
  5. iam-role/gitops — IAM role for accessing plan file storage (single account)
Terraform Execution Roles

The iam-role/planner and iam-role/terraform roles are deployed separately as part of the Identity layer. These roles exist in every account and are configured through Atmos Auth.

Verification

After deployment, verify the GitOps infrastructure is correctly configured:

  • GitHub OIDC provider exists in every account
  • S3 bucket for plan file storage is created
  • DynamoDB table for plan file metadata is created
  • IAM role gitops exists and trusts your GitHub repository
  • IAM policy grants access to the plan storage resources
  • IAM roles planner and terraform exist in every account (deployed via Identity layer)

You can test the setup by creating a pull request — Atmos Pro will attempt to run plans using the deployed infrastructure.

Next Steps

With the AWS infrastructure deployed, verify your Atmos Pro setup by testing the GitHub integration. Verify Setup