add DocuSeal to GKE — manifests, Terraform, Argo CD app; update ci-base Dockerfile
This commit is contained in:
@@ -0,0 +1,68 @@
|
|||||||
|
# ── DocuSeal GKE service account and Workload Identity ───────────────────────
|
||||||
|
# DocuSeal runs in the `docuseal` namespace on GKE. It accesses GCP Secret
|
||||||
|
# Manager via Workload Identity — no JSON key files.
|
||||||
|
#
|
||||||
|
# Secret flow: Vault → GCP Secret Manager → ExternalSecret → k8s Secret → pod
|
||||||
|
|
||||||
|
resource "google_service_account" "docuseal_gke" {
|
||||||
|
account_id = "docuseal-gke"
|
||||||
|
display_name = "DocuSeal GKE"
|
||||||
|
description = "Identity for DocuSeal pod on GKE. Accesses Secret Manager via Workload Identity."
|
||||||
|
project = var.project_id
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Secret Manager access ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
resource "google_secret_manager_secret_iam_member" "docuseal_secret_key_base" {
|
||||||
|
project = var.project_id
|
||||||
|
secret_id = "docuseal-secret-key-base"
|
||||||
|
role = "roles/secretmanager.secretAccessor"
|
||||||
|
member = "serviceAccount:${google_service_account.docuseal_gke.email}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_secret_manager_secret_iam_member" "docuseal_smtp_host" {
|
||||||
|
project = var.project_id
|
||||||
|
secret_id = "docuseal-smtp-host"
|
||||||
|
role = "roles/secretmanager.secretAccessor"
|
||||||
|
member = "serviceAccount:${google_service_account.docuseal_gke.email}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_secret_manager_secret_iam_member" "docuseal_smtp_port" {
|
||||||
|
project = var.project_id
|
||||||
|
secret_id = "docuseal-smtp-port"
|
||||||
|
role = "roles/secretmanager.secretAccessor"
|
||||||
|
member = "serviceAccount:${google_service_account.docuseal_gke.email}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_secret_manager_secret_iam_member" "docuseal_smtp_username" {
|
||||||
|
project = var.project_id
|
||||||
|
secret_id = "docuseal-smtp-username"
|
||||||
|
role = "roles/secretmanager.secretAccessor"
|
||||||
|
member = "serviceAccount:${google_service_account.docuseal_gke.email}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_secret_manager_secret_iam_member" "docuseal_smtp_password" {
|
||||||
|
project = var.project_id
|
||||||
|
secret_id = "docuseal-smtp-password"
|
||||||
|
role = "roles/secretmanager.secretAccessor"
|
||||||
|
member = "serviceAccount:${google_service_account.docuseal_gke.email}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_secret_manager_secret_iam_member" "docuseal_smtp_from" {
|
||||||
|
project = var.project_id
|
||||||
|
secret_id = "docuseal-smtp-from"
|
||||||
|
role = "roles/secretmanager.secretAccessor"
|
||||||
|
member = "serviceAccount:${google_service_account.docuseal_gke.email}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Workload Identity binding ─────────────────────────────────────────────────
|
||||||
|
# The k8s SA `docuseal` in the `docuseal` namespace can impersonate this GCP SA.
|
||||||
|
# ESO uses this to authenticate to Secret Manager without a key file.
|
||||||
|
|
||||||
|
resource "google_service_account_iam_member" "docuseal_workload_identity" {
|
||||||
|
service_account_id = google_service_account.docuseal_gke.name
|
||||||
|
role = "roles/iam.workloadIdentityUser"
|
||||||
|
member = "serviceAccount:${var.project_id}.svc.id.goog[docuseal/docuseal]"
|
||||||
|
|
||||||
|
depends_on = [google_container_cluster.neuron_platform]
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: docuseal-gke
|
||||||
|
namespace: argocd
|
||||||
|
spec:
|
||||||
|
project: default
|
||||||
|
source:
|
||||||
|
repoURL: https://git.neuralplatform.ai/will/infrastructure.git
|
||||||
|
targetRevision: main
|
||||||
|
path: servers/gcp/k8s/docuseal
|
||||||
|
destination:
|
||||||
|
server: https://34.63.89.52
|
||||||
|
namespace: docuseal
|
||||||
|
ignoreDifferences:
|
||||||
|
- group: apps
|
||||||
|
kind: Deployment
|
||||||
|
jsonPointers:
|
||||||
|
- /status
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
prune: true
|
||||||
|
selfHeal: true
|
||||||
|
syncOptions:
|
||||||
|
- CreateNamespace=true
|
||||||
|
- ServerSideApply=true
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: docuseal
|
||||||
|
namespace: docuseal
|
||||||
|
labels:
|
||||||
|
app: docuseal
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
# Recreate — only one pod can hold the RWO PVC at a time.
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: docuseal
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: docuseal
|
||||||
|
spec:
|
||||||
|
serviceAccountName: docuseal
|
||||||
|
containers:
|
||||||
|
- name: docuseal
|
||||||
|
image: ee.docuseal.com/lip5viwf/ds-ee:latest
|
||||||
|
ports:
|
||||||
|
- containerPort: 3000
|
||||||
|
env:
|
||||||
|
- name: SECRET_KEY_BASE
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: docuseal-secrets
|
||||||
|
key: secret_key_base
|
||||||
|
- name: FORCE_SSL
|
||||||
|
value: "false"
|
||||||
|
- name: HOST
|
||||||
|
value: "sign.neurontechnologies.ai"
|
||||||
|
- name: SMTP_ADDRESS
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: docuseal-secrets
|
||||||
|
key: smtp_host
|
||||||
|
- name: SMTP_PORT
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: docuseal-secrets
|
||||||
|
key: smtp_port
|
||||||
|
- name: SMTP_USERNAME
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: docuseal-secrets
|
||||||
|
key: smtp_username
|
||||||
|
- name: SMTP_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: docuseal-secrets
|
||||||
|
key: smtp_password
|
||||||
|
- name: SMTP_FROM
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: docuseal-secrets
|
||||||
|
key: smtp_from
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /data
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /
|
||||||
|
port: 3000
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 10
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 256Mi
|
||||||
|
limits:
|
||||||
|
cpu: 500m
|
||||||
|
memory: 512Mi
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: docuseal-data
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: docuseal
|
||||||
|
namespace: docuseal
|
||||||
|
annotations:
|
||||||
|
# External GCP Network LB — Cloudflare proxies in front, provides TLS.
|
||||||
|
# After provisioning, get the external IP:
|
||||||
|
# kubectl -n docuseal get svc docuseal
|
||||||
|
# Update Cloudflare DNS A record for sign.neurontechnologies.ai to this IP.
|
||||||
|
cloud.google.com/load-balancer-type: "External"
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: docuseal
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
targetPort: 3000
|
||||||
|
type: LoadBalancer
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
---
|
||||||
|
# SecretStore for GKE — uses GCP Secret Manager directly via Workload Identity.
|
||||||
|
# The DocuSeal GCP SA has secretmanager.secretAccessor on its own secrets
|
||||||
|
# (see servers/gcp/docuseal.tf).
|
||||||
|
apiVersion: external-secrets.io/v1
|
||||||
|
kind: SecretStore
|
||||||
|
metadata:
|
||||||
|
name: gcp-secretmanager
|
||||||
|
namespace: docuseal
|
||||||
|
spec:
|
||||||
|
provider:
|
||||||
|
gcpsm:
|
||||||
|
projectID: neuron-785695
|
||||||
|
# Workload Identity — ESO impersonates the docuseal-gke GCP SA to access
|
||||||
|
# Secret Manager. No JSON key file required.
|
||||||
|
auth:
|
||||||
|
workloadIdentity:
|
||||||
|
clusterLocation: us-central1
|
||||||
|
clusterName: neuron-platform
|
||||||
|
serviceAccountRef:
|
||||||
|
name: docuseal
|
||||||
|
namespace: docuseal
|
||||||
|
---
|
||||||
|
# Pull all DocuSeal secrets from GCP Secret Manager into a single k8s Secret.
|
||||||
|
apiVersion: external-secrets.io/v1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: docuseal-secrets
|
||||||
|
namespace: docuseal
|
||||||
|
spec:
|
||||||
|
refreshInterval: 1h
|
||||||
|
secretStoreRef:
|
||||||
|
name: gcp-secretmanager
|
||||||
|
kind: SecretStore
|
||||||
|
target:
|
||||||
|
name: docuseal-secrets
|
||||||
|
creationPolicy: Owner
|
||||||
|
data:
|
||||||
|
- secretKey: secret_key_base
|
||||||
|
remoteRef:
|
||||||
|
key: docuseal-secret-key-base
|
||||||
|
- secretKey: smtp_host
|
||||||
|
remoteRef:
|
||||||
|
key: docuseal-smtp-host
|
||||||
|
- secretKey: smtp_port
|
||||||
|
remoteRef:
|
||||||
|
key: docuseal-smtp-port
|
||||||
|
- secretKey: smtp_username
|
||||||
|
remoteRef:
|
||||||
|
key: docuseal-smtp-username
|
||||||
|
- secretKey: smtp_password
|
||||||
|
remoteRef:
|
||||||
|
key: docuseal-smtp-password
|
||||||
|
- secretKey: smtp_from
|
||||||
|
remoteRef:
|
||||||
|
key: docuseal-smtp-from
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: docuseal
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: docuseal
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: docuseal-data
|
||||||
|
namespace: docuseal
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
|
storageClassName: standard-rwo
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: docuseal
|
||||||
|
namespace: docuseal
|
||||||
|
annotations:
|
||||||
|
# Workload Identity — allows ESO to authenticate to GCP Secret Manager
|
||||||
|
# as the docuseal-gke GCP SA without a JSON key file.
|
||||||
|
# The GCP SA binding is in servers/gcp/docuseal.tf (docuseal_workload_identity).
|
||||||
|
iam.gke.io/gcp-service-account: docuseal-gke@neuron-785695.iam.gserviceaccount.com
|
||||||
@@ -6,7 +6,7 @@ ENV DEBIAN_FRONTEND=noninteractive
|
|||||||
|
|
||||||
COPY --from=runner-bin /bin/forgejo-runner /usr/local/bin/act_runner
|
COPY --from=runner-bin /bin/forgejo-runner /usr/local/bin/act_runner
|
||||||
|
|
||||||
# Core system tools
|
# Core system tools + C build deps needed by El compiler and other CI jobs
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
curl \
|
curl \
|
||||||
@@ -27,8 +27,19 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
pkg-config \
|
pkg-config \
|
||||||
software-properties-common \
|
software-properties-common \
|
||||||
zstd \
|
zstd \
|
||||||
|
sudo \
|
||||||
|
libcurl4-openssl-dev \
|
||||||
|
libssl-dev \
|
||||||
|
libsqlite3-dev \
|
||||||
|
libpq-dev \
|
||||||
|
libffi-dev \
|
||||||
|
zlib1g-dev \
|
||||||
|
dpkg-dev \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Allow any user to run sudo without a password (CI containers need apt-get etc.)
|
||||||
|
RUN echo "ALL ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||||
|
|
||||||
# Node.js 20 LTS via binary tarball (nodesource apt repo is unreliable on Ubuntu 24.04)
|
# Node.js 20 LTS via binary tarball (nodesource apt repo is unreliable on Ubuntu 24.04)
|
||||||
RUN NODE_VERSION=20.19.1 \
|
RUN NODE_VERSION=20.19.1 \
|
||||||
&& curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" \
|
&& curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" \
|
||||||
|
|||||||
Reference in New Issue
Block a user