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.
The workflows and components currently use "gitops" terminology. This will be updated to "atmos-pro" in a future release.
Before You Begin
- Terraform state backend deployed (Initialize Terraform State)
- AWS accounts provisioned (Deploy Accounts)
- Atmos Auth configured for local deployments (How to Log Into AWS)
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 planand retrieves them duringterraform apply. This ensures the exact plan reviewed in a PR is what gets applied on merge. Created with thes3-bucketcomponent. 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
dynamodbcomponent. 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-rolecomponent.
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 theiam-rolecomponent. 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 theiam-rolecomponent.
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-providercomponent.
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.
Below is an example only. The latest version will be included with the reference architecture package.
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.
Below is an example only. The latest version will be included with the reference architecture package.
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:
Alternatively, use Atmos Vendoring directly.
2 Deploy Infrastructure
Deploy the Atmos Pro infrastructure components:
This workflow deploys the Plan File Storage and GitHub OIDC integration:
github-oidc-provider— Creates the OIDC provider in this account if not already deployeds3-bucket/gitops— S3 bucket for storing Terraform plan filesdynamodb/gitops— DynamoDB table for plan file metadata and lockinggitops-iam-policy— IAM policy granting access to plan storage resourcesiam-role/gitops— IAM role for accessing plan file storage (single account)
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
gitopsexists and trusts your GitHub repository - IAM policy grants access to the plan storage resources
- IAM roles
plannerandterraformexist 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