From dbd8914013c357357f32c0f0dcd3706922a20f11 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Tue, 3 Mar 2026 22:24:17 +1100 Subject: [PATCH] feat: migrate woodpecker to argocd (#13) - move woodpecker helm chart deployment to argocd - move cnpg resources - move vault resources Reviewed-on: https://git.unkin.net/unkin/argocd-apps/pulls/13 --- apps/base/woodpecker/cnpg_cluster.yaml | 92 +++++++++++++++++++ apps/base/woodpecker/cnpg_pooler.yaml | 34 +++++++ apps/base/woodpecker/kustomization.yaml | 10 ++ apps/base/woodpecker/namespace.yaml | 5 + apps/base/woodpecker/vaultauth.yaml | 18 ++++ apps/base/woodpecker/vaultstaticsecret.yaml | 17 ++++ .../au-syd1/woodpecker/kustomization.yaml | 14 +++ apps/overlays/au-syd1/woodpecker/values.yaml | 56 +++++++++++ argocd/applicationsets/platform.yaml | 1 + argocd/projects/platform.yaml | 3 + 10 files changed, 250 insertions(+) create mode 100644 apps/base/woodpecker/cnpg_cluster.yaml create mode 100644 apps/base/woodpecker/cnpg_pooler.yaml create mode 100644 apps/base/woodpecker/kustomization.yaml create mode 100644 apps/base/woodpecker/namespace.yaml create mode 100644 apps/base/woodpecker/vaultauth.yaml create mode 100644 apps/base/woodpecker/vaultstaticsecret.yaml create mode 100644 apps/overlays/au-syd1/woodpecker/kustomization.yaml create mode 100644 apps/overlays/au-syd1/woodpecker/values.yaml diff --git a/apps/base/woodpecker/cnpg_cluster.yaml b/apps/base/woodpecker/cnpg_cluster.yaml new file mode 100644 index 0000000..254bd7c --- /dev/null +++ b/apps/base/woodpecker/cnpg_cluster.yaml @@ -0,0 +1,92 @@ +--- +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: woodpecker-postgres + namespace: woodpecker +spec: + affinity: + podAntiAffinityType: preferred + bootstrap: + initdb: + database: woodpecker + encoding: UTF8 + localeCType: C + localeCollate: C + owner: woodpecker + secret: + name: woodpecker-postgres-credentials + enablePDB: true + enableSuperuserAccess: false + failoverDelay: 0 + imageName: ghcr.io/cloudnative-pg/postgresql:18.1-system-trixie + instances: 3 + logLevel: info + maxSyncReplicas: 0 + minSyncReplicas: 0 + monitoring: + customQueriesConfigMap: + - key: queries + name: cnpg-default-monitoring + disableDefaultQueries: false + enablePodMonitor: false + postgresql: + parameters: + archive_mode: "on" + archive_timeout: 5min + dynamic_shared_memory_type: posix + effective_cache_size: 512MB + full_page_writes: "on" + log_destination: csvlog + log_directory: /controller/log + log_filename: postgres + log_rotation_age: "0" + log_rotation_size: "0" + log_truncate_on_rotation: "false" + logging_collector: "on" + max_connections: "200" + max_parallel_workers: "32" + max_replication_slots: "32" + max_worker_processes: "32" + shared_buffers: 128MB + shared_memory_type: mmap + shared_preload_libraries: "" + ssl_max_protocol_version: TLSv1.3 + ssl_min_protocol_version: TLSv1.3 + wal_keep_size: 512MB + wal_level: logical + wal_log_hints: "on" + wal_receiver_timeout: 5s + wal_sender_timeout: 5s + syncReplicaElectionConstraint: + enabled: false + primaryUpdateMethod: restart + primaryUpdateStrategy: unsupervised + probes: + liveness: + isolationCheck: + connectionTimeout: 1000 + enabled: true + requestTimeout: 1000 + replicationSlots: + highAvailability: + enabled: true + slotPrefix: _cnpg_ + synchronizeReplicas: + enabled: true + updateInterval: 30 + resources: + limits: + cpu: "1" + memory: 1Gi + requests: + cpu: 50m + memory: 128Mi + smartShutdownTimeout: 180 + startDelay: 3600 + stopDelay: 1800 + storage: + resizeInUseVolumes: true + size: 20Gi + storageClass: cephrbd-fast-delete + switchoverDelay: 3600 diff --git a/apps/base/woodpecker/cnpg_pooler.yaml b/apps/base/woodpecker/cnpg_pooler.yaml new file mode 100644 index 0000000..7934e76 --- /dev/null +++ b/apps/base/woodpecker/cnpg_pooler.yaml @@ -0,0 +1,34 @@ +--- +apiVersion: postgresql.cnpg.io/v1 +kind: Pooler +metadata: + name: woodpecker-postgres-pooler + namespace: woodpecker + resourceVersion: "136690873" +spec: + cluster: + name: woodpecker-postgres + instances: 2 + pgbouncer: + parameters: + default_pool_size: "20" + max_client_conn: "100" + paused: false + poolMode: session + template: + metadata: + labels: + app: pooler + spec: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - pooler + topologyKey: kubernetes.io/hostname + containers: [] + type: rw diff --git a/apps/base/woodpecker/kustomization.yaml b/apps/base/woodpecker/kustomization.yaml new file mode 100644 index 0000000..be1bb41 --- /dev/null +++ b/apps/base/woodpecker/kustomization.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - namespace.yaml + - cnpg_cluster.yaml + - cnpg_pooler.yaml + - vaultauth.yaml + - vaultstaticsecret.yaml diff --git a/apps/base/woodpecker/namespace.yaml b/apps/base/woodpecker/namespace.yaml new file mode 100644 index 0000000..3c08baf --- /dev/null +++ b/apps/base/woodpecker/namespace.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: woodpecker diff --git a/apps/base/woodpecker/vaultauth.yaml b/apps/base/woodpecker/vaultauth.yaml new file mode 100644 index 0000000..d14cf54 --- /dev/null +++ b/apps/base/woodpecker/vaultauth.yaml @@ -0,0 +1,18 @@ +--- +apiVersion: secrets.hashicorp.com/v1beta1 +kind: VaultAuth +metadata: + name: default + namespace: woodpecker +spec: + allowedNamespaces: + - woodpecker + kubernetes: + audiences: + - vault + role: woodpecker + serviceAccount: default + tokenExpirationSeconds: 600 + method: kubernetes + mount: k8s/au/syd1 + vaultConnectionRef: vso-system/default diff --git a/apps/base/woodpecker/vaultstaticsecret.yaml b/apps/base/woodpecker/vaultstaticsecret.yaml new file mode 100644 index 0000000..763dd74 --- /dev/null +++ b/apps/base/woodpecker/vaultstaticsecret.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: secrets.hashicorp.com/v1beta1 +kind: VaultStaticSecret +metadata: + name: woodpecker-gitea + namespace: woodpecker +spec: + destination: + create: true + name: woodpecker-gitea + overwrite: false + hmacSecretData: true + mount: kv + path: service/woodpecker/woodpecker-gitea + refreshAfter: 5m + type: kv-v2 + vaultAuthRef: default diff --git a/apps/overlays/au-syd1/woodpecker/kustomization.yaml b/apps/overlays/au-syd1/woodpecker/kustomization.yaml new file mode 100644 index 0000000..c9e8a9d --- /dev/null +++ b/apps/overlays/au-syd1/woodpecker/kustomization.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - ../../../base/woodpecker + +helmCharts: + - name: woodpecker + repo: oci://ghcr.io/woodpecker-ci/helm + version: "3.5.1" + releaseName: woodpecker + namespace: woodpecker + valuesFile: values.yaml diff --git a/apps/overlays/au-syd1/woodpecker/values.yaml b/apps/overlays/au-syd1/woodpecker/values.yaml new file mode 100644 index 0000000..dc20102 --- /dev/null +++ b/apps/overlays/au-syd1/woodpecker/values.yaml @@ -0,0 +1,56 @@ +agent: + replicaCount: 1 + env: + WOODPECKER_MAX_WORKFLOWS: 8 + WOODPECKER_BACKEND_K8S_STORAGE_CLASS: cephrbd-fast-delete + WOODPECKER_BACKEND_K8S_VOLUME_SIZE: 10G + WOODPECKER_BACKEND_K8S_STORAGE_RWX: false + WOODPECKER_LOG_LEVEL: debug + #extraSecretNamesForEnvFrom: + # - woodpecker-default-agent-secret + persistence: + storageClass: cephrbd-fast-delete + resources: + requests: + cpu: 100m + limits: + memory: 128Mi + +server: + statefulSet: + replicaCount: 1 + env: + WOODPECKER_HOST: 'https://ci.k8s.syd1.au.unkin.net' + WOODPECKER_OPEN: "true" + WOODPECKER_DISABLE_USER_AGENT_REGISTRATION: "true" + WOODPECKER_PLUGINS_PRIVILEGED: "woodpeckerci/plugin-docker-buildx:latest-insecure" + extraSecretNamesForEnvFrom: + - woodpecker-gitea + - woodpecker-postgres-credentials + - woodpecker-database-config + persistentVolume: + storageClass: cephrbd-fast-delete + ingress: + enabled: true + annotations: + cert-manager.io/cluster-issuer: vault-issuer + cert-manager.io/common-name: ci.k8s.syd1.au.unkin.net + cert-manager.io/private-key-size: "4096" + external-dns.alpha.kubernetes.io/hostname: ci.k8s.syd1.au.unkin.net + external-dns.alpha.kubernetes.io/target: 198.18.200.0 + ingressClassName: nginx + hosts: + - host: ci.k8s.syd1.au.unkin.net + paths: + - path: / + backend: + servicePort: 80 + tls: + - hosts: + - ci.k8s.syd1.au.unkin.net + secretName: ci-tls + resources: + requests: + cpu: 100m + limits: + memory: 128Mi diff --git a/argocd/applicationsets/platform.yaml b/argocd/applicationsets/platform.yaml index c99eee7..10cfb31 100644 --- a/argocd/applicationsets/platform.yaml +++ b/argocd/applicationsets/platform.yaml @@ -13,6 +13,7 @@ spec: - path: apps/overlays/*/reflector-system - path: apps/overlays/*/reloader-system - path: apps/overlays/*/jfrog + - path: apps/overlays/*/woodpecker template: metadata: name: 'platform-{{path[3]}}' # cluster-app format (e.g., platform-reflector-system) diff --git a/argocd/projects/platform.yaml b/argocd/projects/platform.yaml index 2ec90e2..73a9510 100644 --- a/argocd/projects/platform.yaml +++ b/argocd/projects/platform.yaml @@ -9,11 +9,14 @@ spec: sourceRepos: - https://git.unkin.net/unkin/argocd-apps - oci://ghcr.io/emberstack/helm-charts + - oci://ghcr.io/woodpecker-ci/helm/woodpecker destinations: - namespace: '*-system' server: https://kubernetes.default.svc - namespace: 'jfrog' server: https://kubernetes.default.svc + - namespace: 'woodpecker' + server: https://kubernetes.default.svc clusterResourceWhitelist: - group: '' kind: Namespace