Producer/consumer model
Eigenoid separates CI/CD logic (producer) from infrastructure definitions (consumer). This lets multiple infrastructure stacks share the same pipeline without duplicating workflows.
Architecture
The @v1 contract
Consumers invoke the producer using a major tag reference:
uses: eigenoid/platform-actions/.github/workflows/terraform-orchestrator.yml@v1
The v1 tag is a floating tag that always points to the latest v1.x.y release. This means:
- Consumers receive fixes automatically the next time their pipelines run.
- No breaking changes within a major version.
- The producer controls when
v1advances -- each merge tomaincreates a release viarelease-please, and thev1tag moves to the new release.
Producer release cycle
PR in platform-actions/ → merge → release-please creates vX.Y.Z → v1 tag moves
↓
Consumers use @v1 automatically
Full flow: PR, plan, apply, promote
1. Automatic plan (PR opened)
Developer opens PR in consumer
→ terraform.yml fires (pull_request)
→ Calls orchestrator@v1
→ Parses terraflow.yaml
→ Resolves dev config from environments.yaml
→ Runs terraform plan for each layer (by waves)
→ Bot posts plan output as a PR comment
2. Apply (slash command)
Reviewer comments "/terraflow apply" on the PR
→ terraform.yml fires (issue_comment)
→ check-comment validates:
- Author is OWNER/MEMBER/COLLABORATOR
- A successful plan exists for that commit
→ Calls orchestrator@v1 with action=apply
→ Downloads saved plan from the previous run
→ Runs terraform apply
→ Bot updates the comment with the result
3. Promote (post-merge)
Admin triggers workflow_dispatch:
action: promote
target_environment: qa
→ Calls orchestrator@v1
→ Resolves qa config from environments.yaml
→ Runs plan + apply in qa (with approval gate if configured)
Authentication
The pipeline uses two levels of authentication:
| Level | Mechanism | Purpose |
|---|---|---|
| GitHub to GitHub | GitHub App (eigenoid-terraflow-bot) | Cross-repo access to read config and comment on PRs |
| GitHub to GCP | Workload Identity Federation (OIDC) | Secretless authentication for Terraform |
Workload Identity Federation
GitHub Actions Runner
→ Requests OIDC token from GitHub
→ Exchanges it with GCP STS for an ephemeral token
→ Impersonates a Service Account
→ Runs Terraform with temporary credentials
No GCP credentials are stored in GitHub -- the trust relationship is configured entirely in the WIF pool/provider.
Centralized configuration
Environment configuration lives in the producer (platform-actions/config/environments.yaml), not in the consumer. This gives you:
- A single place to update project IDs, WIF providers, and SA emails.
- Consistency across every consumer in the org.
- Fallback: if the bot is not configured, the orchestrator reads
vars.*from the consumer repo.
# platform-actions/config/environments.yaml
environments:
dev:
cloud: gcp
project_id: eigenoid-dev
project_number: "620520745421"
wif_provider: "projects/620520745421/locations/global/workloadIdentityPools/github/providers/eigenoid"
sa_email: "terraform-ci@eigenoid-dev.iam.gserviceaccount.com"
state_bucket_prefix: eigenoid-2cea55
region: europe-west1
qa:
# ...
prd:
# ...