From e156cd10bdbb319223e53a288c49bbfdacc5ee3d Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sat, 2 May 2026 21:27:51 +1000 Subject: [PATCH] feat: deploy paperclip to au-syd1 via ArgoCD (aitooling project) (#100) Adds base manifests and au-syd1 overlay for Paperclip (AI agent orchestration platform), following the litellm deployment pattern. Updates aitooling ApplicationSet to include the paperclip path. Closes #99 Reviewed-on: https://git.unkin.net/unkin/argocd-apps/pulls/100 --- apps/base/paperclip/cnpg_cluster.yaml | 91 +++++++++++++++++++ apps/base/paperclip/cnpg_pooler.yaml | 33 +++++++ apps/base/paperclip/deployment.yaml | 85 +++++++++++++++++ apps/base/paperclip/ingress.yaml | 29 ++++++ apps/base/paperclip/kustomization.yaml | 13 +++ apps/base/paperclip/namespace.yaml | 5 + apps/base/paperclip/services.yaml | 17 ++++ apps/base/paperclip/vaultauth.yaml | 18 ++++ apps/base/paperclip/vaultstaticsecret.yaml | 34 +++++++ .../au-syd1/paperclip/kustomization.yaml | 6 ++ argocd/applicationsets/aitooling.yaml | 1 + 11 files changed, 332 insertions(+) create mode 100644 apps/base/paperclip/cnpg_cluster.yaml create mode 100644 apps/base/paperclip/cnpg_pooler.yaml create mode 100644 apps/base/paperclip/deployment.yaml create mode 100644 apps/base/paperclip/ingress.yaml create mode 100644 apps/base/paperclip/kustomization.yaml create mode 100644 apps/base/paperclip/namespace.yaml create mode 100644 apps/base/paperclip/services.yaml create mode 100644 apps/base/paperclip/vaultauth.yaml create mode 100644 apps/base/paperclip/vaultstaticsecret.yaml create mode 100644 apps/overlays/au-syd1/paperclip/kustomization.yaml diff --git a/apps/base/paperclip/cnpg_cluster.yaml b/apps/base/paperclip/cnpg_cluster.yaml new file mode 100644 index 0000000..400b970 --- /dev/null +++ b/apps/base/paperclip/cnpg_cluster.yaml @@ -0,0 +1,91 @@ +--- +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: paperclip-postgres + namespace: paperclip +spec: + affinity: + podAntiAffinityType: preferred + bootstrap: + initdb: + database: paperclip + encoding: UTF8 + localeCType: C + localeCollate: C + owner: paperclip + secret: + name: postgres-credentials + enablePDB: true + enableSuperuserAccess: false + failoverDelay: 0 + imageName: ghcr.io/cloudnative-pg/postgresql:17-minimal-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: 256MB + 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: "16" + max_replication_slots: "16" + max_worker_processes: "16" + shared_buffers: 128MB + shared_memory_type: mmap + ssl_max_protocol_version: TLSv1.3 + ssl_min_protocol_version: TLSv1.3 + wal_keep_size: 256MB + 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: 500m + memory: 512Mi + requests: + cpu: 250m + memory: 256Mi + smartShutdownTimeout: 180 + startDelay: 3600 + stopDelay: 1800 + storage: + resizeInUseVolumes: true + size: 10Gi + storageClass: cephrbd-fast-delete + switchoverDelay: 3600 diff --git a/apps/base/paperclip/cnpg_pooler.yaml b/apps/base/paperclip/cnpg_pooler.yaml new file mode 100644 index 0000000..7f2259e --- /dev/null +++ b/apps/base/paperclip/cnpg_pooler.yaml @@ -0,0 +1,33 @@ +--- +apiVersion: postgresql.cnpg.io/v1 +kind: Pooler +metadata: + name: paperclip-pooler + namespace: paperclip +spec: + cluster: + name: paperclip-postgres + instances: 2 + pgbouncer: + parameters: + default_pool_size: "100" + max_client_conn: "400" + 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/paperclip/deployment.yaml b/apps/base/paperclip/deployment.yaml new file mode 100644 index 0000000..d89db60 --- /dev/null +++ b/apps/base/paperclip/deployment.yaml @@ -0,0 +1,85 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: paperclip + namespace: paperclip +spec: + selector: + matchLabels: + app: paperclip + template: + metadata: + labels: + app: paperclip + spec: + containers: + - name: paperclip + image: ghcr.io/paperclipai/paperclip:latest + imagePullPolicy: Always + ports: + - containerPort: 3100 + name: http + protocol: TCP + env: + - name: PORT + value: "3100" + - name: PAPERCLIP_BIND + value: custom + - name: PAPERCLIP_BIND_HOST + value: 0.0.0.0 + - name: PAPERCLIP_API_URL + value: https://paperclip.k8s.syd1.au.unkin.net + - name: PAPERCLIP_HOME + value: /paperclip + - name: PAPERCLIP_INSTANCE_ID + value: default + - name: PAPERCLIP_DEPLOYMENT_MODE + value: authenticated + - name: PAPERCLIP_DEPLOYMENT_EXPOSURE + value: private + - name: SERVE_UI + value: "true" + - name: HEARTBEAT_SCHEDULER_ENABLED + value: "true" + - name: PAPERCLIP_MIGRATION_AUTO_APPLY + value: "true" + - name: PAPERCLIP_STORAGE_PROVIDER + value: s3 + - name: PAPERCLIP_STORAGE_S3_BUCKET + value: paperclip + - name: PAPERCLIP_STORAGE_S3_REGION + value: us-east-1 + - name: PAPERCLIP_STORAGE_S3_ENDPOINT + value: https://radosgw.service.consul + - name: PAPERCLIP_STORAGE_S3_FORCE_PATH_STYLE + value: "true" + envFrom: + - secretRef: + name: paperclip-credentials + livenessProbe: + httpGet: + path: / + port: 3100 + failureThreshold: 3 + initialDelaySeconds: 30 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: / + port: 3100 + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2Gi + requests: + cpu: 250m + memory: 512Mi + restartPolicy: Always diff --git a/apps/base/paperclip/ingress.yaml b/apps/base/paperclip/ingress.yaml new file mode 100644 index 0000000..0025544 --- /dev/null +++ b/apps/base/paperclip/ingress.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + kubernetes.io/ingress.class: nginx + external-dns.alpha.kubernetes.io/hostname: paperclip.k8s.syd1.au.unkin.net + external-dns.alpha.kubernetes.io/target: 198.18.200.0 + cert-manager.io/cluster-issuer: vault-issuer + cert-manager.io/common-name: paperclip.k8s.syd1.au.unkin.net + cert-manager.io/private-key-size: "4096" + name: paperclip + namespace: paperclip +spec: + rules: + - host: paperclip.k8s.syd1.au.unkin.net + http: + paths: + - backend: + service: + name: paperclip + port: + number: 3100 + path: / + pathType: Prefix + tls: + - hosts: + - paperclip.k8s.syd1.au.unkin.net + secretName: paperclip-tls diff --git a/apps/base/paperclip/kustomization.yaml b/apps/base/paperclip/kustomization.yaml new file mode 100644 index 0000000..5a7527d --- /dev/null +++ b/apps/base/paperclip/kustomization.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - cnpg_cluster.yaml + - cnpg_pooler.yaml + - deployment.yaml + - ingress.yaml + - namespace.yaml + - services.yaml + - vaultauth.yaml + - vaultstaticsecret.yaml diff --git a/apps/base/paperclip/namespace.yaml b/apps/base/paperclip/namespace.yaml new file mode 100644 index 0000000..e6e91a9 --- /dev/null +++ b/apps/base/paperclip/namespace.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: paperclip diff --git a/apps/base/paperclip/services.yaml b/apps/base/paperclip/services.yaml new file mode 100644 index 0000000..e9d9673 --- /dev/null +++ b/apps/base/paperclip/services.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: paperclip + namespace: paperclip +spec: + internalTrafficPolicy: Cluster + ports: + - name: http + port: 3100 + protocol: TCP + targetPort: http + selector: + app: paperclip + sessionAffinity: None + type: ClusterIP diff --git a/apps/base/paperclip/vaultauth.yaml b/apps/base/paperclip/vaultauth.yaml new file mode 100644 index 0000000..015d1b5 --- /dev/null +++ b/apps/base/paperclip/vaultauth.yaml @@ -0,0 +1,18 @@ +--- +apiVersion: secrets.hashicorp.com/v1beta1 +kind: VaultAuth +metadata: + name: default + namespace: paperclip +spec: + allowedNamespaces: + - paperclip + kubernetes: + audiences: + - vault + role: default + serviceAccount: default + tokenExpirationSeconds: 600 + method: kubernetes + mount: k8s/au/syd1 + vaultConnectionRef: vso-system/default diff --git a/apps/base/paperclip/vaultstaticsecret.yaml b/apps/base/paperclip/vaultstaticsecret.yaml new file mode 100644 index 0000000..603ddee --- /dev/null +++ b/apps/base/paperclip/vaultstaticsecret.yaml @@ -0,0 +1,34 @@ +--- +apiVersion: secrets.hashicorp.com/v1beta1 +kind: VaultStaticSecret +metadata: + name: postgres-credentials + namespace: paperclip +spec: + destination: + create: true + name: postgres-credentials + overwrite: true + hmacSecretData: true + mount: kv + path: kubernetes/namespace/paperclip/default/postgres-credentials + refreshAfter: 5m + type: kv-v2 + vaultAuthRef: default +--- +apiVersion: secrets.hashicorp.com/v1beta1 +kind: VaultStaticSecret +metadata: + name: paperclip-credentials + namespace: paperclip +spec: + destination: + create: true + name: paperclip-credentials + overwrite: true + hmacSecretData: true + mount: kv + path: kubernetes/namespace/paperclip/default/paperclip-credentials + refreshAfter: 5m + type: kv-v2 + vaultAuthRef: default diff --git a/apps/overlays/au-syd1/paperclip/kustomization.yaml b/apps/overlays/au-syd1/paperclip/kustomization.yaml new file mode 100644 index 0000000..a2135dc --- /dev/null +++ b/apps/overlays/au-syd1/paperclip/kustomization.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - ../../../base/paperclip diff --git a/argocd/applicationsets/aitooling.yaml b/argocd/applicationsets/aitooling.yaml index 9088bda..7d0e81b 100644 --- a/argocd/applicationsets/aitooling.yaml +++ b/argocd/applicationsets/aitooling.yaml @@ -11,6 +11,7 @@ spec: revision: HEAD directories: - path: apps/overlays/*/litellm + - path: apps/overlays/*/paperclip template: metadata: name: 'aitooling-{{path[3]}}'