From a218acac347d6fc1786c88091db3408f7d03e44a Mon Sep 17 00:00:00 2001 From: Rasmus Wejlgaard Date: Thu, 18 Jun 2026 20:23:35 +0100 Subject: [PATCH] ci: extract shared SOPS/tofu steps into composite actions The SOPS install + version, the decrypt loop, the OpenTofu version, and the Backblaze backend-credential extraction were copy-pasted across terraform.yml (twice), validate-terraform.yml, and _deploy-core.yml. A version bump meant editing the same string in up to four places and was easy to do partially. Pull them into three local composite actions so each is defined once: - setup-tofu (pins OpenTofu version) - sops-decrypt (installs SOPS, decrypts *.enc.* in place) - tofu-backend-creds (exports Backblaze S3 creds to GITHUB_ENV) Behaviour is unchanged; sops-decrypt also matches *.enc.env everywhere (previously only _deploy-core did), which is a no-op in terraform/. --- .github/actions/setup-tofu/action.yml | 15 ++++++ .github/actions/sops-decrypt/action.yml | 31 +++++++++++ .github/actions/tofu-backend-creds/action.yml | 18 +++++++ .github/workflows/_deploy-core.yml | 17 ++---- .github/workflows/terraform.yml | 52 ++++--------------- .github/workflows/validate-terraform.yml | 27 ++-------- 6 files changed, 84 insertions(+), 76 deletions(-) create mode 100644 .github/actions/setup-tofu/action.yml create mode 100644 .github/actions/sops-decrypt/action.yml create mode 100644 .github/actions/tofu-backend-creds/action.yml diff --git a/.github/actions/setup-tofu/action.yml b/.github/actions/setup-tofu/action.yml new file mode 100644 index 0000000..b0ea696 --- /dev/null +++ b/.github/actions/setup-tofu/action.yml @@ -0,0 +1,15 @@ +name: Set up OpenTofu +description: Install a pinned OpenTofu version (single source of truth for the version). + +inputs: + version: + description: OpenTofu version to install + required: false + default: "1.9.0" + +runs: + using: composite + steps: + - uses: opentofu/setup-opentofu@v2 + with: + tofu_version: ${{ inputs.version }} diff --git a/.github/actions/sops-decrypt/action.yml b/.github/actions/sops-decrypt/action.yml new file mode 100644 index 0000000..a3baeaa --- /dev/null +++ b/.github/actions/sops-decrypt/action.yml @@ -0,0 +1,31 @@ +name: SOPS decrypt +description: Install SOPS and decrypt all in-repo *.enc.* files in place (single source of truth for the SOPS version). + +inputs: + age-key: + description: age private key for SOPS decryption (sets SOPS_AGE_KEY) + required: true + sops-version: + description: SOPS version to install + required: false + default: "3.9.4" + +runs: + using: composite + steps: + - name: Install SOPS + shell: bash + run: | + wget -qO /tmp/sops.deb "https://github.com/getsops/sops/releases/download/v${{ inputs.sops-version }}/sops_${{ inputs.sops-version }}_amd64.deb" + sudo dpkg -i /tmp/sops.deb + + - name: Decrypt secrets + shell: bash + env: + SOPS_AGE_KEY: ${{ inputs.age-key }} + run: | + find . -name '*.enc.yml' -o -name '*.enc.yaml' -o -name '*.enc.env' | while read f; do + out="${f/.enc/}" + sops -d "$f" > "$out" + echo "Decrypted: $f -> $out" + done diff --git a/.github/actions/tofu-backend-creds/action.yml b/.github/actions/tofu-backend-creds/action.yml new file mode 100644 index 0000000..df973d0 --- /dev/null +++ b/.github/actions/tofu-backend-creds/action.yml @@ -0,0 +1,18 @@ +name: Set Terraform backend credentials +description: Export the Backblaze S3 backend credentials from a decrypted secrets.yaml into GITHUB_ENV. + +inputs: + working-directory: + description: Directory containing the decrypted secrets.yaml + required: false + default: terraform + +runs: + using: composite + steps: + - name: Set backend credentials + shell: bash + working-directory: ${{ inputs.working-directory }} + run: | + echo "AWS_ACCESS_KEY_ID=$(yq '.backblaze_keyID' secrets.yaml)" >> "$GITHUB_ENV" + echo "AWS_SECRET_ACCESS_KEY=$(yq '.backblaze_applicationKey' secrets.yaml)" >> "$GITHUB_ENV" diff --git a/.github/workflows/_deploy-core.yml b/.github/workflows/_deploy-core.yml index 69df27f..9106c78 100644 --- a/.github/workflows/_deploy-core.yml +++ b/.github/workflows/_deploy-core.yml @@ -62,23 +62,16 @@ jobs: ssh-keyscan -H "$HOST_IP" >> ~/.ssh/known_hosts 2>/dev/null || true fi - - name: Install tools - run: | - pip install ansible - wget -qO /tmp/sops.deb https://github.com/getsops/sops/releases/download/v3.9.4/sops_3.9.4_amd64.deb - sudo dpkg -i /tmp/sops.deb + - name: Install Ansible + run: pip install ansible - name: Install Ansible collections run: ansible-galaxy install -r ansible/requirements.yml - name: Decrypt secrets - env: - SOPS_AGE_KEY: ${{ secrets.AGE_SECRET_KEY }} - run: | - find . -name '*.enc.yml' -o -name '*.enc.yaml' -o -name '*.enc.env' | while read f; do - out="${f/.enc/}" - sops -d "$f" > "$out" - done + uses: ./.github/actions/sops-decrypt + with: + age-key: ${{ secrets.AGE_SECRET_KEY }} - name: Run playbook working-directory: ansible/ diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 1e3071f..af906c8 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -24,31 +24,15 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Install OpenTofu - uses: opentofu/setup-opentofu@v2 - with: - tofu_version: 1.9.0 - - - name: Install SOPS - run: | - wget -qO /tmp/sops.deb https://github.com/getsops/sops/releases/download/v3.9.4/sops_3.9.4_amd64.deb - sudo dpkg -i /tmp/sops.deb + - uses: ./.github/actions/setup-tofu - name: Decrypt secrets - env: - SOPS_AGE_KEY: ${{ secrets.AGE_SECRET_KEY }} - run: | - find . -name '*.enc.yml' -o -name '*.enc.yaml' | while read f; do - out="${f/.enc/}" - sops -d "$f" > "$out" - echo "Decrypted: $f -> $out" - done + uses: ./.github/actions/sops-decrypt + with: + age-key: ${{ secrets.AGE_SECRET_KEY }} - name: Set backend credentials - working-directory: terraform/ - run: | - echo "AWS_ACCESS_KEY_ID=$(yq '.backblaze_keyID' secrets.yaml)" >> "$GITHUB_ENV" - echo "AWS_SECRET_ACCESS_KEY=$(yq '.backblaze_applicationKey' secrets.yaml)" >> "$GITHUB_ENV" + uses: ./.github/actions/tofu-backend-creds - name: tofu init working-directory: terraform/ @@ -75,31 +59,15 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Install OpenTofu - uses: opentofu/setup-opentofu@v2 - with: - tofu_version: 1.9.0 - - - name: Install SOPS - run: | - wget -qO /tmp/sops.deb https://github.com/getsops/sops/releases/download/v3.9.4/sops_3.9.4_amd64.deb - sudo dpkg -i /tmp/sops.deb + - uses: ./.github/actions/setup-tofu - name: Decrypt secrets - env: - SOPS_AGE_KEY: ${{ secrets.AGE_SECRET_KEY }} - run: | - find . -name '*.enc.yml' -o -name '*.enc.yaml' | while read f; do - out="${f/.enc/}" - sops -d "$f" > "$out" - echo "Decrypted: $f -> $out" - done + uses: ./.github/actions/sops-decrypt + with: + age-key: ${{ secrets.AGE_SECRET_KEY }} - name: Set backend credentials - working-directory: terraform/ - run: | - echo "AWS_ACCESS_KEY_ID=$(yq '.backblaze_keyID' secrets.yaml)" >> "$GITHUB_ENV" - echo "AWS_SECRET_ACCESS_KEY=$(yq '.backblaze_applicationKey' secrets.yaml)" >> "$GITHUB_ENV" + uses: ./.github/actions/tofu-backend-creds - name: tofu init working-directory: terraform/ diff --git a/.github/workflows/validate-terraform.yml b/.github/workflows/validate-terraform.yml index bdda9a8..ac46c23 100644 --- a/.github/workflows/validate-terraform.yml +++ b/.github/workflows/validate-terraform.yml @@ -24,10 +24,7 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Install OpenTofu - uses: opentofu/setup-opentofu@v2 - with: - tofu_version: 1.9.0 + - uses: ./.github/actions/setup-tofu # --- Dependabot: secret-free validation ------------------------------- - name: Validate (no secrets) @@ -54,29 +51,15 @@ jobs: tofu validate # --- Human PRs: full plan against real backend ------------------------ - - name: Install SOPS - if: github.actor != 'dependabot[bot]' - run: | - wget -qO /tmp/sops.deb https://github.com/getsops/sops/releases/download/v3.9.4/sops_3.9.4_amd64.deb - sudo dpkg -i /tmp/sops.deb - - name: Decrypt secrets if: github.actor != 'dependabot[bot]' - env: - SOPS_AGE_KEY: ${{ secrets.AGE_SECRET_KEY }} - run: | - find . -name '*.enc.yml' -o -name '*.enc.yaml' | while read f; do - out="${f/.enc/}" - sops -d "$f" > "$out" - echo "Decrypted: $f -> $out" - done + uses: ./.github/actions/sops-decrypt + with: + age-key: ${{ secrets.AGE_SECRET_KEY }} - name: Set backend credentials if: github.actor != 'dependabot[bot]' - working-directory: terraform/ - run: | - echo "AWS_ACCESS_KEY_ID=$(yq '.backblaze_keyID' secrets.yaml)" >> "$GITHUB_ENV" - echo "AWS_SECRET_ACCESS_KEY=$(yq '.backblaze_applicationKey' secrets.yaml)" >> "$GITHUB_ENV" + uses: ./.github/actions/tofu-backend-creds - name: tofu init if: github.actor != 'dependabot[bot]'