Infracost GitHub Actions
Try the GitHub App
ππ We recommend using the free Infracost GitHub App instead as it has many benefits over GitHub Actions
This project provide a GitHub Action and examples for Infracost, so you can see cloud cost estimates for Terraform in pull requests π°
Quick start
The following steps assume a simple Terraform directory is being used, we recommend you use a more relevant example if required.
-
If you haven't done so already, download Infracost and run
infracost auth login
to get a free API key. -
Retrieve your Infracost API key by running
infracost configure get api_key
. -
Create a repo secret called
INFRACOST_API_KEY
with your API key. -
Create a new file in
.github/workflows/infracost.yml
in your repo with the following content.
# The GitHub Actions docs (https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#on)
# describe other options for 'on', 'pull_request' is a good default.
on: [pull_request]
env:
# If you use private modules you'll need this env variable to use
# the same ssh-agent socket value across all jobs & steps.
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
jobs:
infracost:
name: Infracost
runs-on: ubuntu-latest
permissions:
contents: read
# Required to post comments
pull-requests: write
env:
TF_ROOT: examples/terraform-project/code
# If you're using Terraform Cloud/Enterprise and have variables or private modules stored
# on there, specify the following to automatically retrieve the variables:
# INFRACOST_TERRAFORM_CLOUD_TOKEN: ${{ secrets.TFC_TOKEN }}
# INFRACOST_TERRAFORM_CLOUD_HOST: app.terraform.io # Change this if you're using Terraform Enterprise
steps:
# If you use private modules, add an environment variable or secret
# called GIT_SSH_KEY with your private key, so Infracost can access
# private repositories (similar to how Terraform/Terragrunt does).
# - name: add GIT_SSH_KEY
# run: |
# ssh-agent -a $SSH_AUTH_SOCK
# mkdir -p ~/.ssh
# echo "${{ secrets.GIT_SSH_KEY }}" | tr -d '\r' | ssh-add -
# ssh-keyscan github.com >> ~/.ssh/known_hosts
- name: Setup Infracost
uses: infracost/actions/setup@v2
# See https://github.com/infracost/actions/tree/master/setup for other inputs
# If you can't use this action, see Docker images in https://infracost.io/cicd
with:
api-key: ${{ secrets.INFRACOST_API_KEY }}
# Checkout the base branch of the pull request (e.g. main/master).
- name: Checkout base branch
uses: actions/checkout@v3
with:
ref: '${{ github.event.pull_request.base.ref }}'
# Generate Infracost JSON file as the baseline.
- name: Generate Infracost cost estimate baseline
run: |
infracost breakdown --path=${TF_ROOT} \
--format=json \
--out-file=/tmp/infracost-base.json
# Checkout the current PR branch so we can create a diff.
- name: Checkout PR branch
uses: actions/checkout@v3
# Generate an Infracost diff and save it to a JSON file.
- name: Generate Infracost diff
run: |
infracost diff --path=${TF_ROOT} \
--format=json \
--compare-to=/tmp/infracost-base.json \
--out-file=/tmp/infracost.json
# Posts a comment to the PR using the 'update' behavior.
# This creates a single comment and updates it. The "quietest" option.
# The other valid behaviors are:
# delete-and-new - Delete previous comments and create a new one.
# hide-and-new - Minimize previous comments and create a new one.
# new - Create a new cost estimate comment on every push.
# See https://www.infracost.io/docs/features/cli_commands/#comment-on-pull-requests for other options.
- name: Post Infracost comment
run: |
infracost comment github --path=/tmp/infracost.json \
--repo=$GITHUB_REPOSITORY \
--github-token=${{github.token}} \
--pull-request=${{github.event.pull_request.number}} \
--behavior=update
-
π That's it! Send a new pull request to change something in Terraform that costs money. You should see a pull request comment that gets updated, e.g. the π and π emojis will update as changes are pushed!
If there are issues, check the GitHub Actions logs and this page.
-
In Infracost Cloud, go to Org Settings and enable the dashboard, then trigger your CI/CD pipeline again. This causes the CLI to send its JSON output to your dashboard; the JSON does not contain any cloud credentials or secrets, see the FAQ for more information.
This is our SaaS product that builds on top of Infracost open source. It enables team leads, managers and FinOps practitioners to setup tagging policies, guardrails and best practices to help guide the team. For example, you can check for required tag keys/values, or suggest switching AWS GP2 volumes to GP3 as they are more performant and cheaper.
Troubleshooting
Permissions issue
If you receive an error when running the infracost comment
command in your pipeline, it's probably related to ${{ github.token }}
. This is the default GitHub token available to actions and is used to post comments. The default token permissions are read-only by default and pull-requests: write
is required. If you are using SAML single sign-on, you must first authorize the token.
add GIT_SSH_KEY
step fails
The If you are using private modules and receive a option requires an argument -- a
error in the add GIT_SSH_KEY
step:
- Make sure you have the following set in your workflow
SSH_AUTH_SOCK
:env: SSH_AUTH_SOCK: /tmp/ssh_agent.sock
- Try changing the
ssh-agent -a $SSH_AUTH_SOCK
line to the following:ssh-agent -a "${{ env.SSH_AUTH_SOCK }}"
Examples
The examples directory demonstrates how these actions can be used for different projects. They all work by using the default Infracost CLI option that parses HCL, thus a Terraform plan JSON is not needed.
- Terraform/Terragrunt projects (single or multi): a repository containing one or more (e.g. mono repos) Terraform or Terragrunt projects
- Multi-projects using a config file: repository containing multiple Terraform projects that need different inputs, i.e. variable files or Terraform workspaces
- Slack: send cost estimates to Slack
For advanced use cases where the estimate needs to be generated from Terraform plan JSON files, see the plan JSON examples here.
Contributing
Issues and pull requests are welcome! For development details, see the contributing guide. For major changes, including interface changes, please open an issue first to discuss what you would like to change. Join our community Slack channel, we are a friendly bunch and happy to help you get started :)