This example extends the simple deployment with Ory Kratos (identity management) and Ory Hydra (OAuth2/OIDC provider) for enterprise authentication via OIDC and SAML.
Everything from the simple example, plus:
- Two separate RDS instances (one for Kratos, one for Hydra): PostgreSQL 15
- Instance class: db.t3.small (suitable for Ory workloads)
- Storage: 20GB with autoscaling up to 50GB
- Network Access: Private subnets only, same VPC as the Materialize database
- Helm release: Deployed in the
orynamespace - Replicas: 2 (with PodDisruptionBudget)
- Resources: 250m CPU request / 256Mi memory (request & limit)
- Purpose: Manages user identities, login/registration flows, supports OIDC and SAML providers
- Helm release: Deployed in the
orynamespace (shared with Kratos) - Replicas: 2 (with PodDisruptionBudget)
- Resources: 250m CPU request / 256Mi memory (request & limit)
- Maester: Enabled (CRD controller for managing OAuth2 clients via Kubernetes resources)
- Purpose: Issues OAuth2 tokens, provides OIDC discovery endpoint, delegates login/consent to Kratos
Create a terraform.tfvars file:
aws_region = "us-east-1"
aws_profile = "default"
name_prefix = "mz-enterprise"
license_key = "your-materialize-license-key"
ory_issuer_url = "https://auth.example.com/"
tags = {
environment = "demo"
project = "materialize-enterprise"
}Required Variables:
aws_profile: AWS CLI profile for authenticationname_prefix: Prefix for all resource nameslicense_key: Materialize license keytags: Map of tags to apply to resourcesory_issuer_url: The public URL where Hydra's OIDC discovery will be available
Optional Variables:
aws_region: AWS region (defaults tous-east-1)k8s_apiserver_authorized_networks: List of authorized CIDR blocks for EKS API server accessingress_cidr_blocks: List of CIDR blocks allowed to reach the NLBinternal_load_balancer: Whether to use an internal load balancer (defaults totrue)enable_observability: Enable Prometheus and Grafana monitoring stack (defaults tofalse)
terraform init
terraform apply# Check Ory pods
kubectl get pods -n ory
# Check Kratos health
kubectl port-forward svc/kratos-admin 4434:4434 -n ory
curl http://localhost:4434/admin/health/ready
# Check Hydra health
kubectl port-forward svc/hydra-admin 4445:4445 -n ory
curl http://localhost:4445/admin/health/ready┌─────────────────────────────────────────────────────────────┐
│ EKS Cluster │
│ │
│ ┌──────────────┐ ┌───────────────┐ ┌──────────────────┐ │
│ │ Base Nodes │ │ Generic Nodes │ │ Materialize Nodes│ │
│ │ (Karpenter, │ │ (Karpenter) │ │ (tainted) │ │
│ │ CoreDNS) │ │ │ │ │ │
│ │ │ │ ┌───────────┐ │ │ ┌──────────────┐ │ │
│ │ │ │ │ Ory Kratos│ │ │ │ Materialize │ │ │
│ │ │ │ │ Ory Hydra │ │ │ │ Instance │ │ │
│ │ │ │ │ Operator │ │ │ └──────────────┘ │ │
│ │ │ │ └───────────┘ │ │ │ │
│ └──────────────┘ └───────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│ │ │ │
│ ┌─────┴─────┐ ┌───┴────┐ ┌────┴─────┐
│ │Kratos RDS │ │Hydra │ │ MZ RDS │
│ │(t3.small) │ │RDS │ │(t3.large)│
│ └───────────┘ │(t3.sm) │ └──────────┘
│ └────────┘
│
┌───┴───┐
│ S3 │
│Bucket │
└───────┘
- AWS RDS creates one database per instance, so Kratos and Hydra each get their own RDS instance (
db.t3.small) - Both Ory components share the
orynamespace but have separate databases - Both Ory components are scheduled on generic Karpenter nodes (not the Materialize-dedicated node pool)
- AWS RDS has PostgreSQL extensions (pg_trgm, btree_gin, uuid-ossp) available by default
- For production, configure identity schemas for Kratos and register OAuth2 clients in Hydra via the
helm_valuesoverride or Hydra Maester CRDs - Don't forget to destroy resources when finished:
terraform destroy