Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/andrews actions #67

Open
wants to merge 41 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
dd4af40
Adding github-download-release composite action.
andrewhaller Dec 1, 2022
c3fc59a
Adding discover-changed.
andrewhaller Dec 1, 2022
d27f23e
Adding terraform-compliance-aws.
andrewhaller Dec 1, 2022
231ffbc
Adding terragrunt-setup.
andrewhaller Dec 1, 2022
2c44c6b
Adding terragrunt-run-all.
andrewhaller Dec 1, 2022
955708f
Adding terragrunt-run-all file contents
andrewhaller Dec 1, 2022
3217f61
Adding aws-account-number.
andrewhaller Dec 1, 2022
5e2e781
Implementing some suggested changes.
andrewhaller Dec 1, 2022
bffe4ab
Commenting out token input to test passing env from parent.
andrewhaller Dec 1, 2022
a7fbc40
Implementing more generic terragrunt path input.
andrewhaller Dec 1, 2022
fc1f7d5
Using curl to download asset, instead of gh cli.
andrewhaller Dec 2, 2022
307a950
Changing output name.
andrewhaller Dec 2, 2022
a2ecc8f
Using GITHUB_API_URL.
andrewhaller Dec 6, 2022
2219fdd
Updating directory checks in terragrunt-setup action.
andrewhaller Dec 7, 2022
b2a032d
Checking for empty input in terragrunt-setup.
andrewhaller Dec 7, 2022
d1e7cdb
Using token input.
andrewhaller Dec 7, 2022
58b6219
Removing terragrunt-run-all.
andrewhaller Dec 8, 2022
dd1f4a6
Changing output name.
andrewhaller Dec 8, 2022
0763bf1
Updating description.
andrewhaller Dec 9, 2022
9b6abaa
Adding discover-filename.
andrewhaller Dec 9, 2022
6843b21
Updating terraform-compliance-aws.
andrewhaller Dec 9, 2022
a057622
Changed bash var name for consistency.
andrewhaller Dec 9, 2022
679681a
Defining referenced var.
andrewhaller Dec 9, 2022
fd8b982
Wrapping printf array value in quotes.
andrewhaller Dec 9, 2022
f27b4a1
Wrapping printf array value in quotes.
andrewhaller Dec 9, 2022
ffa9141
Adding git-config-pat.
andrewhaller Dec 9, 2022
7d2808d
Terraform compliance docker.
andrewhaller Dec 9, 2022
39a2bbc
Removing aws-account-number.
andrewhaller Dec 9, 2022
15d2084
Renaming terraform-compliance-aws to terraform-compliance-terragrunt.
andrewhaller Dec 9, 2022
adaf88d
Adding entrypoint contents.
andrewhaller Dec 9, 2022
a686e09
Fixed RANDOM issue.
andrewhaller Dec 9, 2022
f04c0b3
Updating default input.
andrewhaller Dec 9, 2022
d214063
Updating default input.
andrewhaller Dec 10, 2022
54409b0
Checking if file exists.
andrewhaller Dec 10, 2022
22b9ecd
Using mv instead of cp for performance.
andrewhaller Dec 10, 2022
723049f
Updating description.
andrewhaller Dec 10, 2022
c9936a8
Adding composite version of action.
andrewhaller Dec 10, 2022
1a50998
Action updates.
andrewhaller Dec 13, 2022
6bd29a3
Use openssl rand to get replacement key.
andrewhaller Dec 13, 2022
2ab8bd3
Updating actions.
andrewhaller Jan 6, 2023
f649fdd
Referencing action from branch instead of local.
andrewhaller Jan 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions aws-account-number/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: AWS Account Number
description: Retrieves an aws account number from a json file
inputs:
accounts-file:
description: A json file with the aws accounts
required: true
account-name:
description: The name of the specific account to use
required: true
account-name-label:
description: "The key name for the account name"
required: false
default: name
account-id-label:
description: "The key name for the account id"
required: false
default: account
outputs:
account-number:
description: A list of environments that will have plan / apply executed on. This will be a JSON formatted array.
value: ${{ steps.account-number.outputs.number }}
runs:
using: composite
steps:
- name: Get AWS Account Number
shell: bash
id: account-number
run: |
output="$(cat ${{ inputs.accounts-file }} | jq -rc '.[] | select(.${{ inputs.account-name-label }} == "${{ inputs.account-name }}") | .${{ inputs.account-id-label }}')"
echo "number=$output"
echo "number=$output" >> $GITHUB_OUTPUT
38 changes: 38 additions & 0 deletions discover-changed/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Discover Changed Targets
description: Discovers a list of targets to execute plan/apply on
inputs:
targets:
description: A list of target folders to check when determining what to run plan/apply on. This should be a newline-delimited string of targets.
required: true
outputs:
changed-targets:
description: A list of targets that will have plan / apply executed on. This will be a JSON formatted array.
value: ${{ steps.set-matrix.outputs.matrix }}
runs:
using: composite
steps:
- name: Get Changed Files
id: files
uses: tj-actions/changed-files@v34
with:
files: ${{ inputs.targets }}

