This repository was archived by the owner on Aug 10, 2026. It is now read-only.
Repository navigation
Destroy URL Bookmark Saver #3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Destroy URL Bookmark Saver | |
| # Pipeline stages: | |
| # preflight ──→ teardown | |
| # | |
| # preflight validates identity and the safety confirmation. | |
| # teardown only runs if preflight passes. | |
| # Only runs when manually triggered — no push/PR trigger intentionally. | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| student_name: | |
| description: 'Deployment name prefix used when the stack was deployed (e.g. john-smith)' | |
| required: true | |
| aws_region: | |
| description: 'AWS region where the stack lives' | |
| required: false | |
| default: 'us-east-1' | |
| aws_access_key_id: | |
| description: 'AWS Access Key ID — leave blank to use repo secret AWS_ACCESS_KEY_ID' | |
| required: false | |
| default: '' | |
| aws_secret_access_key: | |
| description: 'AWS Secret Access Key — leave blank to use repo secret AWS_SECRET_ACCESS_KEY' | |
| required: false | |
| default: '' | |
| confirm_destroy: | |
| description: 'Type "destroy" to confirm you want to tear down all resources' | |
| required: true | |
| env: | |
| PROJECT_DIR: projects/03-url-bookmark-saver | |
| AWS_REGION: ${{ inputs.aws_region || 'us-east-1' }} | |
| STUDENT_NAME: ${{ inputs.student_name }} | |
| # ── Stage 1: Preflight ──────────────────────────────────────────────────────── | |
| jobs: | |
| preflight: | |
| name: Preflight | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - name: Confirm destruction intent | |
| shell: bash | |
| run: | | |
| if [ "${{ inputs.confirm_destroy }}" != "destroy" ]; then | |
| echo "::error::Safety check failed. Set confirm_destroy to the word \"destroy\" to proceed." | |
| exit 1 | |
| fi | |
| echo "Confirmation accepted. Will destroy stack: ${STUDENT_NAME} in ${AWS_REGION}" | |
| - uses: actions/checkout@v4 | |
| - uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_wrapper: false | |
| # Priority 1: workflow inputs | |
| - name: Configure AWS credentials (workflow inputs) | |
| if: ${{ inputs.aws_access_key_id != '' }} | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-region: ${{ env.AWS_REGION }} | |
| aws-access-key-id: ${{ inputs.aws_access_key_id }} | |
| aws-secret-access-key: ${{ inputs.aws_secret_access_key }} | |
| # Priority 2: OIDC role | |
| - name: Configure AWS credentials (OIDC role) | |
| if: ${{ inputs.aws_access_key_id == '' && vars.URL_BOOKMARK_SAVER_AWS_ROLE_ARN != '' }} | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-region: ${{ env.AWS_REGION }} | |
| role-to-assume: ${{ vars.URL_BOOKMARK_SAVER_AWS_ROLE_ARN }} | |
| role-session-name: github-actions-stash-destroy | |
| # Priority 3: repo secrets | |
| - name: Configure AWS credentials (repo secrets) | |
| if: ${{ inputs.aws_access_key_id == '' && vars.URL_BOOKMARK_SAVER_AWS_ROLE_ARN == '' }} | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-region: ${{ env.AWS_REGION }} | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| - name: Verify AWS identity | |
| run: aws sts get-caller-identity | |
| - name: Create placeholder lambda.zip | |
| run: | | |
| echo "placeholder" | zip -q ${{ env.PROJECT_DIR }}/backend/lambda.zip - | |
| - name: Terraform init (dry-run validate) | |
| working-directory: ${{ env.PROJECT_DIR }}/terraform | |
| run: | | |
| terraform init -input=false | |
| terraform plan \ | |
| -destroy \ | |
| -input=false \ | |
| -var="student_name=${STUDENT_NAME}" \ | |
| -var="aws_region=${AWS_REGION}" \ | |
| -out=destroy.tfplan | |
| # Surface what will be destroyed before teardown runs | |
| - name: Upload destroy plan | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: destroy-tfplan | |
| path: ${{ env.PROJECT_DIR }}/terraform/destroy.tfplan | |
| retention-days: 1 | |
| # ── Stage 2: Teardown ───────────────────────────────────────────────────────── | |
| teardown: | |
| name: Teardown | |
| runs-on: ubuntu-latest | |
| needs: preflight | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_wrapper: false | |
| # Same credential priority as preflight | |
| - name: Configure AWS credentials (workflow inputs) | |
| if: ${{ inputs.aws_access_key_id != '' }} | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-region: ${{ env.AWS_REGION }} | |
| aws-access-key-id: ${{ inputs.aws_access_key_id }} | |
| aws-secret-access-key: ${{ inputs.aws_secret_access_key }} | |
| - name: Configure AWS credentials (OIDC role) | |
| if: ${{ inputs.aws_access_key_id == '' && vars.URL_BOOKMARK_SAVER_AWS_ROLE_ARN != '' }} | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-region: ${{ env.AWS_REGION }} | |
| role-to-assume: ${{ vars.URL_BOOKMARK_SAVER_AWS_ROLE_ARN }} | |
| role-session-name: github-actions-stash-destroy | |
| - name: Configure AWS credentials (repo secrets) | |
| if: ${{ inputs.aws_access_key_id == '' && vars.URL_BOOKMARK_SAVER_AWS_ROLE_ARN == '' }} | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-region: ${{ env.AWS_REGION }} | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| - name: Create placeholder lambda.zip | |
| run: | | |
| echo "placeholder" | zip -q ${{ env.PROJECT_DIR }}/backend/lambda.zip - | |
| - name: Terraform init | |
| working-directory: ${{ env.PROJECT_DIR }}/terraform | |
| run: terraform init -input=false | |
| - name: Empty S3 frontend bucket | |
| working-directory: ${{ env.PROJECT_DIR }}/terraform | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| terraform refresh \ | |
| -input=false \ | |
| -var="student_name=${STUDENT_NAME}" \ | |
| -var="aws_region=${AWS_REGION}" 2>/dev/null || true | |
| BUCKET=$(terraform output -raw frontend_bucket 2>/dev/null || echo "") | |
| if [ -n "$BUCKET" ]; then | |
| echo "Emptying bucket: $BUCKET" | |
| aws s3 rm "s3://${BUCKET}" --recursive --region "${AWS_REGION}" || true | |
| else | |
| echo "No frontend bucket found in state — skipping." | |
| fi | |
| - name: Terraform destroy | |
| working-directory: ${{ env.PROJECT_DIR }}/terraform | |
| run: | | |
| terraform destroy \ | |
| -auto-approve \ | |
| -input=false \ | |
| -var="student_name=${STUDENT_NAME}" \ | |
| -var="aws_region=${AWS_REGION}" | |
| - name: Publish destroy summary | |
| if: always() | |
| shell: bash | |
| run: | | |
| { | |
| echo "## URL Bookmark Saver — Destroyed" | |
| echo "" | |
| echo "| | |" | |
| echo "|---|---|" | |
| echo "| **Region** | ${AWS_REGION} |" | |
| echo "| **Name** | ${STUDENT_NAME} |" | |
| echo "| **Triggered by** | ${{ github.actor }} |" | |
| echo "| **Status** | ${{ job.status }} |" | |
| } >> "$GITHUB_STEP_SUMMARY" |