Patrick de Ruiter 2a5fb1ebd0
Some checks failed
Code Quality & Security Scan / TFLint (push) Successful in 18s
Code Quality & Security Scan / Terraform Destroy (push) Has been skipped
Code Quality & Security Scan / Tfsec Security Scan (push) Successful in 29s
Code Quality & Security Scan / Checkov Security Scan (push) Successful in 39s
Code Quality & Security Scan / Terraform Validate (push) Successful in 34s
Code Quality & Security Scan / SonarQube Trigger (push) Successful in 37s
Code Quality & Security Scan / Terraform Plan (push) Failing after 32s
Code Quality & Security Scan / Terraform Apply (push) Has been skipped
fix: Add backend configuration to all pipeline terraform init steps
Updated all terraform init commands in the pipeline to include backend configuration:
- terraform-plan job: Added backend-config flags
- terraform-apply job: Added backend-config flags
- terraform-destroy job: Added backend-config flags

Backend Configuration:
- Uses secrets for all values (MINIO_ENDPOINT, MINIO_BUCKET)
- State file key: docker/renovate/terraform.tfstate
- Credentials from AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY env vars
- Region: main
- S3-compatible settings for MinIO

Required Secrets (should already be available):
- MINIO_ACCESS_KEY, MINIO_SECRET_KEY
- MINIO_ENDPOINT, MINIO_BUCKET
- VAULT_ROLE_ID, VAULT_SECRET_ID, VAULT_ADDR
- RENOVATE_ENDPOINT, RENOVATE_TOKEN
- SONARQUBE_HOST, SONARQUBE_TOKEN

Fixes pipeline error: Missing Required Value for bucket, key, and region
2025-11-18 02:57:09 +01:00

340 lines
12 KiB
YAML