# given a list of files, output all of the targets that we need to plan against as JSON
# example output: ["liatrio-sandbox", "liatrio-non-prod"]
- name: List Changed Files
id: set-matrix
shell: bash
run: |
envs=()

files="${{ steps.files.outputs.all_modified_files }}"

if [ ! -z "$files" ]; then
for file in $files[@]; do
envs+=($(echo $file | cut -d'/' -f2))
done
fi

output="$(echo "${envs[@]}" | tr ' ' '\n' | sort -u | xargs echo -n | jq -R -s -c 'split(" ")')"
echo "matrix=${output}"
echo "matrix=${output}" >> $GITHUB_OUTPUT
83 changes: 83 additions & 0 deletions github-download-release/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Github Download Release
description: Downloads the specified release using curl
inputs:
owner:
description: The repo owner
required: true
repo:
description: The repo name
required: true
release:
description: The release tag or number
required: true
format-ext:
description: The type of archive
required: false
default: linux_amd64.tar.gz
file:
description: The explicit filename to use ... format-ext will be ignored.
required: false
outputs:
filename:
description: The name of the downloaded tarball
value: ${{ steps.download-asset.outputs.filename }}
runs:
using: composite
steps:

- name: CURL Download Asset
shell: bash
id: download-asset
env:
GITHUB_REPO: ${{ inputs.repo }}
GITHUB_REPO_OWNER: ${{ inputs.owner }}
RELEASE_NAME: ${{ inputs.release }}
DOWNLOAD_FORMAT_EXT: ${{ inputs.format-ext }}
FILE: ${{ inputs.file }}
run: |
function gh_curl_releases() {
local base_url="https://${GITHUB_API_URL}"
curl -H "Authorization: token ${GITHUB_TOKEN}" -H "Accept: application/vnd.github.v3.raw" -o releases.tmp.json ${base_url}$@
}

function gh_curl_asset() {
local base_url="https://${GITHUB_TOKEN}:@${GITHUB_API_URL}"
curl -sL -H "Authorization: token ${GITHUB_TOKEN}" -H "Accept: application/octet-stream" ${base_url}$@
}

