From 93aa33705f0d02e72337be2f8816ea484edff390 Mon Sep 17 00:00:00 2001 From: Artem Nikitin Date: Sat, 20 Jun 2026 13:54:35 +0200 Subject: [PATCH 1/4] Add GCP support --- .github/workflows/build-images.yaml | 65 ++++++++++++++++++++++ AGENTS.md | 2 +- Makefile | 8 ++- README.md | 57 ++++++++++++++++--- scripts/push-images.sh | 22 +++++--- tenants/tenant-1/kibana.yaml | 2 +- tenants/tenant-2/kibana.yaml | 2 +- tenants/tenant-3/elasticsearch-data-1.yaml | 2 +- 8 files changed, 139 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build-images.yaml b/.github/workflows/build-images.yaml index 475192c..9656322 100644 --- a/.github/workflows/build-images.yaml +++ b/.github/workflows/build-images.yaml @@ -6,7 +6,38 @@ on: pull_request: jobs: + validate-config: + # Validate the GitOps runtime config with the exact Firework enricher before + # any expensive image build. Pin FIREWORK_CONFIG_REF to the core version + # deployed to the nodes; do not validate against a floating main. + permissions: + contents: read + runs-on: ubuntu-24.04 + steps: + - name: Checkout GitOps config + uses: actions/checkout@v4 + + - name: Checkout Firework (pinned config contract) + uses: actions/checkout@v4 + with: + repository: artemnikitin/firework + ref: ${{ vars.FIREWORK_CONFIG_REF }} + path: .firework + token: ${{ secrets.FIREWORK_GITHUB_TOKEN }} + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: .firework/go.mod + + - name: Validate runtime config + working-directory: .firework + run: go run ./cmd/configcheck --require-remote-routing --input-dir "$GITHUB_WORKSPACE" + build: + needs: validate-config + permissions: + contents: read strategy: fail-fast: false matrix: @@ -53,3 +84,37 @@ jobs: AWS_REGION: ${{ vars.AWS_REGION }} S3_IMAGES_BUCKET: ${{ vars.S3_IMAGES_BUCKET }} run: make push + + - name: Save amd64 rootfs artifacts + if: matrix.target_platform == 'linux/amd64' + uses: actions/upload-artifact@v4 + with: + name: rootfs-amd64 + path: "*-rootfs.ext4" + if-no-files-found: error + + upload-gcs: + needs: build + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + runs-on: ubuntu-24.04 + permissions: + contents: read + id-token: write + steps: + - uses: actions/checkout@v4 + + - uses: actions/download-artifact@v4 + with: + name: rootfs-amd64 + + - name: Authenticate to GCP + uses: google-github-actions/auth@v3 + with: + workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }} + service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }} + project_id: ${{ secrets.GCP_PROJECT_ID }} + + - name: Upload images to GCS + env: + GCS_IMAGES_BUCKET: ${{ vars.GCS_IMAGES_BUCKET }} + run: make push-gcs diff --git a/AGENTS.md b/AGENTS.md index c82f293..501421e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ ## Project -This is the example GitOps input repo for Firework. It defines tenant service YAML and config overlays used to build Firecracker-ready rootfs images and publish them to S3. +This is the example GitOps input repo for Firework. It defines tenant service YAML and config overlays used to build Firecracker-ready rootfs images and publish them (ARM64 to S3, amd64 to GCS). Public routing is provider-neutral via `metadata.subdomain`; there is no provider-specific runtime config tree. ## Layout diff --git a/Makefile b/Makefile index 4bd4e04..ab1b620 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ TARGET_PLATFORM ?= linux/arm64 -.PHONY: build build-amd64 build-arm64 push +.PHONY: build build-amd64 build-arm64 push push-s3 push-gcs build: TARGET_PLATFORM="$(TARGET_PLATFORM)" bash ./scripts/build-images.sh @@ -13,3 +13,9 @@ build-arm64: push: bash ./scripts/push-images.sh + +push-s3: + S3_IMAGES_BUCKET="$(S3_IMAGES_BUCKET)" bash ./scripts/push-images.sh + +push-gcs: + GCS_IMAGES_BUCKET="$(GCS_IMAGES_BUCKET)" bash ./scripts/push-images.sh diff --git a/README.md b/README.md index a72eac1..5b767cb 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,12 @@ > This is an example deployment intended for demonstration and learning purposes only. It is not hardened, audited, etc. -Example GitOps repository for [Firework](https://github.com/artemnikitin/firework), focused on building Firecracker-ready rootfs images from Docker images and publishing them to S3. +Example GitOps repository for [Firework](https://github.com/artemnikitin/firework), focused on building Firecracker-ready rootfs images and publishing ARM64 images to S3 and amd64 images to GCS. ## Related Repositories - [firework](https://github.com/artemnikitin/firework) - orchestrator runtime (`firework-agent`, `enricher`, `scheduler`) -- [firework-deployment-example](https://github.com/artemnikitin/firework-deployment-example) - Terraform + Packer deployment on AWS +- [firework-deployment-example](https://github.com/artemnikitin/firework-deployment-example) - Terraform + Packer deployment on AWS and GCP ## Configuration Docs @@ -25,7 +25,7 @@ flowchart LR GH[Git push to this repo] --> GHA[GitHub Actions build-images] GH --> WEBHOOK[Webhook to enricher] - GHA --> IMG[S3 images bucket
*-rootfs.ext4] + GHA --> IMG[S3 ARM64 / GCS amd64 images
*-rootfs.ext4] WEBHOOK --> ENRICHER[enricher Lambda] ENRICHER --> CFG[S3 configs bucket
nodes/*.yaml] @@ -45,9 +45,10 @@ locally cached tag for another architecture cannot leak into the build. The workflow installs CI dependencies, then delegates image work to the Makefile. The Makefile is a thin entrypoint that calls the shell scripts in `scripts/`: -On pull requests, CI runs `make build` only for both architectures. On pushes to -`main`, CI builds both architectures and uploads the existing ARM64 artifact -names with `make push`. +On pull requests, CI builds both architectures without cloud credentials. On +pushes to `main`, the ARM64 leg uploads to S3. The amd64 leg saves an artifact +for a separate main-only job that obtains a GCP token through Workload Identity +Federation and uploads to GCS. The shared build job has no OIDC permission. 1. `make build` calls `scripts/build-images.sh`. 2. `scripts/build-images.sh` resolves `fc-init` (release asset, `go install`, @@ -61,8 +62,48 @@ names with `make push`. first, tenant-specific on top): - `configs//` (shared baseline, applied first if present) - `configs/-/` (tenant-specific, applied on top if present, overrides shared) -7. `make push` calls `scripts/push-images.sh` to upload resulting - `*-rootfs.ext4` artifacts to S3. +7. `make push` calls `scripts/push-images.sh`; `S3_IMAGES_BUCKET` selects S3 and + `GCS_IMAGES_BUCKET` selects GCS. + +## Public routing (provider-neutral) + +A service requests a public route with `metadata.subdomain: