From f8b66917360b6536e3e9383d45e2c593cc8fb206 Mon Sep 17 00:00:00 2001 From: Denis Mishin Date: Tue, 16 Jun 2026 20:14:56 -0400 Subject: [PATCH 1/3] config: add CRD-less kustomize variants + CRD sync to install Decouple CRD installation from the controller so a single owner can manage the cluster-scoped CRD. Extract the clustered-databroker StatefulSet patch into a shared component, add default-no-crd / clustered-databroker-no-crd variants, and add a workflow that publishes CRD bases to pomerium/install. --- .github/workflows/sync-crds-to-install.yaml | 47 ++++++++ .../kustomization.yaml | 8 ++ .../clustered-databroker/kustomization.yaml | 106 +---------------- .../databroker-cluster/kustomization.yaml | 111 ++++++++++++++++++ .../databroker-cluster}/pdb.yaml | 0 .../databroker-cluster}/service/headless.yaml | 0 .../service/kustomization.yaml | 0 config/default-no-crd/kustomization.yaml | 11 ++ 8 files changed, 179 insertions(+), 104 deletions(-) create mode 100644 .github/workflows/sync-crds-to-install.yaml create mode 100644 config/clustered-databroker-no-crd/kustomization.yaml create mode 100644 config/components/databroker-cluster/kustomization.yaml rename config/{clustered-databroker => components/databroker-cluster}/pdb.yaml (100%) rename config/{clustered-databroker => components/databroker-cluster}/service/headless.yaml (100%) rename config/{clustered-databroker => components/databroker-cluster}/service/kustomization.yaml (100%) create mode 100644 config/default-no-crd/kustomization.yaml diff --git a/.github/workflows/sync-crds-to-install.yaml b/.github/workflows/sync-crds-to-install.yaml new file mode 100644 index 00000000..9da1d4be --- /dev/null +++ b/.github/workflows/sync-crds-to-install.yaml @@ -0,0 +1,47 @@ +name: Sync CRDs to install + +# Publishes the generated CRD bases to pomerium/install so the Terraform +# install module never silently lags this repo. Opens a PR against install +# whenever the CRD bases change on main (and on demand). + +on: + push: + branches: + - main + paths: + - "config/crd/bases/**" + workflow_dispatch: + +jobs: + sync-crds: + runs-on: ubuntu-latest + steps: + - name: Checkout ingress-controller + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + + - name: Checkout install + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + with: + repository: pomerium/install + path: install + token: ${{ secrets.APPARITOR_GITHUB_TOKEN }} + + - name: Copy CRD bases + run: | + dst="install/ingress-controller/kustomize/crd/bases" + mkdir -p "$dst" + cp config/crd/bases/ingress.pomerium.io_pomerium.yaml "$dst/" + cp config/crd/bases/gateway.pomerium.io_policyfilters.yaml "$dst/" + + - name: Create Pull Request + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 + with: + path: install + author: GitHub Actions + body: "Automated CRD sync from pomerium/ingress-controller@${{ github.sha }}." + branch: ci/sync-crds + commit-message: "ci: sync CRDs from ingress-controller" + delete-branch: true + labels: ci + title: "ci: sync CRDs from ingress-controller" + token: ${{ secrets.APPARITOR_GITHUB_TOKEN }} diff --git a/config/clustered-databroker-no-crd/kustomization.yaml b/config/clustered-databroker-no-crd/kustomization.yaml new file mode 100644 index 00000000..dca88229 --- /dev/null +++ b/config/clustered-databroker-no-crd/kustomization.yaml @@ -0,0 +1,8 @@ +# CRD-less variant of clustered-databroker: the clustered StatefulSet install +# without the CRD bases, for clusters where the CRD is owned by a separate +# installer. Mirrors clustered-databroker but builds on default-no-crd. +namespace: pomerium +resources: + - ../default-no-crd +components: + - ../components/databroker-cluster diff --git a/config/clustered-databroker/kustomization.yaml b/config/clustered-databroker/kustomization.yaml index 2a93e6e6..36999818 100644 --- a/config/clustered-databroker/kustomization.yaml +++ b/config/clustered-databroker/kustomization.yaml @@ -1,107 +1,5 @@ namespace: pomerium resources: - ../default - - ./service - - ./pdb.yaml -patches: - - patch: |- - - op: replace - path: /kind - value: StatefulSet - - op: add - path: /spec/template/spec/containers/0/args/- - value: '--databroker-cluster-node-id=$(POD_NAME)' - - op: add - path: /spec/template/spec/containers/0/args/- - value: '--databroker-raft-bind-address=:5999' - - op: add - path: /spec/template/spec/containers/0/args/- - value: '--databroker-auto-tls=*.pomerium-headless' - - op: add - path: /spec/template/spec/containers/0/env/- - value: - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - op: add - path: /spec/template/spec/containers/0/env/- - value: - name: DATABROKER_CLUSTER_NODES - value: |- - [ - { "id": "pomerium-0", "grpc_address": "https://pomerium-0.pomerium-headless:5443", "raft_address": "pomerium-0.pomerium-headless:5999" }, - { "id": "pomerium-1", "grpc_address": "https://pomerium-1.pomerium-headless:5443", "raft_address": "pomerium-1.pomerium-headless:5999" }, - { "id": "pomerium-2", "grpc_address": "https://pomerium-2.pomerium-headless:5443", "raft_address": "pomerium-2.pomerium-headless:5999" } - ] - - op: add - path: /spec/template/spec/containers/0/ports/- - value: - name: grpc - containerPort: 5443 - protocol: TCP - - op: add - path: /spec/template/spec/containers/0/ports/- - value: - name: raft - containerPort: 5999 - protocol: TCP - - op: add - path: /spec/template/spec/containers/0/volumeMounts/- - value: - name: storage - mountPath: /var/pomerium/databroker - - op: add - path: /spec/replicas - value: 3 - - op: add - path: /spec/updateStrategy - value: - type: RollingUpdate - rollingUpdate: - maxUnavailable: 1 - - op: add - path: /spec/podManagementPolicy - value: Parallel - - op: add - path: /spec/persistentVolumeClaimRetentionPolicy - value: - whenDeleted: Delete - whenScaled: Delete - - op: add - path: /spec/serviceName - value: pomerium-headless - - op: add - path: /spec/volumeClaimTemplates - value: - - metadata: - name: storage - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - - op: replace - path: /spec/template/spec/containers/0/resources/requests/cpu - value: 500m - - op: add - path: /spec/template/spec/securityContext/fsGroup - value: 65532 - - op: add - path: /spec/template/spec/securityContext/fsGroupChangePolicy - value: OnRootMismatch - - op: add - path: /spec/template/spec/affinity - value: - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - topologyKey: kubernetes.io/hostname - labelSelector: - matchLabels: - app.kubernetes.io/name: pomerium - target: - group: apps - version: v1 - kind: Deployment - name: pomerium +components: + - ../components/databroker-cluster diff --git a/config/components/databroker-cluster/kustomization.yaml b/config/components/databroker-cluster/kustomization.yaml new file mode 100644 index 00000000..d8cdd53b --- /dev/null +++ b/config/components/databroker-cluster/kustomization.yaml @@ -0,0 +1,111 @@ +# Component: converts the all-in-one pomerium Deployment into a clustered, +# raft-backed StatefulSet with a 3-node databroker. Shared by the +# clustered-databroker and clustered-databroker-no-crd variants so the +# (large) patch is defined exactly once. +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component +resources: + - ./service + - ./pdb.yaml +patches: + - patch: |- + - op: replace + path: /kind + value: StatefulSet + - op: add + path: /spec/template/spec/containers/0/args/- + value: '--databroker-cluster-node-id=$(POD_NAME)' + - op: add + path: /spec/template/spec/containers/0/args/- + value: '--databroker-raft-bind-address=:5999' + - op: add + path: /spec/template/spec/containers/0/args/- + value: '--databroker-auto-tls=*.pomerium-headless' + - op: add + path: /spec/template/spec/containers/0/env/- + value: + name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - op: add + path: /spec/template/spec/containers/0/env/- + value: + name: DATABROKER_CLUSTER_NODES + value: |- + [ + { "id": "pomerium-0", "grpc_address": "https://pomerium-0.pomerium-headless:5443", "raft_address": "pomerium-0.pomerium-headless:5999" }, + { "id": "pomerium-1", "grpc_address": "https://pomerium-1.pomerium-headless:5443", "raft_address": "pomerium-1.pomerium-headless:5999" }, + { "id": "pomerium-2", "grpc_address": "https://pomerium-2.pomerium-headless:5443", "raft_address": "pomerium-2.pomerium-headless:5999" } + ] + - op: add + path: /spec/template/spec/containers/0/ports/- + value: + name: grpc + containerPort: 5443 + protocol: TCP + - op: add + path: /spec/template/spec/containers/0/ports/- + value: + name: raft + containerPort: 5999 + protocol: TCP + - op: add + path: /spec/template/spec/containers/0/volumeMounts/- + value: + name: storage + mountPath: /var/pomerium/databroker + - op: add + path: /spec/replicas + value: 3 + - op: add + path: /spec/updateStrategy + value: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + - op: add + path: /spec/podManagementPolicy + value: Parallel + - op: add + path: /spec/persistentVolumeClaimRetentionPolicy + value: + whenDeleted: Delete + whenScaled: Delete + - op: add + path: /spec/serviceName + value: pomerium-headless + - op: add + path: /spec/volumeClaimTemplates + value: + - metadata: + name: storage + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + - op: replace + path: /spec/template/spec/containers/0/resources/requests/cpu + value: 500m + - op: add + path: /spec/template/spec/securityContext/fsGroup + value: 65532 + - op: add + path: /spec/template/spec/securityContext/fsGroupChangePolicy + value: OnRootMismatch + - op: add + path: /spec/template/spec/affinity + value: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: kubernetes.io/hostname + labelSelector: + matchLabels: + app.kubernetes.io/name: pomerium + target: + group: apps + version: v1 + kind: Deployment + name: pomerium diff --git a/config/clustered-databroker/pdb.yaml b/config/components/databroker-cluster/pdb.yaml similarity index 100% rename from config/clustered-databroker/pdb.yaml rename to config/components/databroker-cluster/pdb.yaml diff --git a/config/clustered-databroker/service/headless.yaml b/config/components/databroker-cluster/service/headless.yaml similarity index 100% rename from config/clustered-databroker/service/headless.yaml rename to config/components/databroker-cluster/service/headless.yaml diff --git a/config/clustered-databroker/service/kustomization.yaml b/config/components/databroker-cluster/service/kustomization.yaml similarity index 100% rename from config/clustered-databroker/service/kustomization.yaml rename to config/components/databroker-cluster/service/kustomization.yaml diff --git a/config/default-no-crd/kustomization.yaml b/config/default-no-crd/kustomization.yaml new file mode 100644 index 00000000..01cc7b3f --- /dev/null +++ b/config/default-no-crd/kustomization.yaml @@ -0,0 +1,11 @@ +# Same as config/default but WITHOUT the CRD bases. Use this when the +# pomerium.ingress.pomerium.io / policyfilters.gateway.pomerium.io CRDs are +# owned by a separate installer (e.g. a dedicated ArgoCD CRD Application or a +# Terraform-managed CRD) so the controller install does not also write the +# cluster-scoped CRD object and fight over its schema. +namespace: pomerium +commonLabels: + app.kubernetes.io/name: pomerium +resources: + - ../pomerium + - ../gen_secrets From e45aef4d44cdae9e647fe08b341711a45dc1ee49 Mon Sep 17 00:00:00 2001 From: Denis Mishin Date: Wed, 17 Jun 2026 10:18:14 -0400 Subject: [PATCH 2/3] ci: sparse-checkout in CRD sync workflow Only the CRD bases are needed; avoid a full working-tree checkout. --- .github/workflows/sync-crds-to-install.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/sync-crds-to-install.yaml b/.github/workflows/sync-crds-to-install.yaml index 9da1d4be..6aba2c92 100644 --- a/.github/workflows/sync-crds-to-install.yaml +++ b/.github/workflows/sync-crds-to-install.yaml @@ -18,6 +18,8 @@ jobs: steps: - name: Checkout ingress-controller uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + with: + sparse-checkout: config/crd/bases - name: Checkout install uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 From 9af90df959c4ac99fc87a390e024c097e6205dde Mon Sep 17 00:00:00 2001 From: Denis Mishin Date: Wed, 17 Jun 2026 10:56:35 -0400 Subject: [PATCH 3/3] ci: set explicit GITHUB_TOKEN permissions on CRD sync workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit contents: read is sufficient — the cross-repo PR uses the APPARITOR PAT, not GITHUB_TOKEN. Clears the CodeQL 'workflow does not contain permissions' alert. --- .github/workflows/sync-crds-to-install.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/sync-crds-to-install.yaml b/.github/workflows/sync-crds-to-install.yaml index 6aba2c92..94928577 100644 --- a/.github/workflows/sync-crds-to-install.yaml +++ b/.github/workflows/sync-crds-to-install.yaml @@ -12,6 +12,11 @@ on: - "config/crd/bases/**" workflow_dispatch: +# Only this repo is checked out with GITHUB_TOKEN; the PR against pomerium/install +# is created with the APPARITOR_GITHUB_TOKEN PAT, so contents: read is enough here. +permissions: + contents: read + jobs: sync-crds: runs-on: ubuntu-latest