diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..5fac912 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,156 @@ +name: CI +on: +# push: +# branches: [main] + pull_request: + types: + - opened + - synchronize + - reopened + - closed +concurrency: + group: ${{ github.workflow}}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} +permissions: + contents: write +jobs: + plan: + name: TF Plan + if: github.event_name == 'pull_request' && github.event.pull_request.merged == false + runs-on: ubuntu-latest + steps: + - name: Dependencies + run: sudo apt-get install -y colorized-logs + - name: Checkout repo + uses: actions/checkout@v3 +# - name: Generate app token +# id: generate-app-token +# uses: tibdex/github-app-token@v1.9.0 +# with: +# app_id: ${{ vars.GH_APP_STEELECO_SYSTEMS_APP_ID }} +# private_key: ${{ secrets.GH_APP_STEELECO_SYSTEMS_PRIVATE_KEY }} + - name: Download and decrypt statefile + env: + #GITHUB_TOKEN: ${{ steps.generate-app-token.outputs.token }} + GITHUB_TOKEN: ${{ github.token }} + TFSTATE_PGP_KEY: ${{ secrets.TFSTATE_PGP_KEY }} + run: | + # step script + set -x + ./scripts/get-state-file.sh + - name: Terraform init + run: terraform init + - name: Terraform plan + run: terraform plan | tee >(ansi2txt > terraform.tfplan.log) + - name: Create release body + run: | + cat \ + <(echo "
Terraform Plan Log") \ + <(echo "") \ + <(echo '```') \ + terraform.tfplan.log \ + <(echo '```') \ + <(echo "
") \ + > release.md + - name: Create or update tag + env: + GITHUB_TOKEN: ${{ github.token }} + run: | + # step script + set -x + + if gh api /repos/:owner/:repo/git/ref/tags/pr/${{ github.event.pull_request.number }}; then + gh api --method PATCH /repos/:owner/:repo/git/refs/tags/pr/${{ github.event.pull_request.number }} \ + -f sha=${{ github.event.pull_request.head.sha }} \ + -F force=true \ + | jq . + else + gh api --method POST /repos/:owner/:repo/git/refs \ + -f ref=refs/tags/pr/${{ github.event.pull_request.number }} \ + -f sha=${{ github.event.pull_request.head.sha }} \ + | jq . + fi + - name: Create release + id: create-release + uses: softprops/action-gh-release@v1 + with: + body_path: release.md + prerelease: true + files: terraform.tfplan.log + tag_name: pr/${{ github.event.pull_request.number }} + name: ${{ github.event.pull_request.title }} (#${{ github.event.pull_request.number }}) + fail_on_unmatched_files: true + target_commitish: ${{ github.event.pull_request.head.sha }} + + apply: + name: TF Apply + if: github.event_name == 'pull_request' && github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: + - name: Dependencies + run: sudo apt-get install -y colorized-logs + - name: Checkout repo + uses: actions/checkout@v3 + - name: Generate app token + id: generate-app-token + uses: tibdex/github-app-token@v1.9.0 + with: + app_id: ${{ vars.GH_APP_STEELECO_SYSTEMS_APP_ID }} + private_key: ${{ secrets.GH_APP_STEELECO_SYSTEMS_PRIVATE_KEY }} + - name: Download and decrypt statefile + env: + GITHUB_TOKEN: ${{ github.token }} + TFSTATE_PGP_KEY: ${{ secrets.TFSTATE_PGP_KEY }} + run: | + # step script + set -x + ./scripts/get-state-file.sh + - name: Terraform init + run: terraform init + - name: Terraform apply + env: + GITHUB_TOKEN: ${{ steps.generate-app-token.outputs.token }} + run: terraform appy -auto-approve | tee >(ansi2txt > terraform.apply.log) + - name: Encrypt statefile + run: | + # step script + set -x + gpg --encrypt --default-recipient "141457414+steeleco-systems[bot]@users.noreply.github.com" \ + --output terraform.tfstate.gpg terraform.tfstate + gpg --encrypt --default-recipient "141457414+steeleco-systems[bot]@users.noreply.github.com" \ + --output terraform.tfstate.backup.gpg terraform.tfstate.backup + - name: Create release body + run: | + cat \ + <(echo "
Terraform Apply Log") \ + <(echo "") \ + <(echo '```') \ + terraform.apply.log \ + <(echo '```') \ + <(echo "
") \ + > release.md + - name: Create or update tag + env: + GITHUB_TOKEN: ${{ github.token }} + run: | + # step script + set -x + + gh api --method PATCH /repos/:owner/:repo/git/refs/tags/pr/${{ github.event.pull_request.number }} \ + -f sha=${{ github.event.pull_request.merge_commit_sha }} \ + -F force=true \ + | jq . + - name: Create release + id: create-release + uses: softprops/action-gh-release@v1 + with: + body_path: release.md + prerelease: false + files: | + terraform.apply.log + terraform.tfstate.gpg + terraform.tfstate.backup.gpg + tag_name: pr/${{ github.event.pull_request.number }} + name: ${{ github.event.pull_request.title }} (#${{ github.event.pull_request.number }}) + fail_on_unmatched_files: true + target_commitish: ${{ github.event.pull_request.merge_commit_sha }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dc813fd --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +terraform.tfstate +terraform.tfstate.backup +terraform.tfplan +terraform.tfplan.log +.terraform.lock.hcl +.terraform +*.gpg diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..f591e7b --- /dev/null +++ b/main.tf @@ -0,0 +1,31 @@ +terraform { + required_providers { + github = { + source = "integrations/github" + version = "~> 5.38" + } + } +} + +# Configure the GitHub Provider +provider "github" { + +# app_auth { +# id = "371766" +# installation_id = "40392571" +# pem_file = file("~/Downloads/steelecosystems.2023-09-24.private-key.pem") +# } + owner = "SteelecoSystems" +} + +resource "github_actions_variable" "test_variable" { + variable_name = "test_variable" + value = "hello world" + repository = "tf-test" +} + +resource "github_actions_secret" "test_secret" { + secret_name = "test_secret" + plaintext_value = "asd" + repository = "tf-test" +} diff --git a/scripts/get-state-file.sh b/scripts/get-state-file.sh new file mode 100755 index 0000000..2324a00 --- /dev/null +++ b/scripts/get-state-file.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +set -eo pipefail +[[ $RUNNER_DEBUG || $DEBUG ]] && set -x + +set +e +state_file_url="$(gh api /repos/:owner/:repo/releases/latest --jq '.assets[] | select(.name == "terraform.tfstate.gpg") | .url')" +rc=$?; set -e + +if [[ $rc != 0 ]]; then + error_message="$(jq -r .message <<< "$state_file_url")" + if [[ $error_message == "Not Found" ]]; then + >&2 echo "No state file found, exiting" + exit 0 + else + >&2 echo "Other error occurred while trying to obtain the state file:" + >&2 echo "$error_message" + exit 1 + fi +fi + +gpg --import <<< "$TFSTATE_PGP_KEY" +gh api -H 'Accept: application/octet-stream' "$state_file_url" | gpg --out terraform.tfstate --decrypt + + diff --git a/scripts/upload-state-file.sh b/scripts/upload-state-file.sh new file mode 100644 index 0000000..b377b92 --- /dev/null +++ b/scripts/upload-state-file.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -eo pipefail +[[ $RUNNER_DEBUG || $DEBUG ]] && set -x + +gpg --encrypt --default-recipient "141457414+steeleco-systems[bot]@users.noreply.github.com" --output terraform.tfstate.gpg terraform.tfstate