on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened]
name: Code Quality & Security Scan
jobs:
tflint:
name: TFLint
runs-on: ubuntu-latest
steps:
- name: Checking out
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup TFLint
uses: terraform-linters/setup-tflint@v4
with:
tflint_version: latest
- name: Initialize TFLint
run: tflint --init
- name: Run TFLint
run: tflint --format compact
tfsec:
name: Tfsec Security Scan
runs-on: ubuntu-latest
needs: tflint
steps:
- name: Checking out
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run Tfsec
uses: aquasecurity/tfsec-action@v1.0.3
with:
format: default
soft_fail: false
checkov:
name: Checkov Security Scan
runs-on: ubuntu-latest
needs: tfsec
steps:
- name: Checking out
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run Checkov
uses: bridgecrewio/checkov-action@v12
with:
directory: .
framework: terraform
output_format: cli
soft_fail: false
terraform-validate:
name: Terraform Validate
runs-on: ubuntu-latest
needs: checkov
steps:
- name: Checking out
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: latest
- name: Terraform Format Check
run: terraform fmt -check -recursive
- name: Terraform Init (validation only)
env:
TF_VAR_role_id: ${{ secrets.VAULT_ROLE_ID }}
TF_VAR_secret_id: ${{ secrets.VAULT_SECRET_ID }}
TF_VAR_renovate_endpoint: "https://gitea.example.com/api/v1/"
TF_VAR_renovate_token: "dummy-token-for-validation"
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
run: terraform init -backend=false
- name: Terraform Validate
env:
TF_VAR_role_id: ${{ secrets.VAULT_ROLE_ID }}
TF_VAR_secret_id: ${{ secrets.VAULT_SECRET_ID }}
TF_VAR_renovate_endpoint: "https://gitea.example.com/api/v1/"
TF_VAR_renovate_token: "dummy-token-for-validation"
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
run: terraform validate
sonarqube:
name: SonarQube Trigger
runs-on: ubuntu-latest
needs: terraform-validate
steps:
- name: Checking out
uses: actions/checkout@v4
with:
# Disabling shallow clone is recommended for improving relevancy of reporting
fetch-depth: 0
- name: SonarQube Scan
uses: sonarsource/sonarqube-scan-action@v6
env:
SONAR_HOST_URL: ${{ secrets.SONARQUBE_HOST }}
SONAR_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
terraform-plan:
name: Terraform Plan
runs-on: ubuntu-latest
needs: sonarqube
steps:
- name: Checking out
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: latest
- name: Terraform Init
env:
AWS_ACCESS_KEY_ID: ${{ secrets.MINIO_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.MINIO_SECRET_KEY }}
TF_VAR_role_id: ${{ secrets.VAULT_ROLE_ID }}
TF_VAR_secret_id: ${{ secrets.VAULT_SECRET_ID }}
TF_VAR_renovate_endpoint: ${{ secrets.RENOVATE_ENDPOINT }}
TF_VAR_renovate_token: ${{ secrets.RENOVATE_TOKEN }}
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
run: |
terraform init -input=false \
-backend-config="endpoints={s3=\"${{ secrets.MINIO_ENDPOINT }}\"}" \
-backend-config="bucket=${{ secrets.MINIO_BUCKET }}" \
-backend-config="key=docker/renovate/terraform.tfstate" \
-backend-config="region=main" \
-backend-config="skip_credentials_validation=true" \
-backend-config="skip_metadata_api_check=true" \
-backend-config="skip_requesting_account_id=true" \
-backend-config="skip_region_validation=true" \
-backend-config="use_path_style=true"
- name: Terraform Plan
env:
AWS_ACCESS_KEY_ID: ${{ secrets.MINIO_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.MINIO_SECRET_KEY }}
TF_VAR_role_id: ${{ secrets.VAULT_ROLE_ID }}
TF_VAR_secret_id: ${{ secrets.VAULT_SECRET_ID }}
TF_VAR_renovate_endpoint: ${{ secrets.RENOVATE_ENDPOINT }}
TF_VAR_renovate_token: ${{ secrets.RENOVATE_TOKEN }}
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
run: |
terraform plan -input=false -out=tfplan
terraform show -no-color tfplan > tfplan.txt
- name: Upload Terraform Plan to MinIO
env:
AWS_ACCESS_KEY_ID: ${{ secrets.MINIO_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.MINIO_SECRET_KEY }}
MINIO_ENDPOINT: ${{ secrets.MINIO_ENDPOINT }}
MINIO_BUCKET: ${{ secrets.MINIO_BUCKET }}
run: |
# Install AWS CLI for S3-compatible operations
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip -q awscliv2.zip
sudo ./aws/install
# Upload plan files to MinIO
PLAN_PATH="terraform-plans/${{ github.repository }}/${{ github.run_number }}"
aws s3 cp tfplan "s3://${MINIO_BUCKET}/${PLAN_PATH}/tfplan" \
--endpoint-url="${MINIO_ENDPOINT}"
aws s3 cp tfplan.txt "s3://${MINIO_BUCKET}/${PLAN_PATH}/tfplan.txt" \
--endpoint-url="${MINIO_ENDPOINT}"
echo "Plan uploaded to: s3://${MINIO_BUCKET}/${PLAN_PATH}/"
terraform-apply:
name: Terraform Apply
runs-on: ubuntu-latest
needs: terraform-plan
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
environment:
name: production
steps:
- name: Checking out
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: latest
- name: Install AWS CLI
run: |
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip -q awscliv2.zip
sudo ./aws/install
- name: Terraform Init
env:
AWS_ACCESS_KEY_ID: ${{ secrets.MINIO_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.MINIO_SECRET_KEY }}
TF_VAR_role_id: ${{ secrets.VAULT_ROLE_ID }}
TF_VAR_secret_id: ${{ secrets.VAULT_SECRET_ID }}
TF_VAR_renovate_endpoint: ${{ secrets.RENOVATE_ENDPOINT }}
TF_VAR_renovate_token: ${{ secrets.RENOVATE_TOKEN }}
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
run: |
terraform init \
-backend-config="endpoints={s3=\"${{ secrets.MINIO_ENDPOINT }}\"}" \
-backend-config="bucket=${{ secrets.MINIO_BUCKET }}" \
-backend-config="key=docker/renovate/terraform.tfstate" \
-backend-config="region=main" \
-backend-config="skip_credentials_validation=true" \
-backend-config="skip_metadata_api_check=true" \
-backend-config="skip_requesting_account_id=true" \
-backend-config="skip_region_validation=true" \
-backend-config="use_path_style=true"
- name: Download Terraform Plan from MinIO
env:
AWS_ACCESS_KEY_ID: ${{ secrets.MINIO_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.MINIO_SECRET_KEY }}
MINIO_ENDPOINT: ${{ secrets.MINIO_ENDPOINT }}
MINIO_BUCKET: ${{ secrets.MINIO_BUCKET }}
run: |
PLAN_PATH="terraform-plans/${{ github.repository }}/${{ github.run_number }}"
aws s3 cp "s3://${MINIO_BUCKET}/${PLAN_PATH}/tfplan" tfplan \
--endpoint-url="${MINIO_ENDPOINT}"
echo "Plan downloaded from: s3://${MINIO_BUCKET}/${PLAN_PATH}/tfplan"
- name: Terraform Apply
env:
AWS_ACCESS_KEY_ID: ${{ secrets.MINIO_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.MINIO_SECRET_KEY }}
TF_VAR_role_id: ${{ secrets.VAULT_ROLE_ID }}
TF_VAR_secret_id: ${{ secrets.VAULT_SECRET_ID }}
TF_VAR_renovate_endpoint: ${{ secrets.RENOVATE_ENDPOINT }}
TF_VAR_renovate_token: ${{ secrets.RENOVATE_TOKEN }}
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
run: terraform apply -input=false -auto-approve tfplan
terraform-destroy:
name: Terraform Destroy
runs-on: ubuntu-latest
if: github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'destroy')
environment:
name: destroy-approval
steps:
- name: Verify Destroy Authorization
run: |
echo "⚠️ CRITICAL: INFRASTRUCTURE DESTRUCTION REQUESTED"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "PR: ${{ github.event.pull_request.html_url }}"
echo "Requested by: ${{ github.actor }}"
echo "Repository: ${{ github.repository }}"
echo "Branch: ${{ github.head_ref }}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "This action will PERMANENTLY DESTROY the Renovate container"
echo "and all associated resources managed by this Terraform configuration."
echo ""
echo "Waiting for manual approval via environment protection rules..."
- name: Checking out
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: latest
- name: Terraform Init (Fresh - No Cache)
env:
AWS_ACCESS_KEY_ID: ${{ secrets.MINIO_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.MINIO_SECRET_KEY }}
TF_VAR_role_id: ${{ secrets.VAULT_ROLE_ID }}
TF_VAR_secret_id: ${{ secrets.VAULT_SECRET_ID }}
TF_VAR_renovate_endpoint: ${{ secrets.RENOVATE_ENDPOINT }}
TF_VAR_renovate_token: ${{ secrets.RENOVATE_TOKEN }}
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
run: |
echo "Performing fresh terraform init (no cache for safety)..."
terraform init \
-backend-config="endpoints={s3=\"${{ secrets.MINIO_ENDPOINT }}\"}" \
-backend-config="bucket=${{ secrets.MINIO_BUCKET }}" \
-backend-config="key=docker/renovate/terraform.tfstate" \
-backend-config="region=main" \
-backend-config="skip_credentials_validation=true" \
-backend-config="skip_metadata_api_check=true" \
-backend-config="skip_requesting_account_id=true" \
-backend-config="skip_region_validation=true" \
-backend-config="use_path_style=true"
- name: Terraform Destroy Plan
env:
AWS_ACCESS_KEY_ID: ${{ secrets.MINIO_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.MINIO_SECRET_KEY }}
TF_VAR_role_id: ${{ secrets.VAULT_ROLE_ID }}
TF_VAR_secret_id: ${{ secrets.VAULT_SECRET_ID }}
TF_VAR_renovate_endpoint: ${{ secrets.RENOVATE_ENDPOINT }}
TF_VAR_renovate_token: ${{ secrets.RENOVATE_TOKEN }}
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
run: |
echo "Generating destroy plan..."
terraform plan -input=false -destroy -out=destroy.tfplan
echo ""
echo "Destroy plan generated. Review the plan above carefully."
- name: Terraform Destroy Execute
env:
AWS_ACCESS_KEY_ID: ${{ secrets.MINIO_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.MINIO_SECRET_KEY }}
TF_VAR_role_id: ${{ secrets.VAULT_ROLE_ID }}
TF_VAR_secret_id: ${{ secrets.VAULT_SECRET_ID }}
TF_VAR_renovate_endpoint: ${{ secrets.RENOVATE_ENDPOINT }}
TF_VAR_renovate_token: ${{ secrets.RENOVATE_TOKEN }}
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
run: |
echo "🔥 DESTROYING INFRASTRUCTURE..."
echo "This cannot be undone!"
echo ""
terraform apply -input=false -auto-approve destroy.tfplan
echo ""
echo "✅ Renovate infrastructure has been destroyed"
echo "State file updated in MinIO"