Skip to main content

GitHub Actions

GitHub Actions are a powerful way to automate your workflows with Atmos. Use these actions to plan, apply, and manage your Terraform infrastructure with Atmos.

This collection of GitHub Actions is designed to work specifically with Atmos in an opinionated manner, enabling you to implement a modern change management system entirely within the native GitHub UI. These Actions use the standard atmos.yaml configuration and some backing services designed to properly manage Terraform plan files, including their invalidation.

These GitHub Actions stribe to be cloud-agnostic; however, most of our instructions focus on AWS, where we predominantly use them. None of these actions require hardcoded credentials, and all work using GitHub OIDC and GitHub Apps managed by your organization. These Actions do not require any subscriptions and are based entirely on open source.

GitHub Actions for Atmos

Requirements

GitHub Actions that utilize "plan file" storage depends on a few resources:

  • S3 bucket for storing planfiles
  • DynamoDB table for retrieving metadata about planfiles
  • 2x IAM roles for "planning" and accessing the "state" bucket
  • atmos.yaml config with GitOps settings

S3 Bucket

This action can use any S3 Bucket to keep track of your planfiles. Just ensure the bucket is properly locked down since planfiles may contain secrets.

For example, vendor in the s3-component, then using an Atmos stack configuration, define a bucket using the s3-bucket component with this catalog configuration:

stacks/catalog/s3-bucket/gitops.yaml

import:
- catalog/s3-bucket/defaults

components:
terraform:
# S3 Bucket for storing Terraform Plans
gitops/s3-bucket:
metadata:
component: s3-bucket
inherits:
- s3-bucket/defaults
vars:
name: gitops-plan-storage
allow_encrypted_uploads_only: false

Assign this S3 Bucket ARN to the terraform-plan-bucket input.

DynamoDB Table

Similarly, a simple DynamoDB table can be provisioned using our dynamodb component. Set the Hash Key and create a Global Secondary Index as follows:

stacks/catalog/dynamodb/gitops.yaml

import:
- catalog/dynamodb/defaults

components:
terraform:
# DynamoDB table used to store metadata for Terraform Plans
gitops/dynamodb:
metadata:
component: dynamodb
inherits:
- dynamodb/defaults
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

Pass the ARN of this table as the input to the terraform-plan-table of the cloudposse/github-action-atmos-terraform-plan GitHub Action.

IAM Access Roles

First create an access role for storing and retrieving planfiles from the S3 Bucket and DynamoDB table. We deploy this role using the gitops component. Assign this role ARN to the terraform-state-role input.

Next, create a role for GitHub workflows to use to plan and apply Terraform. We typically create an "AWS Team" with our aws-teams component, and then allow this team to assume terraform in the delegated accounts with our aws-team-roles component. Assign this role ARN to the terraform-plan-role input

Atmos Configuration

The actions that works with atmos >= 1.63.0 expects the Atmos configuration file atmos.yaml to be present in the repository. The config should have the following structure:

rootfs/usr/local/etc/atmos/atmos.yaml

integrations:
github:
gitops:
terraform-version: 1.5.2
infracost-enabled: false
artifact-storage:
region: us-east-2
bucket: cptest-core-ue2-auto-gitops
table: cptest-core-ue2-auto-gitops-plan-storage
role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-core-ue2-auto-gitops-gha
role:
plan: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
apply: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
matrix:
sort-by: .stack_slug
group-by: .stack_slug | split("-") | [.[0], .[2]] | join("-")

For actions that use atmos < 1.63.0 the settings passed as github action inputs. Please follow documentation for each action to see the required inputs.

Compatibility Matrix

Important!

Our GitHub Actions depend on specific versions of Atmos.

Artifacts Upgrade

With version v2 of cloudposse/github-action-atmos-terraform-drift-detection and version v3 of cloudposse/github-action-atmos-terraform-plan, the artifact storage configuration was updated to use the same structure. Both will need to be updated to these versions or later to pass artifacts across the actions.

Please see the release notes:

  1. https://github.com/cloudposse/github-action-atmos-terraform-plan/releases/tag/v3.0.0
  2. https://github.com/cloudposse/github-action-atmos-terraform-drift-detection/releases/tag/v2.0.0

Atmos < 1.63.0

If you are using Atmos < 1.63.0, please refer to the following table:

Github actionAtmos < 1.63.0Atmos >= 1.63.0
github-action-atmos-affected-stacksv2v1 or greater
github-action-atmos-terraform-planv1v2 or greater
github-action-atmos-terraform-applyv1v2 or greater
github-action-atmos-terraform-drift-remediationv1v2 or greater
github-action-atmos-terraform-drift-detectionv0v1 or greater