Skip to content

Commit

Permalink
feat: upgrade infracost to latest version (v0.6.2)
Browse files Browse the repository at this point in the history
Adds support for all arguments that might be useful
  • Loading branch information
alikhajeh1 authored and aliscott committed Oct 10, 2020
1 parent 1775f40 commit df21fe6
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 59 deletions.
8 changes: 4 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ FROM alpine:3.12

# GitHub actions don't support build-args (https://github.community/t/feature-request-build-args-support-in-docker-container-actions/16846/4)
# so using ENV might help people who need to fork/change it
ENV TERRAFORM_VERSION=0.13.3 \
TERRAFORM_BINARY=terraform \
INFRACOST_VERSION=latest
ENV TERRAFORM_VERSION=0.13.4 \
INFRACOST_VERSION=latest \
INFRACOST_SKIP_UPDATE_CHECK=true

RUN apk --update --no-cache add ca-certificates openssl sudo curl git jq && \
wget -O terraform.zip "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip" && \
unzip terraform.zip -d /bin && \
rm -rf terraform.zip /var/cache/apk/*

RUN curl --silent --location https://github.com/infracost/infracost/releases/${INFRACOST_VERSION}/download/infracost-linux-amd64.tar.gz | tar xz -C /tmp
RUN mv /tmp/infracost-linux-amd64 /usr/local/bin/infracost
RUN mv /tmp/infracost-linux-amd64 /bin/infracost

COPY entrypoint.sh /entrypoint.sh

Expand Down
100 changes: 59 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,44 @@
# Infracost GitHub action

This action runs [Infracost](https://infracost.io) on the provided terraform directory in the master branch and the pull request whenever a `.tf` file changes. It automatically adds a pull request comment showing the cost estimate `diff` if a percentage threshold is crossed.
This action runs [Infracost](https://infracost.io) against the master branch and the pull request whenever a Terraform file changes. It automatically adds a pull request comment showing the cost estimate difference (similar to `git diff`) if a percentage threshold is crossed.

<img src="screenshot.png" width=557 alt="Example screenshot" />

## Inputs

### `terraform_dir`
### `tfjson`

**Required** Path of the repo's terraform directory.
**Optional** Path to Terraform plan JSON file.

### `tfplan`

**Optional** Path to Terraform plan file relative to 'tfdir'. Requires 'tfdir' to be set.

### `tfdir`

**Optional** Path to the Terraform code directory (default is current working directory).

### `tfflags`

**Optional** Flags to pass to the 'terraform plan' command.

### `percentage_threshold`

**Optional** The absolute percentage threshold that triggers a pull request comment with the diff. Defaults to 0, meaning that a comment is posted if the cost estimate changes. For example, set to 5 to post a comment if the cost estimate changes by plus or minus 5%.

### `pricing_api_endpoint`

**Optional** Specify an alternate price list API URL (default is https://pricing.api.infracost.io).

## Environment variables

The AWS secrets mentioned below are used by terraform init and plan commands. As mentioned in the [Infracost FAQ](https://www.infracost.io/docs/faq) you can run `infracost` in your terraform directories without worrying about security or privacy issues as no cloud credentials, secrets, tags or Terraform resource identifiers are sent to Infracost's cloud pricing API. Infracost does not make any changes to your Terraform state or cloud resources.

Standard Terraform env vars can also be added if required, e.g. `TF_CLI_ARGS`.

### `INFRACOST_API_KEY`

**Required if the Infracost hosted pricing API is used (default behavior)** To get an API key [download Infracost](https://www.infracost.io/docs/#installation) and run `infracost register`.
**Required** To get an API key [download Infracost](https://www.infracost.io/docs/#installation) and run `infracost register`.

### `AWS_ACCESS_KEY_ID`

Expand All @@ -34,8 +52,6 @@ The AWS secrets mentioned below are used by terraform init and plan commands. As

**Required** GitHub token used to post comments, should be set to `${{ secrets.GITHUB_TOKEN }}` to use the default GitHub token available to actions.

Standard Terraform env vars can also be added if required, e.g. `TF_CLI_ARGS`.

## Outputs

### `master_monthly_cost`
Expand All @@ -48,41 +64,43 @@ The pull request's monthly cost estimate.

## Usage

1. [Add repo secrets](https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets-for-a-repository) for `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` to your GitHub repo. As a security precaution, read-only AWS IAM creds can be used.

2. Create a new file in `.github/workflows/infracost.yml` in your repo with the following content. You must set the `terraform_dir` value, everything else should work out of the box.
```
on:
push:
paths:
- '**.tf'
- '**.tfvars'
jobs:
infracost:
runs-on: ubuntu-latest
name: Show infracost diff
steps:
- name: Checkout master branch
uses: actions/checkout@v2
with:
ref: master
path: master
- name: Checkout pull request branch
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
path: pull_request
- name: Run infracost diff
uses: infracost/[email protected]
env:
INFRACOST_API_KEY: ${{ secrets.INFRACOST_API_KEY }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
##### You should only need to modify the following #####
terraform_dir: PATH/TO/MY/TERRAFORM
```
1. [Add repo secrets](https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets-for-a-repository) for `INFRACOST_API_KEY`, `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` to your GitHub repo.

2. Create a new file in `.github/workflows/infracost.yml` in your repo with the following content. Use the Inputs and Environment Variables section above to decide which `env` and `with` options work for your Terraform setup. The following example uses `tfdir` and `tfflags` so it would be the equivalent of running `terraform -var-file=myvars.tfvars` inside the directory with the terraform code.

```
on:
push:
paths:
- '**.tf'
- '**.tfvars'
- '**.tfvars.json'
jobs:
infracost:
runs-on: ubuntu-latest
name: Show infracost diff
steps:
- name: Checkout master branch
uses: actions/checkout@v2
with:
ref: master
path: master
- name: Checkout pull request branch
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
path: pull_request
- name: Run infracost diff
uses: infracost/infracost-gh-action@master
env:
INFRACOST_API_KEY: ${{ secrets.INFRACOST_API_KEY }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tfdir: PATH/TO/CODE
tfflags: -var-file=myvars.tfvars
```

## Contributing

Expand Down
24 changes: 20 additions & 4 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,25 @@ branding:
icon: trending-up
color: yellow
inputs:
terraform_dir:
description: Path of the repo's terraform directory.
required: true
tfjson:
description: Path to Terraform plan JSON file.
required: false
tfplan:
description: Path to Terraform plan file relative to 'tfdir'. Requires 'tfdir' to be set.
required: false
tfdir:
description: Path to the Terraform code directory (default is current working directory).
required: false
tfflags:
description: Flags to pass to the 'terraform plan' command.
required: false
percentage_threshold:
description: The absolute percentage threshold that triggers a pull request comment with the diff. Defaults to 0, meaning that a comment is posted if the cost estimate changes. For example, set to 5 to post a comment if the cost estimate changes by plus or minus 5%.
required: false
default: 0
pricing_api_endpoint:
description: Specify an alternate price list API URL (default is https://pricing.api.infracost.io).
required: false
outputs:
master_monthly_cost:
description: The master branch's monthly cost estimate.
Expand All @@ -21,5 +33,9 @@ runs:
using: docker
image: Dockerfile
args:
- ${{ inputs.terraform_dir }}
- ${{ inputs.tfjson }}
- ${{ inputs.tfplan }}
- ${{ inputs.tfdir }}
- ${{ inputs.tfflags }}
- ${{ inputs.percentage_threshold }}
- ${{ inputs.pricing_api_endpoint }}
49 changes: 39 additions & 10 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,21 +1,50 @@
#!/bin/sh -l
#!/bin/sh -le

terraform_dir=$1
percentage_threshold=$2
echo "Using terraform_dir=$terraform_dir and percentage_threshold=$percentage_threshold"
tfjson=$1
tfplan=$2
tfdir=$3
tfflags=$4
percentage_threshold=$5
pricing_api_endpoint=$6

echo "Running infracost on master branch..."
master_output=$(infracost --no-color --log-level warn --tfdir /github/workspace/master/$terraform_dir)
echo "$master_output"
save_infracost_cmd () {
local infracost_cmd="infracost --no-color --log-level warn"
if [ ! -z "$tfjson" ]; then
infracost_cmd="$infracost_cmd --tfjson $1/$tfjson"
fi
if [ ! -z "$tfplan" ]; then
infracost_cmd="$infracost_cmd --tfplan $1/$tfplan"
fi
if [ ! -z "$tfdir" ]; then
infracost_cmd="$infracost_cmd --tfdir $1/$tfdir"
fi
if [ ! -z "$tfflags" ]; then
infracost_cmd="$infracost_cmd --tfflags \"$tfflags\""
fi
if [ ! -z "$pricing_api_endpoint" ]; then
infracost_cmd="$infracost_cmd --pricing_api_endpoint $pricing_api_endpoint"
fi
echo "$infracost_cmd" > $1/infracost_cmd
}

dir="/github/workspace/master"
save_infracost_cmd $dir
echo "Running infracost on master branch using:"
echo " $ $(cat $dir/infracost_cmd)"
master_output=$(cat $dir/infracost_cmd | sh)
echo "$master_output" > master_infracost.txt
master_monthly_cost=$(cat master_infracost.txt | awk '/OVERALL TOTAL/ { print $NF }')
echo " master_monthly_cost=$master_monthly_cost"
echo "::set-output name=master_monthly_cost::$master_monthly_cost"

echo "Running infracost on pull_request..."
pull_request_output=$(infracost --no-color --log-level warn --tfdir /github/workspace/pull_request/$terraform_dir)
echo "$pull_request_output"
dir="/github/workspace/pull_request"
save_infracost_cmd $dir
echo "Running infracost on pull request using:"
echo " $ $(cat $dir/infracost_cmd)"
pull_request_output=$(cat $dir/infracost_cmd | sh)
echo "$pull_request_output" > pull_request_infracost.txt
pull_request_monthly_cost=$(cat pull_request_infracost.txt | awk '/OVERALL TOTAL/ { print $NF }')
echo " pull_request_monthly_cost=$pull_request_monthly_cost"
echo "::set-output name=pull_request_monthly_cost::$pull_request_monthly_cost"

percent_diff=$(echo "scale=4; $pull_request_monthly_cost / $master_monthly_cost * 100 - 100" | bc)
Expand Down

0 comments on commit df21fe6

Please sign in to comment.