Skip to content

ci: terraform composite action — plan/apply/destroy + scaleway lifecycle#36

Merged
nbrieussel merged 6 commits into
mainfrom
ci/reusable-terraform-action
Jun 19, 2026
Merged

ci: terraform composite action — plan/apply/destroy + scaleway lifecycle#36
nbrieussel merged 6 commits into
mainfrom
ci/reusable-terraform-action

Conversation

@nbrieussel

@nbrieussel nbrieussel commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Refactors the Terraform CI so it scales across roots, supports the full lifecycle, and keeps secrets out of action inputs.

Composite action .github/actions/terraform — setup-terraform + Infisical OIDC mint + AWS assume + init/workspace select/plan|apply|destroy. It declares no secret inputs: provider creds (SCW_*, INFISICAL_MACHINE_IDENTITY_ID) are read from the job env.

Workflows use the action directly (no reusable-workflow wrapper — the secrets: keyword is workflow-only and wrapping just for it was overengineering). The calling job sets the provider creds as job env: within the scaleway environment, owns the trigger→command mapping, concurrency, and timeout-minutes.

Behaviour:

  • plan on PR, apply on push to main.
  • scaleway: daily 18h cron → destroy (homelab cost control) and workflow_dispatch up/down (apply = up, destroy = down). Consolidates the old scaleway-plan.yml.

Naming/doc fixes (were misleading):

  • Org state role s3-listertf-state-access (grants AmazonS3FullAccess = R/W + lock). Wired via vars.AWS_TF_STATE_ROLE_ARN.
  • Scaleway CI policy object-storage-rocluster-management (actually grants Kubernetes/VPC/PrivateNetwork access).
  • CLAUDE.md updated.

⚠️ Cutover for the role rename (operational)

vars.AWS_TF_STATE_ROLE_ARN is already set to the predicted ARN (…/tf-state-access). On merge to main, iam_terraform-backend-role applies 00-remote_state/1-iam and recreates the role at that ARN; afterwards vars.AWS_S3_LISTER_ROLE_ARN can be deleted. The scaleway check on this PR may stay red until the role exists at the new ARN.

Notes

  • Destroy cron 0 16 * * * UTC = 18h Paris in summer (17h in winter — GitHub cron ignores DST).
  • The scaleway environment must keep no required-reviewer rule (currently none), or the cron destroy would block.

Test plan

  • actionlint + zizmor (default severity) pass locally.
  • lint-workflows green in CI.
  • After cutover: PR plan, workflow_dispatch apply/destroy, cron destroy.

🤖 Generated with Claude Code

…ction

Extract the boilerplate (setup-terraform + AWS OIDC + init/workspace/plan-apply)
into .github/actions/terraform. Both iam_terraform-backend-role and scaleway-plan
now call it — the latter keeping its SCW/Infisical env vars and Infisical OIDC
token step before the action call.

Also fixes a destroy→plan bug in scaleway-plan.yml and adds concurrency guard
to iam_terraform-backend-role.yml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread .github/actions/terraform/action.yml
Comment thread .github/actions/terraform/action.yml Outdated
Wrap the .github/actions/terraform composite action in a reusable workflow
(.github/workflows/terraform.yml) that owns the `secrets:` block — Scaleway keys
are no longer passed as plain action inputs. The action declares NO secret
inputs; provider creds flow through the job env / the `scaleway` environment.

- Support plan | apply | destroy; the reusable workflow derives the command from
  the event (push→apply, schedule→destroy, else plan), overridable via `command`.
- scaleway.yml: PR→plan, push→apply, daily 18h cron→destroy, workflow_dispatch
  up/down. Consolidates the former scaleway-plan.yml. Adds concurrency + timeout.
- Rename the org state role s3-lister → tf-state-access (it grants
  AmazonS3FullAccess: R/W + lock — the old name was misleading). Wired via
  vars.AWS_TF_STATE_ROLE_ARN.
- Fix stale docs/naming: the Scaleway CI policy (object-storage-ro →
  cluster-management; it actually grants Kubernetes/VPC/PrivateNetwork access)
  and the read-only descriptions in CLAUDE.md / 00-remote_state.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@nbrieussel nbrieussel changed the title ci: reusable composite action for Terraform workflows ci: reusable terraform workflow (plan/apply/destroy) with first-class secret handling Jun 19, 2026
…ctly

The `secrets:` keyword only exists at the workflow level, so a reusable-workflow
wrapper added solely to declare it is overengineering for now. Removed
terraform.yml; scaleway.yml and iam_terraform-backend-role.yml use the composite
action directly again.

Secrets are still not passed as action inputs: the composite action declares no
secret inputs and reads provider creds (SCW_*, INFISICAL_MACHINE_IDENTITY_ID)
from the job env, which the calling workflow sets from the `scaleway` environment.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@nbrieussel nbrieussel changed the title ci: reusable terraform workflow (plan/apply/destroy) with first-class secret handling ci: terraform composite action — plan/apply/destroy + scaleway lifecycle Jun 19, 2026
The `lock` input only existed for the (mistaken) read-only-role assumption — a
role that can't write S3 can't acquire the state lock. The state role is
tf-state-access (AmazonS3FullAccess: R/W + lock) and no caller ever set
lock=false, so the input was dead. Let Terraform manage the lock by default
(the S3 backend has use_lockfile = true).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The role name is read from env/00-remote-state-iam.tfvars (which overrides the
variables.tf default), and the rename only touched the default — so an apply
still produced `s3-lister`. Set it in the tfvars so it matches the agreed name
and vars.AWS_TF_STATE_ROLE_ARN.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@nbrieussel nbrieussel merged commit f1f7321 into main Jun 19, 2026
5 checks passed
@nbrieussel nbrieussel deleted the ci/reusable-terraform-action branch June 19, 2026 11:40
@nbrieussel nbrieussel restored the ci/reusable-terraform-action branch June 19, 2026 12:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant