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

Configure terraform setup #3

Merged
merged 2 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
30 changes: 30 additions & 0 deletions .github/workflows/preview.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Speculative Run

on:
workflow_dispatch:
inputs:
workspace_transfer_url:
description: "URL from which to download the workspace"
required: true
type: string

jobs:
plan:
name: Plan
runs-on: ubuntu-22.04
env:
TF_HTTP_PASSWORD: ${{ github.token }}
TF_IN_AUTOMATION: "true"
defaults:
run:
working-directory: ./terraform
steps:
- name: Download Workspace
run: |
curl ${{ inputs.workspace_transfer_url }} --fail --silent | tar -xzf -
working-directory: .
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.6.6"
- run: terraform init
- run: terraform plan
175 changes: 175 additions & 0 deletions .github/workflows/terraform.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
name: Terraform

on:
push:
branches: [main]
pull_request:

jobs:
run:
name: Run
runs-on: ubuntu-22.04
permissions:
contents: read
pull-requests: write
checks: write
env:
TF_HTTP_PASSWORD: ${{ github.token }}
TF_IN_AUTOMATION: "true"
defaults:
run:
working-directory: ./terraform
steps:
- name: Checkout
uses: actions/checkout@v3

- uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.6.6"

- run: terraform init

- run: terraform plan -out=tfplan
- run: terraform apply tfplan | tee apply.log
if: ${{ github.event_name == 'push' && github.ref_name == 'main' }}
- 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
run: |
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
- run: terraform show -no-color tfplan > summary.txt

- 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`
)

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",
output: {
title,
summary,
},
});

- name: Show plan on PR
uses: actions/github-script@v7
if: ${{ github.event_name == 'pull_request' }}
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 plan = await fs.readFile('terraform/summary.txt', 'utf-8')

const codefence = "```"
const body = `
🏗️ Terraform Plan
${codefence}
${plan.trim("\n")}
${codefence}`

github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body,
})
11 changes: 11 additions & 0 deletions terraform/backend.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
terraform {
backend "http" {
# see https://tfstate.dev/ for instructions
address = "https://api.tfstate.dev/github/v1"
lock_address = "https://api.tfstate.dev/github/v1/lock"
unlock_address = "https://api.tfstate.dev/github/v1/lock"
lock_method = "PUT"
unlock_method = "DELETE"
username = "ffddorf/supernodes-v2@dev"
}
}
2 changes: 2 additions & 0 deletions terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
resource "null_resource" "test" {
}