Deploy on EKS
Start from charts/presponsievelite/values-aws.example.yaml. This is also the template for Azure and any other platform: external database, external S3-compatible storage, external OIDC.
What differs from GKE
There is no Auth Proxy equivalent, so the database connection uses a password in a DSN. Put it in the application secret as DATABASE_URL rather than in a values file.
There is no IAP equivalent, so sign-in is OIDC against your identity provider.
Signed URLs are simpler: the app presigns S3 URLs with its IRSA credentials directly, with no signBlob step.
Prerequisites
An IAM OIDC provider on the cluster, and an IRSA role for the workload scoped to the artifacts bucket:
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::acme-presponsieve-artifacts",
"arn:aws:s3:::acme-presponsieve-artifacts/*"
]
}
Values
serviceAccount:
create: true
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<ACCOUNT>:role/presponsieve-app
app:
existingSecret: presponsieve-secrets
config:
KMS_BACKEND: "k8s"
S3_PREFIX: "reports"
S3_FORCE_PATH_STYLE: "false"
postgresql:
enabled: false
externalDatabase:
url: "" # supplied through the secret as DATABASE_URL
minio:
enabled: false
externalObjectStore:
endpointUrl: ""
bucket: acme-presponsieve-artifacts
region: us-east-1
accessKeyId: "" # empty: IRSA supplies credentials
secretAccessKey: ""
keycloak:
enabled: false
oidc:
issuerUrl: https://acme.okta.com/oauth2/default
clientId: presponsieve
ingress:
enabled: true
className: alb
host: app.acme.com
annotations:
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:...
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80},{"HTTPS":443}]'
alb.ingress.kubernetes.io/ssl-redirect: "443"
alb.ingress.kubernetes.io/healthcheck-path: /healthz
tls:
enabled: false
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 5
scheme: internal is deliberate. Behavioral profiles have no reason to be reachable from the public internet; have users arrive over VPN or Direct Connect.
KMS instead of APP_KEK
KMS_BACKEND: "aws" delegates the key-encryption key to AWS KMS rather than reading APP_KEK from the secret. The IRSA role then needs kms:Encrypt, kms:Decrypt, and kms:GenerateDataKey on the key.
This is worth doing. A KMS-held KEK can be revoked centrally, and it removes the one secret whose loss is unrecoverable from your backup burden. See Encryption.
Timeouts
The ALB default idle timeout is 60 seconds, shorter than a long analysis. Raise it:
alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=600