Terraform — Scaleway cluster #32
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: Terraform — Scaleway cluster | |
| # Drives 02-cluster/scaleway through the .github/actions/terraform composite action: | |
| # - pull_request → plan | |
| # - push to main → apply | |
| # - schedule (daily 18h) → destroy (cost-control teardown of the homelab) | |
| # - workflow_dispatch → up/down on demand (plan | apply | destroy) | |
| # | |
| # State R/W + lock uses the org state role (vars.AWS_TF_STATE_ROLE_ARN — | |
| # AmazonS3FullAccess, see 01-iam/ci-managed/aws-state-access). Scaleway cluster | |
| # lifecycle uses the CI API key from the `scaleway` environment (Kubernetes/VPC/ | |
| # PrivateNetwork FullAccess, see 01-iam/bootstrap/scaleway). Provider creds are set as job env (read by the | |
| # action) — never passed as plain action inputs. No static AWS keys. | |
| on: | |
| pull_request: | |
| paths: | |
| - '02-cluster/scaleway/**' | |
| - '.github/actions/terraform/**' | |
| - '.github/workflows/scaleway.yml' | |
| push: | |
| branches: [main] | |
| paths: | |
| - '02-cluster/scaleway/**' | |
| - '.github/actions/terraform/**' | |
| - '.github/workflows/scaleway.yml' | |
| schedule: | |
| # 16:00 UTC = 18:00 Europe/Paris in summer (CEST). GitHub cron is UTC and does | |
| # NOT follow DST, so in winter (CET) this fires at 17:00 Paris. | |
| - cron: '0 16 * * *' | |
| workflow_dispatch: | |
| inputs: | |
| command: | |
| description: 'Terraform command (apply = up, destroy = down).' | |
| type: choice | |
| options: [plan, apply, destroy] | |
| default: plan | |
| concurrency: | |
| # Serialize everything that writes this root's state (apply/destroy never cancel | |
| # mid-flight); only cancel superseded PR plans. schedule/push share ref=main. | |
| group: scaleway-${{ github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| permissions: | |
| contents: read | |
| jobs: | |
| terraform: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| # The `scaleway` environment carries SCW_ACCESS_KEY / SCW_SECRET_KEY (and | |
| # satisfies zizmor's secrets-in-environment audit). It currently has no | |
| # protection rule, so the daily scheduled destroy runs unattended — keep it | |
| # that way (a required-reviewer rule would block the cron). | |
| environment: scaleway | |
| permissions: | |
| id-token: write # mint OIDC tokens for AWS + Infisical | |
| contents: read | |
| # Provider creds exposed to the composite action via the job env (not inputs). | |
| env: | |
| SCW_ACCESS_KEY: ${{ secrets.SCW_ACCESS_KEY }} | |
| SCW_SECRET_KEY: ${{ secrets.SCW_SECRET_KEY }} | |
| SCW_DEFAULT_ORGANIZATION_ID: ${{ vars.SCW_DEFAULT_ORGANIZATION_ID }} | |
| SCW_DEFAULT_PROJECT_ID: ${{ vars.SCW_DEFAULT_PROJECT_ID }} | |
| INFISICAL_MACHINE_IDENTITY_ID: ${{ vars.INFISICAL_MACHINE_IDENTITY_ID }} | |
| steps: | |
| - name: Assert state role ARN is present | |
| env: | |
| ROLE_ARN: ${{ vars.AWS_TF_STATE_ROLE_ARN }} | |
| run: | | |
| if [ -z "$ROLE_ARN" ]; then | |
| echo "::error::vars.AWS_TF_STATE_ROLE_ARN is not set (provisioned by 01-iam/ci-managed/aws-state-access)." | |
| exit 1 | |
| fi | |
| - name: Resolve terraform command | |
| id: cmd | |
| env: | |
| EVENT: ${{ github.event_name }} | |
| DISPATCH_CMD: ${{ github.event.inputs.command }} | |
| run: | | |
| case "$EVENT" in | |
| schedule) cmd=destroy ;; | |
| push) cmd=apply ;; | |
| workflow_dispatch) cmd="${DISPATCH_CMD:-plan}" ;; | |
| *) cmd=plan ;; | |
| esac | |
| echo "command=$cmd" >> "$GITHUB_OUTPUT" | |
| echo "Resolved terraform command: $cmd (event: $EVENT)" | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| fetch-depth: 1 | |
| - uses: ./.github/actions/terraform | |
| with: | |
| root: 02-cluster/scaleway | |
| tfvars-file: 02-cluster-staging.tfvars | |
| command: ${{ steps.cmd.outputs.command }} | |
| aws-role-arn: ${{ vars.AWS_TF_STATE_ROLE_ARN }} |