Skip to content

Tokyo Drift Detector #40

Tokyo Drift Detector

Tokyo Drift Detector #40

Workflow file for this run

name: Tokyo Drift Detector
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"
jobs:
get-tofu-directories:
outputs:
TFDIRS: ${{ steps.get-tf-dirs.outputs.TFDIRS }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Get list of directories with Tofu
id: get-tf-dirs
run: |
TFDIRS=$(find . -type f -name "*.tf" ! -path "*/modules/*" ! -path "*/gcp/*" -exec dirname {} \; | sort -u)
echo "List of Tofu directories"
echo "$TFDIRS"
# Convert into JSON array
FMT_TFDIRS=$(echo "$TFDIRS" | jq -R -s -c 'split("\n")[:-1]')
echo "TFDIRS=$FMT_TFDIRS" >> $GITHUB_OUTPUT
check-drift:
needs: get-tofu-directories
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
strategy:
matrix:
tf-dir: ${{ fromJSON(needs.get-tofu-directories.outputs.TFDIRS) }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup OpenTofu
uses: opentofu/setup-opentofu@v1
- name: Set up AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_GHA_ROLE }}
aws-region: ap-southeast-1
- name: Check drift in Tofu directories
id: tf-plan
run: |
echo "Running plan in ${{ matrix.tf-dir }}"
cd ${{ matrix.tf-dir }}
export EXITCODE=0
tofu init
tofu plan -detailed-exitcode -no-color -out tfplan || export EXITCODE=$?
echo "EXITCODE=$exitcode" >> $GITHUB_ENV
if [ $exitcode -eq 1 ]; then
echo Tofu Plan Failed!
exit 1
else
exit 0
fi
# Save plan to artifacts
- name: Publish Tofu Plan
uses: actions/upload-artifact@v4
with:
name: tfplan
path: tfplan
# Create string output of Tofu Plan
- name: Create String Output
id: tf-plan-string
run: |
cd ${{ matrix.tf-dir }}
TOFU_PLAN=$(tofu show -no-color tfplan)
delimiter="$(openssl rand -hex 8)"
echo "summary<<${delimiter}" >> $GITHUB_OUTPUT
echo "## Tofu Plan Output" >> $GITHUB_OUTPUT
echo "<details><summary>Click to expand</summary>" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo '```tofu' >> $GITHUB_OUTPUT
echo "$TOFU_PLAN" >> $GITHUB_OUTPUT
echo '```' >> $GITHUB_OUTPUT
echo "</details>" >> $GITHUB_OUTPUT
echo "${delimiter}" >> $GITHUB_OUTPUT
# Publish Terraform Plan as task summary
- name: Publish Terraform Plan to Task Summary
env:
SUMMARY: ${{ steps.tf-plan-string.outputs.summary }}
run: |
echo "$SUMMARY" >> $GITHUB_STEP_SUMMARY
# If changes are detected, create a new issue
- name: Publish Drift Report
if: env.EXITCODE == 2
uses: actions/github-script@v7
env:
SUMMARY: "${{ steps.tf-plan-string.outputs.summary }}"
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const body = `${process.env.SUMMARY}`;
const title = 'Tofu Drift Detected | ${{ matrix.tf-dir }}';
const creator = 'github-actions[bot]'
// Look to see if there is an existing drift issue
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
creator: creator,
title: title
})
if( issues.data.length > 0 ) {
// We assume there shouldn't be more than 1 open issue, since we update any issue we find
const issue = issues.data[0]
if ( issue.body == body ) {
console.log('Drift Detected: Found matching issue with duplicate content')
} else {
console.log('Drift Detected: Found matching issue, updating body')
github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: body
})
}
} else {
console.log('Drift Detected: Creating new issue')
github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: title,
body: body
})
}
# If changes aren't detected, close any open drift issues
- name: Publish Drift Report
if: env.EXITCODE == 0
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const title = 'Tofu Drift Detected | ${{ matrix.tf-dir }}';
const creator = 'github-actions[bot]'
// Look to see if there is an existing drift issue
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
creator: creator,
title: title
})
if( issues.data.length > 0 ) {
const issue = issues.data[0]
github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
state: 'closed'
})
}
# Mark the workflow as failed if drift detected
- name: Error on Failure
if: env.EXITCODE == 2
run: exit 1