feat: add Woodpecker gRPC Tailscale funnel for external Mac agent #173

Merged
forgejo_admin merged 1 commit from 172-woodpecker-grpc-funnel into main 2026-03-26 15:50:08 +00:00

Summary

  • Adds a Tailscale funnel for Woodpecker gRPC (port 9000) at woodpecker-grpc.tail5b443a.ts.net
  • Enables external Mac agent to connect for iOS build jobs
  • Existing HTTP funnel (port 80, web UI) unchanged

Changes

  • terraform/main.tf: Added kubernetes_ingress_v1.woodpecker_grpc_funnel resource (31 lines)

tofu plan output

Plan: 1 to add, 2 to change, 0 to destroy.

Test Plan

  • tofu validate passes
  • tofu plan -lock=false shows clean 1-add
  • tofu apply creates ingress
  • woodpecker-grpc.tail5b443a.ts.net resolves
  • Mac agent logs show successful gRPC connection
  • Woodpecker admin UI shows Mac agent connected
  • Existing web UI at woodpecker.tail5b443a.ts.net unaffected

Review Checklist

  • Passed tofu fmt and tofu validate
  • No secrets committed
  • No unnecessary file changes (1 file, 1 resource)
  • Commit message is descriptive
  • Closes #172
  • project-capacitor-mobile — discovered scope from Mac CI agent setup (#166)
## Summary - Adds a Tailscale funnel for Woodpecker gRPC (port 9000) at `woodpecker-grpc.tail5b443a.ts.net` - Enables external Mac agent to connect for iOS build jobs - Existing HTTP funnel (port 80, web UI) unchanged ## Changes - `terraform/main.tf`: Added `kubernetes_ingress_v1.woodpecker_grpc_funnel` resource (31 lines) ### tofu plan output ``` Plan: 1 to add, 2 to change, 0 to destroy. ``` ## Test Plan - [x] `tofu validate` passes - [x] `tofu plan -lock=false` shows clean 1-add - [ ] `tofu apply` creates ingress - [ ] `woodpecker-grpc.tail5b443a.ts.net` resolves - [ ] Mac agent logs show successful gRPC connection - [ ] Woodpecker admin UI shows Mac agent connected - [ ] Existing web UI at `woodpecker.tail5b443a.ts.net` unaffected ## Review Checklist - [x] Passed `tofu fmt` and `tofu validate` - [x] No secrets committed - [x] No unnecessary file changes (1 file, 1 resource) - [x] Commit message is descriptive ## Related - Closes #172 - `project-capacitor-mobile` — discovered scope from Mac CI agent setup (#166)
feat: add Woodpecker gRPC Tailscale funnel for external Mac agent
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
a008dc1a5a
The existing woodpecker-funnel routes HTTP (port 80) for the web UI.
External agents (Mac CI) need gRPC access on port 9000. This adds a
separate funnel at woodpecker-grpc.tail5b443a.ts.net routing to the
gRPC port, enabling the Mac Woodpecker agent to connect.

Closes #172

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author
Owner

PR #173 Review

DOMAIN REVIEW

Tech stack: Terraform (OpenTofu) / Kubernetes / Tailscale / Woodpecker CI

The PR adds a single kubernetes_ingress_v1.woodpecker_grpc_funnel resource to expose the Woodpecker server gRPC port (9000) via a Tailscale funnel at woodpecker-grpc.tail5b443a.ts.net. This enables an external Mac agent to connect for iOS build jobs.

Terraform style: The new resource follows the exact same pattern as the existing woodpecker_funnel (lines 796-823) and all other funnels in the codebase (grafana, alertmanager, forgejo, harbor, minio, keycloak). Annotations, ingress class, TLS block, and depends_on chain are all consistent. This is correct pattern reuse, not duplication.

Tailscale ACL: The nodeAttrs block (line 82-87) grants the funnel attribute to autogroup:member and tag:k8s. This already covers the new ingress resource -- no ACL changes needed.

Woodpecker gRPC port: The Helm chart (v3.5.1) exposes gRPC on port 9000 by default via the woodpecker-server service. No WOODPECKER_GRPC_ADDR override is present or needed (server defaults to 0.0.0.0:9000). The backend port reference is correct.

Security: Tailscale funnel provides TLS termination. gRPC auth uses the existing WOODPECKER_AGENT_SECRET (already configured via set_sensitive at lines 773-783). No new secrets or credentials introduced.

State safety: Plan: 1 to add, 2 to change, 0 to destroy -- additive only, no state-breaking changes. The 2 changes are expected (Tailscale ACL refresh + operator reconciliation).

BLOCKERS

None.

NITS

  1. Missing output: Every other funnel has a corresponding output in outputs.tf (e.g., woodpecker_url, grafana_url, harbor_url). Consider adding a woodpecker_grpc_url output for discoverability:
    output "woodpecker_grpc_url" {
      description = "Woodpecker gRPC URL (Tailscale funnel, external agent)"
      value       = "https://woodpecker-grpc.${var.tailscale_domain}"
    }
    

SOP COMPLIANCE

  • Branch named after issue: 172-woodpecker-grpc-funnel matches issue #172
  • PR body follows template: Summary, Changes, Test Plan, Review Checklist, Related all present
  • Related references project: project-capacitor-mobile with discovered scope from #166
  • No plan slug expected (kanban-driven, not plan-driven)
  • No secrets committed
  • No unnecessary file changes: 1 file, 31 additions, 0 deletions
  • Commit message is descriptive
  • tofu fmt and tofu validate confirmed passing
  • tofu plan -lock=false output included

PROCESS OBSERVATIONS

  • Clean, minimal change with low change failure risk. The pattern is well-established across 7+ existing funnels in this file.
  • Test plan includes post-apply validation steps (DNS resolution, Mac agent connection, existing UI unaffected) which are appropriate for infra changes that cannot be unit-tested.
  • Deployment frequency: unblocks iOS CI pipeline work, enabling the Capacitor mobile build chain.

VERDICT: APPROVED

## PR #173 Review ### DOMAIN REVIEW **Tech stack**: Terraform (OpenTofu) / Kubernetes / Tailscale / Woodpecker CI The PR adds a single `kubernetes_ingress_v1.woodpecker_grpc_funnel` resource to expose the Woodpecker server gRPC port (9000) via a Tailscale funnel at `woodpecker-grpc.tail5b443a.ts.net`. This enables an external Mac agent to connect for iOS build jobs. **Terraform style**: The new resource follows the exact same pattern as the existing `woodpecker_funnel` (lines 796-823) and all other funnels in the codebase (grafana, alertmanager, forgejo, harbor, minio, keycloak). Annotations, ingress class, TLS block, and `depends_on` chain are all consistent. This is correct pattern reuse, not duplication. **Tailscale ACL**: The `nodeAttrs` block (line 82-87) grants the `funnel` attribute to `autogroup:member` and `tag:k8s`. This already covers the new ingress resource -- no ACL changes needed. **Woodpecker gRPC port**: The Helm chart (v3.5.1) exposes gRPC on port 9000 by default via the `woodpecker-server` service. No `WOODPECKER_GRPC_ADDR` override is present or needed (server defaults to `0.0.0.0:9000`). The backend port reference is correct. **Security**: Tailscale funnel provides TLS termination. gRPC auth uses the existing `WOODPECKER_AGENT_SECRET` (already configured via `set_sensitive` at lines 773-783). No new secrets or credentials introduced. **State safety**: `Plan: 1 to add, 2 to change, 0 to destroy` -- additive only, no state-breaking changes. The 2 changes are expected (Tailscale ACL refresh + operator reconciliation). ### BLOCKERS None. ### NITS 1. **Missing output**: Every other funnel has a corresponding `output` in `outputs.tf` (e.g., `woodpecker_url`, `grafana_url`, `harbor_url`). Consider adding a `woodpecker_grpc_url` output for discoverability: ```hcl output "woodpecker_grpc_url" { description = "Woodpecker gRPC URL (Tailscale funnel, external agent)" value = "https://woodpecker-grpc.${var.tailscale_domain}" } ``` ### SOP COMPLIANCE - [x] Branch named after issue: `172-woodpecker-grpc-funnel` matches issue #172 - [x] PR body follows template: Summary, Changes, Test Plan, Review Checklist, Related all present - [x] Related references project: `project-capacitor-mobile` with discovered scope from #166 - [x] No plan slug expected (kanban-driven, not plan-driven) - [x] No secrets committed - [x] No unnecessary file changes: 1 file, 31 additions, 0 deletions - [x] Commit message is descriptive - [x] `tofu fmt` and `tofu validate` confirmed passing - [x] `tofu plan -lock=false` output included ### PROCESS OBSERVATIONS - Clean, minimal change with low change failure risk. The pattern is well-established across 7+ existing funnels in this file. - Test plan includes post-apply validation steps (DNS resolution, Mac agent connection, existing UI unaffected) which are appropriate for infra changes that cannot be unit-tested. - Deployment frequency: unblocks iOS CI pipeline work, enabling the Capacitor mobile build chain. ### VERDICT: APPROVED
forgejo_admin deleted branch 172-woodpecker-grpc-funnel 2026-03-26 15:50:08 +00:00
Sign in to join this conversation.
No description provided.