This Github Action is used to run Terraform plan for a single, Atmos-supported component and save the given planfile to S3 and DynamoDB.
Tip
Cloud Posse uses atmos
to easily orchestrate multiple environments using Terraform.
Works with Github Actions, Atlantis, or Spacelift.
Watch demo of using Atmos with Terraform
Example of running
atmos
to manage infrastructure from our Quick Start tutorial.
This Github Action is used to run Terraform plan for a single, Atmos-supported component and save the given planfile to S3 and DynamoDB.
After running this action, apply Terraform with the companion action, github-action-atmos-terraform-apply
This GitHub Action requires AWS access for two different purposes. This action will attempt to first run terraform plan
against a given component and
then will use another role to save that given Terraform Plan to an S3 Bucket with metadata in a DynamoDB table. We recommend configuring
OpenID Connect with AWS
to allow GitHub to assume roles in AWS and then deploying both a Terraform Plan role and a Terraform State role.
For Cloud Posse documentation on setting up GitHub OIDC, see our github-oidc-provider
component.
In order to store Terraform State, we configure an S3 Bucket to store plan files and a DynamoDB table to track plan metadata. Both will need to be deployed before running
this action. For more on setting up those components, see the gitops
component (documentation pending). This action will then use the github-action-terraform-plan-storage action to update these resources.
Important
Please note! This GitHub Action only works with atmos >= 1.99.0
.
If you are using atmos >= 1.63.0, < 1.99.0
please use v2
or v3
version of this action.
If you are using atmos < 1.63.0
please use v1
version of this action.
The action expects the atmos configuration file atmos.yaml
to be present in the repository.
The action supports AWS and Azure to store Terraform plan files.
You can read more about plan storage in the cloudposse/github-action-terraform-plan-storage documentation.
Depending on the cloud provider, the following fields should be set in the atmos.yaml
:
The config should have the following structure:
integrations:
github:
gitops:
opentofu-version: 1.7.3
terraform-version: 1.5.2
infracost-enabled: false
artifact-storage:
plan-repository-type: s3
metadata-repository-type: dynamo
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:
# Set `plan` empty if you don't want to assume IAM role before terraform plan
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("-")
The config should have the following structure:
integrations:
github:
gitops:
opentofu-version: 1.7.3
terraform-version: 1.5.2
infracost-enabled: false
artifact-storage:
plan-repository-type: azureblob
metadata-repository-type: cosmos
blob-account-name: tfplans
blob-container-name: plans
cosmos-container-name: terraform-plan-storage
cosmos-database-name: terraform-plan-storage
cosmos-endpoint: "https://my-cosmo-account.documents.azure.com:443/"
# We remove the `role` section as it is AWS specific
matrix:
sort-by: .stack_slug
group-by: .stack_slug | split("-") | [.[0], .[2]] | join("-")
Important
Wherever it is possible to specify integration.github.gitops
on stack level
it is required to define default values in atmos.yaml
It is possible to override integration settings on a stack level by defining settings.integrations
.
components:
terraform:
foobar:
settings:
integrations:
github:
gitops:
artifact-storage:
bucket: cptest-plat-ue2-auto-gitops
table: cptest-plat-ue2-auto-gitops-plan-storage
role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-plat-ue2-auto-gitops-gha
role:
# Set `plan` empty if you don't want to assume IAM role before terraform plan
plan: arn:aws:iam::yyyyyyyyyyyy:role/cptest-plat-gbl-identity-gitops
apply: arn:aws:iam::yyyyyyyyyyyy:role/cptest-plat-gbl-identity-gitops
This action supports OpenTofu.
Important
Please note! OpenTofu supported by Atmos >= 1.73.0
.
For details read
To enable OpenTofu add the following settings to atmos.yaml
- Set the
opentofu-version
in theatmos.yaml
to the desired version - Set
components.terraform.command
totofu
components:
terraform:
command: tofu
...
integrations:
github:
gitops:
opentofu-version: 1.7.3
...
name: "atmos-terraform-plan"
on:
workflow_dispatch: {}
pull_request:
types:
- opened
- synchronize
- reopened
branches:
- main
# These permissions are required for GitHub to assume roles in AWS
permissions:
id-token: write
contents: read
jobs:
plan:
runs-on: ubuntu-latest
steps:
- name: Plan Atmos Component
uses: cloudposse/github-action-atmos-terraform-plan@v2
with:
component: "foobar"
stack: "plat-ue2-sandbox"
atmos-config-path: ./rootfs/usr/local/etc/atmos/
atmos-version: 1.81.0
The notable changes in v4
are:
v4
works only withatmos >= 1.99.0
v4
support azure plan and metadata storagev4
supports stack level integration gitops settingsv4
allow to skip internal checkout withskip-checkout
inputv4
support creating summary comments to PR
The only required migration step is updating atmos version to >= 1.99.0
The notable changes in v3
are:
v3
useactions/upload-artifact@v4
to share artifacts so it is not compatible withcloudposse/github-action-atmos-terraform-drift-detection
< v2.0.0
v3
support .terraform caching to performance improvment
No special migration steps required
The notable changes in v2
are:
v2
works only withatmos >= 1.63.0
v2
dropsinstall-terraform
input because terraform is not required for affected stacks callv2
dropsatmos-gitops-config-path
input and the./.github/config/atmos-gitops.yaml
config file. Now you have to use GitHub Actions environment variables to specify the location of theatmos.yaml
.
The following configuration fields now moved to GitHub action inputs with the same names
name |
---|
atmos-version |
atmos-config-path |
The following configuration fields moved to the atmos.yaml
configuration file.
name | YAML path in atmos.yaml |
---|---|
aws-region |
integrations.github.gitops.artifact-storage.region |
terraform-state-bucket |
integrations.github.gitops.artifact-storage.bucket |
terraform-state-table |
integrations.github.gitops.artifact-storage.table |
terraform-state-role |
integrations.github.gitops.artifact-storage.role |
terraform-plan-role |
integrations.github.gitops.role.plan |
terraform-apply-role |
integrations.github.gitops.role.apply |
terraform-version |
integrations.github.gitops.terraform-version |
enable-infracost |
integrations.github.gitops.infracost-enabled |
sort-by |
integrations.github.gitops.matrix.sort-by |
group-by |
integrations.github.gitops.matrix.group-by |
For example, to migrate from v1
to v2
, you should have something similar to the following in your atmos.yaml
:
./.github/config/atmos.yaml
# ... your existing configuration
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("-")
.github/workflows/main.yaml
- name: Plan Atmos Component
uses: cloudposse/github-action-atmos-terraform-plan@v2
with:
component: "foobar"
stack: "plat-ue2-sandbox"
atmos-config-path: ./rootfs/usr/local/etc/atmos/
atmos-version: 1.63.0
This corresponds to the v1
configuration (deprecated) below.
The v1
configuration file ./.github/config/atmos-gitops.yaml
looked like this:
atmos-version: 1.45.3
atmos-config-path: ./rootfs/usr/local/etc/atmos/
terraform-state-bucket: cptest-core-ue2-auto-gitops
terraform-state-table: cptest-core-ue2-auto-gitops
terraform-state-role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-core-ue2-auto-gitops-gha
terraform-plan-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
terraform-apply-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
terraform-version: 1.5.2
aws-region: us-east-2
enable-infracost: false
sort-by: .stack_slug
group-by: .stack_slug | split("-") | [.[0], .[2]] | join("-")
And the v1
GitHub Action Workflow looked like this.
.github/workflows/main.yaml
- name: Plan Atmos Component
uses: cloudposse/github-action-atmos-terraform-plan@v1
with:
component: "foobar"
stack: "plat-ue2-sandbox"
atmos-gitops-config-path: ./.github/config/atmos-gitops.yaml
v2
drops thecomponent-path
variable and instead fetches if directly from theatmos.yaml
file automatically. Simply remove thecomponent-path
argument from your invocations of thecloudposse/github-action-atmos-terraform-plan
action.v2
moves most of theinputs
to the Atmos GitOps config path./.github/config/atmos-gitops.yaml
. Simply create this file, transfer your settings to it, then remove the corresponding arguments from your invocations of thecloudposse/github-action-atmos-terraform-plan
action. | name | |--------------------------| |atmos-version
| |atmos-config-path
| |terraform-state-bucket
| |terraform-state-table
| |terraform-state-role
| |terraform-plan-role
| |terraform-apply-role
| |terraform-version
| |aws-region
| |enable-infracost
|
If you want the same behavior in v2
as in v1
you should create config ./.github/config/atmos-gitops.yaml
with the same variables as in v1
inputs.
- name: Plan Atmos Component
uses: cloudposse/github-action-atmos-terraform-plan@v1
with:
component: "foobar"
stack: "plat-ue2-sandbox"
atmos-gitops-config-path: ./.github/config/atmos-gitops.yaml
Which would produce the same behavior as in v1
, doing this:
- name: Plan Atmos Component
uses: cloudposse/github-action-atmos-terraform-plan@v1
with:
component: "foobar"
stack: "plat-ue2-sandbox"
component-path: "components/terraform/s3-bucket"
terraform-plan-role: "arn:aws:iam::111111111111:role/acme-core-gbl-identity-gitops"
terraform-state-bucket: "acme-core-ue2-auto-gitops"
terraform-state-role: "arn:aws:iam::999999999999:role/acme-core-ue2-auto-gitops-gha"
terraform-state-table: "acme-core-ue2-auto-gitops"
aws-region: "us-east-2"
Important
In Cloud Posse's examples, we avoid pinning modules to specific versions to prevent discrepancies between the documentation and the latest released versions. However, for your own projects, we strongly advise pinning each module to the exact version you're using. This practice ensures the stability of your infrastructure. Additionally, we recommend implementing a systematic approach for updating versions to avoid unexpected changes.
Name | Description | Default | Required |
---|---|---|---|
atmos-config-path | The path to the atmos.yaml file | N/A | true |
atmos-version | The version of atmos to install | >= 1.99.0 | false |
branding-logo-image | Branding logo image url | https://cloudposse.com/logo-300x69.svg | false |
branding-logo-url | Branding logo url | https://cloudposse.com/ | false |
component | The name of the component to plan. | N/A | true |
debug | Enable action debug mode. Default: 'false' | false | false |
drift-detection-mode-enabled | Indicate whether this action is used in drift detection workflow. | false | true |
infracost-api-key | Infracost API key | N/A | false |
metadata-retention-days | Infracost API key | 1 | false |
pr-comment | Set to 'true' to create a PR comment with the summary of the plan | false | false |
sha | Commit SHA to plan. Default: github.sha | ${{ github.event.pull_request.head.sha }} | true |
skip-checkout | Disable actions/checkout. Useful for when the checkout happens in a previous step and file are modified outside of git through other actions | false | false |
stack | The stack name for the given component. | N/A | true |
token | Used to pull node distributions for Atmos from Cloud Posse's GitHub repository. Since there's a default, this is typically not supplied by the user. When running this action on github.com, the default value is sufficient. When running on GHES, you can pass a personal access token for github.com if you are experiencing rate limiting. | ${{ github.server_url == 'https://github.com' && github.token || '' }} | false |
Name | Description |
---|---|
plan_file | Path to the terraform plan file |
plan_json | Path to the terraform plan in JSON format |
summary | Summary |
Check out these related projects.
For additional context, refer to some of these links.
- github-action-atmos-terraform-apply - Companion GitHub Action to apply Terraform for a given component
- github-action-terraform-plan-storage - GitHub Action to store Terraform plans
Tip
Use Cloud Posse's ready-to-go terraform architecture blueprints for AWS to get up and running quickly.
✅ We build it together with your team.
✅ Your team owns everything.
✅ 100% Open Source and backed by fanatical support.
📚 Learn More
Cloud Posse is the leading DevOps Accelerator for funded startups and enterprises.
Your team can operate like a pro today.
Ensure that your team succeeds by using Cloud Posse's proven process and turnkey blueprints. Plus, we stick around until you succeed.
- Reference Architecture. You'll get everything you need from the ground up built using 100% infrastructure as code.
- Deployment Strategy. Adopt a proven deployment strategy with GitHub Actions, enabling automated, repeatable, and reliable software releases.
- Site Reliability Engineering. Gain total visibility into your applications and services with Datadog, ensuring high availability and performance.
- Security Baseline. Establish a secure environment from the start, with built-in governance, accountability, and comprehensive audit logs, safeguarding your operations.
- GitOps. Empower your team to manage infrastructure changes confidently and efficiently through Pull Requests, leveraging the full power of GitHub Actions.
- Training. Equip your team with the knowledge and skills to confidently manage the infrastructure, ensuring long-term success and self-sufficiency.
- Support. Benefit from a seamless communication over Slack with our experts, ensuring you have the support you need, whenever you need it.
- Troubleshooting. Access expert assistance to quickly resolve any operational challenges, minimizing downtime and maintaining business continuity.
- Code Reviews. Enhance your team’s code quality with our expert feedback, fostering continuous improvement and collaboration.
- Bug Fixes. Rely on our team to troubleshoot and resolve any issues, ensuring your systems run smoothly.
- Migration Assistance. Accelerate your migration process with our dedicated support, minimizing disruption and speeding up time-to-value.
- Customer Workshops. Engage with our team in weekly workshops, gaining insights and strategies to continuously improve and innovate.
This project is under active development, and we encourage contributions from our community.
Many thanks to our outstanding contributors:
For 🐛 bug reports & feature requests, please use the issue tracker.
In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow.
- Review our Code of Conduct and Contributor Guidelines.
- Fork the repo on GitHub
- Clone the project to your own machine
- Commit changes to your own branch
- Push your work back up to your fork
- Submit a Pull Request so that we can review your changes
NOTE: Be sure to merge the latest changes from "upstream" before making a pull request!
Join our Open Source Community on Slack. It's FREE for everyone! Our "SweetOps" community is where you get to talk with others who share a similar vision for how to rollout and manage infrastructure. This is the best place to talk shop, ask questions, solicit feedback, and work together as a community to build totally sweet infrastructure.
Sign up for our newsletter and join 3,000+ DevOps engineers, CTOs, and founders who get insider access to the latest DevOps trends, so you can always stay in the know. Dropped straight into your Inbox every week — and usually a 5-minute read.
Join us every Wednesday via Zoom for your weekly dose of insider DevOps trends, AWS news and Terraform insights, all sourced from our SweetOps community, plus a live Q&A that you can’t find anywhere else. It's FREE for everyone!
Preamble to the Apache License, Version 2.0
Complete license is available in the LICENSE
file.
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
All other trademarks referenced herein are the property of their respective owners.
Copyright © 2017-2024 Cloud Posse, LLC