export RELEASE_TAG=$(echo "${RELEASE_NAME}" | sed s/^v//g)
export REPO="${GITHUB_REPO_OWNER}/${GITHUB_REPO}"
export FILE_DEFAULT="${GITHUB_REPO}_${RELEASE_TAG}_${DOWNLOAD_FORMAT_EXT}"
[ -z "$FILE" -o "${FILE}x" = "x" ] && export FILE="$FILE_DEFAULT"

if [ "$RELEASE_NAME" = "latest" ]; then
# Github should return the latest release first.
JQ_PARSER_ASSET_ID=".[0].assets | map(select(.name == \"$FILE\"))[0].id"
else
JQ_PARSER_ASSET_ID=". | map(select(.tag_name == \"$RELEASE_NAME\"))[0].assets | map(select(.name == \"$FILE\"))[0].id"
fi

printf "Getting asset id from '%s' ...\n" "https://${GITHUB_API_URL}/repos/${REPO}/releases"
gh_curl_releases "/repos/${REPO}/releases"
ASSET_ID=$(cat releases.tmp.json | jq "$JQ_PARSER_ASSET_ID")
if [ -z "$ASSET_ID" -o "$ASSET_ID" = "null" ]; then
echo "ERROR: version not found $RELEASE_NAME" >&2
exit 1
fi

printf "Getting asset '%s' ...\n" "$ASSET_ID"
URL_BASE_PATH="/repos/${REPO}/releases"
gh_curl_asset "/repos/${REPO}/releases/assets/${ASSET_ID}" > $FILE

ls -lah $FILE

echo "filename=${FILE}"
echo "filename=${FILE}" >> $GITHUB_OUTPUT

ASSET_URL="https://${GITHUB_API_URL}/repos/${REPO}/releases/assets/${ASSET_ID}"
echo "asset=${ASSET_URL}"
echo "asset=${ASSET_URL}" >> $GITHUB_OUTPUT

WEB_URL="https://github.com/${REPO}/releases/download/${RELEASE_NAME}/${FILE}"
echo "web=${WEB_URL}"
echo "web=${WEB_URL}" >> $GITHUB_OUTPUT
55 changes: 55 additions & 0 deletions terraform-compliance-aws/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: AWS Terraform Compliance
description: Checks terraform complicance with aws
inputs:
target-folder:
description: The target folder
required: true
subfolders:
description: A space delimited list of sub-folders with terragrunt.hcl files
required: true
iam-role:
description: The iam role to assume
required: true
runs:
using: composite
steps:
- name: List Compliance folder
shell: bash
run: |
ls -la

- name: Terraform Compliance setup
shell: bash
working-directory: ${{ inputs.target-folder }}
env:
SUBFOLDERS: ${{ inputs.subfolders }}
TERRAGRUNT_IAM_ROLE: ${{ inputs.iam-role }}
run: |
for i in $SUBFOLDERS
do
cd $i/
terragrunt plan -lock=false --out plan.out
terragrunt show -json plan.out > plan.out.json
cd ..
done

- name: Terraform Compliance
shell: bash
working-directory: ${{ inputs.target-folder }}
env:
TARGET_FOLDER: ${{ inputs.target-folder }}
SUBFOLDERS: ${{ inputs.subfolders }}
run: |
for i in $SUBFOLDERS
do
ii="${TARGET_FOLDER}/${i}"
echo "##################################################################################################################"
echo "TERRAFORM COMPLIANCE PATH ${ii}"
echo "##################################################################################################################"
cd $i/
terraform-compliance -n -p plan.out.json -f git:https://github.com/terraform-compliance/user-friendly-features.git
echo "##################################################################################################################"
echo "\n"
rm plan.out.json
cd ..
done
30 changes: 30 additions & 0 deletions terragrunt-run-all/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Terragrunt Run All
description: Terragrunt run-all
inputs:
folder:
description: The target folder
required: true
iam-role:
description: The iam role to assume
required: true
terragrunt-bin-path:
description: The terragrunt bin path
required: false
default: ./terragrunt
run-all-action:
description: The terragrunt command args
required: true
additional-options-args:
description: Additional terragrunt option args
required: false

runs:
using: composite
steps:

- name: Terrgrunt Apply
shell: bash
env:
TERRAGRUNT_IAM_ROLE: ${{ inputs.iam-role }}
run: |
${{ inputs.terragrunt-bin-path }} run-all ${{ inputs.run-all-action }} --terragrunt-non-interactive --terragrunt-working-dir ${{ inputs.folder }} ${{ inputs.additional-options-args }}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this action is wrapping a single run step, does it still make sense to have it as a separate action? Is it likely that this action will do other things before the run-all?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you meant there would be some additional parameters between ${{ inputs.terragrunt-bin-path }} and "run-all"? Or that there might be an additional step before "terragrunt run-all"? If it's the latter, my thinking with this action is only used to run the terragrunt plan command, and abstract away the nuances for doing that

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The more I think about it, terragrunt run-all commands can get too nuanced to handle with an overly simple action such as this, so I think I'm going to remove it from this pr.

60 changes: 60 additions & 0 deletions terragrunt-setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Terragrunt Setup
description: Checks terraform complicance with aws
inputs:
terragrunt-version:
description: The terragrunt version to use
required: false
default: 'v0.31.1'
terragrunt-bin-name:
description: The name of the executable
required: false
default: terragrunt
terragrunt-bin-dir:
description: The bin location
required: false
default: ""
format-ext:
description: The type of archive
required: false
default: linux_amd64
outputs:
terragrunt-bin-path:
description: The path of the downloaded terragrunt bin
value: ${{ steps.tg-setup.outputs.tgpath }}
runs:
using: composite
steps:

- name: Terrgrunt Setup
shell: bash
id: tg-setup
env:
TERRAGRUNT_VERSION: ${{ inputs.terragrunt-version }}
TERRAGRUNT_BIN_NAME: ${{ inputs.terragrunt-bin-name }}
run: |
[ -z "${{ inputs.terragrunt-bin-dir }}" -o "${{ inputs.terragrunt-bin-dir }}x" = "x" ] && TERRAGRUNT_BIN_DIR=$(realpath "./") || export TERRAGRUNT_BIN_DIR=$(realpath "${{ inputs.terragrunt-bin-dir }}")
export DOWNLOAD_URL="https://github.com/gruntwork-io/terragrunt/releases/download/${TERRAGRUNT_VERSION}/terragrunt_${{ inputs.format-ext }}"
tgpath=$(realpath "${TERRAGRUNT_BIN_NAME}")
printf "Downloading '%s' ...\n" "${DOWNLOAD_URL}"
curl -f -Lo "${TERRAGRUNT_BIN_NAME}" "${DOWNLOAD_URL}"
[ -f "${TERRAGRUNT_BIN_NAME}" ] || { printf "Downloaded file '%s' not found. Exiting ...\n" "${TERRAGRUNT_BIN_NAME}" >&2 && exit 1; }
# TODO
# Verify checksum of download
chmod +x "${TERRAGRUNT_BIN_NAME}"
if [ -n "${{ inputs.terragrunt-bin-dir }}" -a "${{ inputs.terragrunt-bin-dir }}x" != "x" ]; then
if [ ! -d "${{ inputs.terragrunt-bin-dir }}" ]; then
printf "Creating directory '%s' ...\n" "${{ inputs.terragrunt-bin-dir }}"
mkdir -p "${{ inputs.terragrunt-bin-dir }}" || { printf "Unabled to create '%s'. Exiting ...\n" "${{ inputs.terragrunt-bin-dir }}" >&2 && exit 1; }
fi
export TERRAGRUNT_BIN_DIR=$(realpath "${{ inputs.terragrunt-bin-dir }}")
tgpath="${TERRAGRUNT_BIN_DIR}/${TERRAGRUNT_BIN_NAME}"
if [ "$(realpath ${TERRAGRUNT_BIN_NAME})" != "$tgpath" ]; then
mv "${TERRAGRUNT_BIN_NAME}" "${TERRAGRUNT_BIN_DIR}/"
printf "Moving '%s' to '%s' ...\n" "$(realpath ${TERRAGRUNT_BIN_NAME})" "${TERRAGRUNT_BIN_DIR}/${TERRAGRUNT_BIN_NAME}"
fi
fi
[ -f "$tgpath" ] || { printf "Terragrunt path '%s' not found. Exiting ...\n" "${tgpath}" >&2 && exit 1; }

output=$(realpath "$tgpath")
echo "terragrunt-bin-path: ${output}"
echo "tgpath=${output}" >> $GITHUB_OUTPUT