From 8710ca78ab7dcfaf4bcea0813239190e2b763d93 Mon Sep 17 00:00:00 2001 From: cloudneutral Date: Tue, 9 Dec 2025 12:03:53 +0800 Subject: [PATCH] Add Vultr Terraform workflow equivalents --- ...ard-iac-pipeline-vultr-account-matrix.yaml | 62 ++++++++ ...d-iac-pipeline-vultr-global-bootstrap.yaml | 144 ++++++++++++++++++ ...ine-vultr-global-landingzone-baseline.yaml | 57 +++++++ ...d-iac-pipeline-vultr-resources-matrix.yaml | 63 ++++++++ 4 files changed, 326 insertions(+) create mode 100644 .github/workflows/terraform-standard-iac-pipeline-vultr-account-matrix.yaml create mode 100644 .github/workflows/terraform-standard-iac-pipeline-vultr-global-bootstrap.yaml create mode 100644 .github/workflows/terraform-standard-iac-pipeline-vultr-global-landingzone-baseline.yaml create mode 100644 .github/workflows/terraform-standard-iac-pipeline-vultr-resources-matrix.yaml diff --git a/.github/workflows/terraform-standard-iac-pipeline-vultr-account-matrix.yaml b/.github/workflows/terraform-standard-iac-pipeline-vultr-account-matrix.yaml new file mode 100644 index 00000000..c41f133b --- /dev/null +++ b/.github/workflows/terraform-standard-iac-pipeline-vultr-account-matrix.yaml @@ -0,0 +1,62 @@ +name: Terraform Standard - IAC Pipeline (Vultr Account/VPC Matrix) + +on: + push: + paths: + - 'iac-template/terraform-hcl-standard/vultr-vps/modules/vpc/**' + - 'iac-template/terraform-hcl-standard/vultr-vps/modules/iam/**' + - 'iac-template/terraform-hcl-standard/vultr-vps/envs/dev/**' + - '.github/workflows/terraform-standard-iac-pipeline-vultr-account-matrix.yaml' + workflow_dispatch: + inputs: + dry_run: + type: choice + options: ['true', 'false'] + default: 'true' + +env: + BASE_DIR: iac-template/terraform-hcl-standard/vultr-vps/envs + DRY_RUN: ${{ github.event.inputs.dry_run || 'true' }} + +jobs: + terraform: + name: "${{ matrix.env }} :: pipeline (dry_run=${{ inputs.dry_run }})" + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + env: + - dev + + steps: + - uses: actions/checkout@v4 + + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.9.5 + + - uses: terraform-linters/setup-tflint@v4 + with: + tflint_version: v0.51.0 + + - name: Export Vultr credentials + run: echo "TF_VAR_vultr_api_key=${{ secrets.VULTR_API_KEY }}" >> "$GITHUB_ENV" + + - name: Init + run: terraform -chdir=${{ env.BASE_DIR }}/${{ matrix.env }} init -upgrade + + - name: Plan + run: terraform -chdir=${{ env.BASE_DIR }}/${{ matrix.env }} plan + + - name: Apply + if: ${{ env.DRY_RUN == 'false' }} + run: terraform -chdir=${{ env.BASE_DIR }}/${{ matrix.env }} apply -auto-approve + + - name: Skip Apply (dry-run) + if: ${{ env.DRY_RUN == 'true' }} + run: echo "Dry run enabled → skip apply step." + + - name: Output + if: ${{ env.DRY_RUN == 'false' }} + run: terraform -chdir=${{ env.BASE_DIR }}/${{ matrix.env }} output -json diff --git a/.github/workflows/terraform-standard-iac-pipeline-vultr-global-bootstrap.yaml b/.github/workflows/terraform-standard-iac-pipeline-vultr-global-bootstrap.yaml new file mode 100644 index 00000000..21d5bd89 --- /dev/null +++ b/.github/workflows/terraform-standard-iac-pipeline-vultr-global-bootstrap.yaml @@ -0,0 +1,144 @@ +name: Terraform Standard - Vultr Account Bootstrap + +concurrency: + group: terraform-vultr-bootstrap-${{ github.ref }} + cancel-in-progress: false + +on: + push: + paths: + - 'iac-template/terraform-hcl-standard/vultr-vps/bootstrap-object-storage/**' + - 'iac-template/terraform-hcl-standard/vultr-vps/bootstrap-iam/**' + - '.github/workflows/terraform-standard-iac-pipeline-vultr-global-bootstrap.yaml' + workflow_dispatch: + inputs: + deploy_action: + type: choice + options: [plan, apply, destroy] + default: plan + +env: + TF_WORKDIR: iac-template/terraform-hcl-standard/vultr-vps + DEPLOY_ACTION: ${{ github.event.inputs.deploy_action || 'plan' }} + +jobs: + bootstrap: + name: "Bootstrap Vultr state backends & identity" + runs-on: ubuntu-latest + + strategy: + matrix: + target: [bootstrap-object-storage, bootstrap-iam] + + steps: + - uses: actions/checkout@v4 + + - name: Document Bootstrap Scope + run: | + cat <<'SUMMARY' >> "$GITHUB_STEP_SUMMARY" + ## Vultr bootstrap scope + - Object Storage: create S3-compatible bucket + API keys for Terraform state + - IAM: create limited-access user and upload SSH public key + + Variables such as bucket name, region and API keys are sourced from GitHub secrets. + SUMMARY + + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.9.5 + + - name: Export shared credentials + run: echo "TF_VAR_vultr_api_key=${{ secrets.VULTR_API_KEY }}" >> "$GITHUB_ENV" + + - name: Init + working-directory: ${{ env.TF_WORKDIR }}/${{ matrix.target }} + env: + TF_VAR_region: ${{ secrets.VULTR_REGION }} + TF_VAR_cluster_id: ${{ secrets.VULTR_OBJECT_STORAGE_CLUSTER_ID }} + TF_VAR_bucket: ${{ secrets.VULTR_STATE_BUCKET }} + TF_VAR_seed_secret: ${{ secrets.VULTR_STATE_SEED_SECRET }} + TF_VAR_user_email: ${{ secrets.VULTR_BOOTSTRAP_USER_EMAIL }} + TF_VAR_user_password: ${{ secrets.VULTR_BOOTSTRAP_USER_PASSWORD }} + TF_VAR_public_key: ${{ secrets.VULTR_BOOTSTRAP_PUBLIC_KEY }} + run: terraform init -upgrade + + - name: Plan + if: env.DEPLOY_ACTION == 'plan' + working-directory: ${{ env.TF_WORKDIR }}/${{ matrix.target }} + env: + TF_VAR_region: ${{ secrets.VULTR_REGION }} + TF_VAR_cluster_id: ${{ secrets.VULTR_OBJECT_STORAGE_CLUSTER_ID }} + TF_VAR_bucket: ${{ secrets.VULTR_STATE_BUCKET }} + TF_VAR_seed_secret: ${{ secrets.VULTR_STATE_SEED_SECRET }} + TF_VAR_user_email: ${{ secrets.VULTR_BOOTSTRAP_USER_EMAIL }} + TF_VAR_user_password: ${{ secrets.VULTR_BOOTSTRAP_USER_PASSWORD }} + TF_VAR_public_key: ${{ secrets.VULTR_BOOTSTRAP_PUBLIC_KEY }} + run: terraform plan + + - name: Apply + if: env.DEPLOY_ACTION == 'apply' + working-directory: ${{ env.TF_WORKDIR }}/${{ matrix.target }} + env: + TF_VAR_region: ${{ secrets.VULTR_REGION }} + TF_VAR_cluster_id: ${{ secrets.VULTR_OBJECT_STORAGE_CLUSTER_ID }} + TF_VAR_bucket: ${{ secrets.VULTR_STATE_BUCKET }} + TF_VAR_seed_secret: ${{ secrets.VULTR_STATE_SEED_SECRET }} + TF_VAR_user_email: ${{ secrets.VULTR_BOOTSTRAP_USER_EMAIL }} + TF_VAR_user_password: ${{ secrets.VULTR_BOOTSTRAP_USER_PASSWORD }} + TF_VAR_public_key: ${{ secrets.VULTR_BOOTSTRAP_PUBLIC_KEY }} + run: terraform apply -auto-approve + + - name: Destroy + if: env.DEPLOY_ACTION == 'destroy' + working-directory: ${{ env.TF_WORKDIR }}/${{ matrix.target }} + env: + TF_VAR_region: ${{ secrets.VULTR_REGION }} + TF_VAR_cluster_id: ${{ secrets.VULTR_OBJECT_STORAGE_CLUSTER_ID }} + TF_VAR_bucket: ${{ secrets.VULTR_STATE_BUCKET }} + TF_VAR_seed_secret: ${{ secrets.VULTR_STATE_SEED_SECRET }} + TF_VAR_user_email: ${{ secrets.VULTR_BOOTSTRAP_USER_EMAIL }} + TF_VAR_user_password: ${{ secrets.VULTR_BOOTSTRAP_USER_PASSWORD }} + TF_VAR_public_key: ${{ secrets.VULTR_BOOTSTRAP_PUBLIC_KEY }} + run: terraform destroy -auto-approve + + - name: Save Outputs + if: env.DEPLOY_ACTION == 'apply' + working-directory: ${{ env.TF_WORKDIR }}/${{ matrix.target }} + run: terraform output -json > ../outputs_${{ matrix.target }}.json + + - uses: actions/upload-artifact@v4 + if: env.DEPLOY_ACTION == 'apply' + with: + name: vultr-${{ matrix.target }}-outputs + path: iac-template/terraform-hcl-standard/vultr-vps/outputs_${{ matrix.target }}.json + retention-days: 30 + + aggregate: + name: "Aggregate Vultr Bootstrap Outputs" + runs-on: ubuntu-latest + needs: bootstrap + + if: ${{ github.event.inputs.deploy_action == 'apply' }} + + steps: + - uses: actions/download-artifact@v4 + with: + path: ./outputs + + - name: Merge Outputs + run: | + echo "{" > vultr_bootstrap_outputs.json + first=true + for x in outputs/**/outputs_*.json; do + key=$(basename "$x" .json | sed 's/outputs_//') + [ "$first" = true ] && first=false || echo "," >> vultr_bootstrap_outputs.json + echo "\"$key\": $(cat "$x")" >> vultr_bootstrap_outputs.json + done + echo "}" >> vultr_bootstrap_outputs.json + + - run: cat vultr_bootstrap_outputs.json + + - uses: actions/upload-artifact@v4 + with: + name: vultr-bootstrap-final-output + path: vultr_bootstrap_outputs.json diff --git a/.github/workflows/terraform-standard-iac-pipeline-vultr-global-landingzone-baseline.yaml b/.github/workflows/terraform-standard-iac-pipeline-vultr-global-landingzone-baseline.yaml new file mode 100644 index 00000000..5689b12e --- /dev/null +++ b/.github/workflows/terraform-standard-iac-pipeline-vultr-global-landingzone-baseline.yaml @@ -0,0 +1,57 @@ +name: Terraform Standard - Vultr Global LandingZone Baseline + +on: + push: + paths: + - 'iac-template/terraform-hcl-standard/vultr-vps/**' + - '.github/workflows/terraform-standard-iac-pipeline-vultr-global-landingzone-baseline.yaml' + pull_request: + branches: [main] + workflow_dispatch: + inputs: + deploy_action: + description: "Deployment action" + type: choice + options: [plan, apply, destroy] + default: plan + +env: + TF_WORKDIR: iac-template/terraform-hcl-standard/vultr-vps + DEPLOY_ACTION: ${{ github.event.inputs.deploy_action || 'plan' }} + +jobs: + landingzone: + name: "Deploy Vultr LandingZone Baseline" + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.9.5 + + - name: Export Vultr credentials + run: echo "TF_VAR_vultr_api_key=${{ secrets.VULTR_API_KEY }}" >> "$GITHUB_ENV" + + - name: Terraform Init (LandingZone) + run: terraform -chdir=${{ env.TF_WORKDIR }}/envs/dev init -upgrade + + - name: Terraform Plan (LandingZone) + if: env.DEPLOY_ACTION == 'plan' + run: terraform -chdir=${{ env.TF_WORKDIR }}/envs/dev plan -no-color > plan_output.txt + + - name: Upload LandingZone Plan Artifact + if: env.DEPLOY_ACTION == 'plan' + uses: actions/upload-artifact@v4 + with: + name: vultr-landingzone-plan + path: ${{ env.TF_WORKDIR }}/envs/dev/plan_output.txt + + - name: Terraform Apply (LandingZone) + if: env.DEPLOY_ACTION == 'apply' + run: terraform -chdir=${{ env.TF_WORKDIR }}/envs/dev apply -auto-approve + + - name: Terraform Destroy (LandingZone) + if: env.DEPLOY_ACTION == 'destroy' + run: terraform -chdir=${{ env.TF_WORKDIR }}/envs/dev destroy -auto-approve diff --git a/.github/workflows/terraform-standard-iac-pipeline-vultr-resources-matrix.yaml b/.github/workflows/terraform-standard-iac-pipeline-vultr-resources-matrix.yaml new file mode 100644 index 00000000..ce63d0ec --- /dev/null +++ b/.github/workflows/terraform-standard-iac-pipeline-vultr-resources-matrix.yaml @@ -0,0 +1,63 @@ +name: Terraform Standard - IAC Pipeline (Vultr Resources Matrix) + +on: + push: + paths: + - 'iac-template/terraform-hcl-standard/vultr-vps/modules/compute/**' + - 'iac-template/terraform-hcl-standard/vultr-vps/modules/storage/**' + - 'iac-template/terraform-hcl-standard/vultr-vps/modules/data_store/**' + - 'iac-template/terraform-hcl-standard/vultr-vps/envs/dev/**' + - '.github/workflows/terraform-standard-iac-pipeline-vultr-resources-matrix.yaml' + workflow_dispatch: + inputs: + dry_run: + type: choice + options: ['true', 'false'] + default: 'true' + +env: + BASE_DIR: iac-template/terraform-hcl-standard/vultr-vps/envs + DRY_RUN: ${{ github.event.inputs.dry_run || 'true' }} + +jobs: + terraform: + name: "${{ matrix.env }} :: pipeline (dry_run=${{ inputs.dry_run }})" + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + env: + - dev + + steps: + - uses: actions/checkout@v4 + + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.9.5 + + - uses: terraform-linters/setup-tflint@v4 + with: + tflint_version: v0.51.0 + + - name: Export Vultr credentials + run: echo "TF_VAR_vultr_api_key=${{ secrets.VULTR_API_KEY }}" >> "$GITHUB_ENV" + + - name: Init + run: terraform -chdir=${{ env.BASE_DIR }}/${{ matrix.env }} init -upgrade + + - name: Plan + run: terraform -chdir=${{ env.BASE_DIR }}/${{ matrix.env }} plan + + - name: Apply + if: ${{ env.DRY_RUN == 'false' }} + run: terraform -chdir=${{ env.BASE_DIR }}/${{ matrix.env }} apply -auto-approve + + - name: Skip Apply (dry-run) + if: ${{ env.DRY_RUN == 'true' }} + run: echo "Dry run enabled → skip apply step." + + - name: Output + if: ${{ env.DRY_RUN == 'false' }} + run: terraform -chdir=${{ env.BASE_DIR }}/${{ matrix.env }} output -json