Update Terraform proxmox to v3.0.1-rc6 #15
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Terraform | |
on: | |
push: | |
branches: [main] | |
pull_request: | |
jobs: | |
run: | |
name: Run | |
runs-on: ubuntu-22.04 | |
strategy: | |
matrix: | |
domain: ["dev"] | |
concurrency: | |
group: terraform-${{ matrix.domain }} | |
cancel-in-progress: false | |
permissions: | |
contents: read | |
pull-requests: write | |
checks: write | |
env: | |
# renovate: datasource=github-releases depName=hashicorp/terraform | |
TERRAFORM_VERSION: "1.9.3" | |
TF_HTTP_ADDRESS: https://ffddorf-terraform-backend.fly.dev/state/supernodes-v2/${{ matrix.domain }} | |
TF_HTTP_LOCK_ADDRESS: https://ffddorf-terraform-backend.fly.dev/state/supernodes-v2/${{ matrix.domain }} | |
TF_HTTP_UNLOCK_ADDRESS: https://ffddorf-terraform-backend.fly.dev/state/supernodes-v2/${{ matrix.domain }} | |
TF_HTTP_PASSWORD: ${{ github.token }} | |
TF_IN_AUTOMATION: "true" | |
TF_CLI_ARGS: "-input=false -var-file=domains/${{ matrix.domain }}.tfvars" | |
NETBOX_API_TOKEN: ${{ secrets.NETBOX_API_TOKEN }} | |
PM_API_TOKEN_ID: ${{ secrets.PM_API_TOKEN_ID }} | |
PM_API_TOKEN_SECRET: ${{ secrets.PM_API_TOKEN_SECRET }} | |
defaults: | |
run: | |
working-directory: ./terraform | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- uses: hashicorp/setup-terraform@v3 | |
with: | |
terraform_version: ${TERRAFORM_VERSION} | |
- run: terraform init | |
- run: terraform plan -out=tfplan | |
- name: terraform apply | |
if: ${{ github.event_name == 'push' && github.ref_name == 'main' }} | |
env: | |
TF_CLI_ARGS: "-input=false" | |
run: | | |
set -o pipefail | |
terraform apply tfplan | tee apply.log | |
- name: Backup state | |
if: ${{ github.event_name == 'push' && github.ref_name == 'main' }} | |
env: | |
AWS_ACCESS_KEY_ID: ${{ secrets.B2_TFBACKUP_KEY_ID }} | |
AWS_SECRET_ACCESS_KEY: ${{ secrets.B2_TFBACKUP_SECRET_KEY }} | |
AWS_DEFAULT_REGION: us-east-1 | |
AWS_ENDPOINT_URL: https://s3.us-east-005.backblazeb2.com | |
S3_BUCKET: terraform-state-backup | |
TF_CLI_ARGS: "" | |
run: | | |
set -e -o pipefail | |
terraform show -json > state.json | |
aws s3 cp state.json s3://${S3_BUCKET}/${{ github.repository }}/$(date +%s).json | |
DELETE_FILES=$(\ | |
aws s3api list-objects-v2 --bucket "${S3_BUCKET}" --prefix "${{ github.repository }}" | \ | |
jq -r '.Contents | map(.Key) | sort | reverse | .[5:] | .[]' \ | |
) | |
for file in ${DELETE_FILES}; do aws s3 rm s3://${S3_BUCKET}/$file; done | |
- run: terraform show -json tfplan > tfplan.json | |
env: | |
TF_CLI_ARGS: "" | |
- run: terraform show -no-color tfplan > summary.txt | |
env: | |
TF_CLI_ARGS: "" | |
- name: Create status check with details | |
uses: actions/github-script@v7 | |
with: | |
github-token: ${{ github.token }} | |
script: | | |
const fs = require('fs').promises | |
const plan = JSON.parse(await fs.readFile('terraform/tfplan.json', 'utf-8')) | |
const humanSummary = await fs.readFile('terraform/summary.txt', 'utf-8') | |
let applyLog; | |
try { | |
applyLog = await fs.readFile('terraform/apply.log', 'utf-8') | |
} catch {} | |
function countActions(plan, type) { | |
return plan.resource_changes.filter(ch => ch.change.actions.includes(type)).length | |
} | |
const createCount = countActions(plan, 'create') | |
const updateCount = countActions(plan, 'update') | |
const deleteCount = countActions(plan, 'delete') | |
const noChanges = createCount == 0 && updateCount == 0 && deleteCount == 0 | |
const title = noChanges | |
? "No changes" | |
: (context.eventName === 'push' | |
? `${createCount} added, ${updateCount} changed, ${deleteCount} destroyed` | |
: `${createCount} to add, ${updateCount} to change, ${deleteCount} to destroy` | |
) | |
await fs.writeFile("terraform/title.txt", title) | |
const codefence = "```" | |
const summary = ` | |
# Terraform Plan | |
${codefence} | |
${humanSummary.trim("\n")} | |
${codefence} | |
${!!applyLog ? ` | |
# Terraform Apply | |
${codefence} | |
${applyLog.replace(/\u001b\[[^m]+m/g, '').trim()} | |
${codefence} | |
` : ""} | |
` | |
const sha = context.eventName === 'pull_request' | |
? context.payload.pull_request.head.sha | |
: context.sha | |
await github.rest.checks.create({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
head_sha: sha, | |
status: 'completed', | |
conclusion: noChanges ? 'neutral' : 'success', | |
name: `${context.eventName === 'push' ? "Apply" : "Plan"} (${{ matrix.domain }})`, | |
output: { | |
title, | |
summary, | |
}, | |
}); | |
- name: Upload summary | |
uses: actions/upload-artifact@v4 | |
with: | |
name: tf-summary-${{ matrix.domain }} | |
path: | | |
terraform/summary.txt | |
terraform/title.txt | |
summary: | |
name: Summary | |
runs-on: ubuntu-22.04 | |
needs: run | |
if: ${{ github.event_name == 'pull_request' }} | |
steps: | |
- name: Download outputs from workspaces | |
uses: actions/download-artifact@v4 | |
with: | |
path: outputs | |
pattern: tf-summary-* | |
- name: Show plan on PR | |
uses: actions/github-script@v7 | |
with: | |
github-token: ${{ github.token }} | |
script: | | |
const { repository: { pullRequest: { comments } } } = await github.graphql(` | |
query($owner:String!, $name:String!, $pr:Int!) { | |
repository(owner:$owner, name:$name) { | |
pullRequest(number:$pr) { | |
comments(last: 10) { | |
nodes { | |
id, | |
minimizedReason | |
author { | |
...on Bot { | |
login | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
`, { | |
owner: context.repo.owner, | |
name: context.repo.repo, | |
pr: context.issue.number, | |
}) | |
const commentsToHide = comments.nodes.filter((comment) => { | |
return !comment.minimizedReason && comment.author.login == "github-actions" | |
}) | |
if (commentsToHide.length > 0) { | |
await github.graphql(` | |
mutation { | |
${commentsToHide.map((c,i) => | |
`c${i}: minimizeComment(input: { subjectId: "${c.id}", classifier: OUTDATED }) { | |
clientMutationId | |
} | |
` | |
).join("")} | |
} | |
`) | |
} | |
const fs = require('fs').promises | |
const summaries = await fs.readdir('outputs'); | |
let body = "#### :building_construction: Terraform Plan"; | |
for (const dir of summaries) { | |
const plan = await fs.readFile(`outputs/${dir}/summary.txt`, 'utf-8') | |
const title = await fs.readFile(`outputs/${dir}/title.txt`, 'utf-8') | |
const domain = dir.slice("tf-summary-".length) | |
const codefence = "```" | |
body += ` | |
<details> | |
<summary>${domain} - ${title}</summary> | |
${codefence} | |
${plan.trim("\n")} | |
${codefence} | |
</details>` | |
} | |
github.rest.issues.createComment({ | |
issue_number: context.issue.number, | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
body, | |
}) |