Skip to main content
Infrastructure Foundation - Create the Kubernetes cluster and database infrastructure that will host your self-hosted Relvy application.

Overview

This guide walks you through setting up the infrastructure for Relvy on Kubernetes. We’ll focus on AWS EKS as the primary platform, with notes for GKE and AKS. You can also use any standard Kubernetes cluster.

What You’ll Create

Kubernetes Cluster

EKS, GKE, or AKS cluster running Kubernetes 1.20+

PostgreSQL Database

RDS, Cloud SQL, or Azure Database for PostgreSQL

Ingress Controller

AWS Load Balancer Controller or equivalent

Option 1: AWS EKS

Step 1: Create EKS Cluster

Configure aws

# Configure AWS credentials
aws configure

# Set your AWS region
aws configure set region us-east-1

1.1 Using eksctl

The fastest way to create an EKS cluster is using eksctl:
# Create cluster with eksctl
eksctl create cluster \
  --name relvy-cluster \
  --region us-east-1 \
  --nodegroup-name relvy-nodes \
  --node-type t3.xlarge \
  --nodes 3 \
  --nodes-min 1 \
  --nodes-max 5 \
  --managed
This command creates:
  • EKS cluster named relvy-cluster
  • Managed node group with 3 t3.xlarge instances (4 vCPU, 16 GB RAM each)
  • Auto-scaling between 1-5 nodes
  • New VPC with public and private subnets across multiple availability zones
VPC and Subnet Configuration - By default, eksctl creates a new VPC with both public and private subnets across multiple availability zones. If you have an existing VPC and want to use specific subnets, you can specify them with —vpc-public-subnets or —vpc-private-subnets. The ALB requires at least 2 public subnets in different availability zones.
Optional: Use existing VPC subnets
# For public subnets (at least 2 in different AZs):
eksctl create cluster \
  --name relvy-cluster \
  --region us-east-1 \
  --nodegroup-name relvy-nodes \
  --node-type t3.xlarge \
  --nodes 3 \
  --nodes-min 1 \
  --nodes-max 5 \
  --vpc-public-subnets subnet-xxx,subnet-yyy \
  --managed

# For private subnets (requires NAT Gateway or VPC endpoints):
eksctl create cluster \
  --name relvy-cluster \
  --region us-east-1 \
  --nodegroup-name relvy-nodes \
  --node-type t3.xlarge \
  --nodes 3 \
  --nodes-min 1 \
  --nodes-max 5 \
  --vpc-private-subnets subnet-xxx,subnet-yyy \
  --managed

1.2 Verify Cluster Access

# Update kubeconfig
aws eks update-kubeconfig --name relvy-cluster --region us-east-1

# Verify cluster access
kubectl get nodes

# You should see 3 nodes in Ready status

1.3 Using AWS Console (Alternative)

If you prefer the AWS Console:
  1. Navigate to EKS Console → Clusters → Create cluster
  2. Cluster Configuration:
    • Name: relvy-cluster
    • Kubernetes version: 1.28 or higher
    • Cluster service role: Create new or use existing
  3. Networking:
    • VPC: Select your VPC or create new
    • Subnets: Select at least 2 subnets in different AZs (required for ALB)
    • Security groups: Use default or custom
  4. Add-ons: Keep default (CoreDNS, kube-proxy, VPC CNI)
  5. Review and Create
After cluster creation, add a node group:
  1. Navigate to Compute → Add node group
  2. Configuration:
    • Name: relvy-nodes
    • Node IAM role: Create new or use existing
    • Instance types: t3.xlarge
    • Disk size: 30 GB
    • Scaling configuration: Min 1, Max 5, Desired 3
    • Subnets: Select the same subnets as cluster (at least 2 in different AZs)

Step 2: Install AWS Load Balancer Controller

The AWS Load Balancer Controller is required for Ingress support and automatic ALB provisioning.

2.1 Create IAM Policy

# Download IAM policy
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.7.0/docs/install/iam_policy.json

# Create IAM policy
aws iam create-policy \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document file://iam_policy.json

2.2 Create IAM Role for Service Account

# Get your AWS account ID
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)

eksctl utils associate-iam-oidc-provider --cluster=relvy-cluster --approve

# Create service account with IAM role
eksctl create iamserviceaccount \
  --cluster=relvy-cluster \
  --namespace=default \
  --name=aws-load-balancer-controller \
  --role-name AmazonEKSLoadBalancerControllerRole \
  --attach-policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/AWSLoadBalancerControllerIAMPolicy \
  --approve \
  --override-existing-serviceaccounts

2.3 Install Load Balancer Controller with Helm

# Add EKS Helm repository
helm repo add eks https://aws.github.io/eks-charts
helm repo update

# Install AWS Load Balancer Controller
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
  -n default \
  --set clusterName=relvy-cluster \
  --set serviceAccount.create=false \
  --set serviceAccount.name=aws-load-balancer-controller \
  --set region=us-east-1 \
  --set vpcId=$VPC_ID

# Verify installation
kubectl get deployment -n default aws-load-balancer-controller

Step 3: Create RDS PostgreSQL Database

3.1 Get EKS Cluster Security Group

# Get cluster security group ID
export CLUSTER_SG=$(aws eks describe-cluster \
  --name relvy-cluster \
  --query 'cluster.resourcesVpcConfig.clusterSecurityGroupId' \
  --output text)

echo "Cluster Security Group: $CLUSTER_SG"

3.2 Create Database Security Group

Option A: Using AWS CLI
# Get your VPC ID (same VPC as EKS cluster)
VPC_ID=$(aws eks describe-cluster \
  --name relvy-cluster \
  --query 'cluster.resourcesVpcConfig.vpcId' \
  --output text)

# Get EKS cluster security group ID
EKS_SG=$(aws eks describe-cluster \
  --name relvy-cluster \
  --query 'cluster.resourcesVpcConfig.clusterSecurityGroupId' \
  --output text)

# Create security group for RDS
RDS_SG_ID=$(aws ec2 create-security-group \
  --group-name relvy-db-sg \
  --description "Database security group for Relvy" \
  --vpc-id $VPC_ID \
  --output text)

# Add inbound rule to allow PostgreSQL from EKS cluster
aws ec2 authorize-security-group-ingress \
  --group-id $RDS_SG_ID \
  --protocol tcp \
  --port 5432 \
  --source-group $EKS_SG \
  --group-rule-description "Allow EKS cluster access"

# Verify the security group was created
aws ec2 describe-security-groups --group-ids $RDS_SG_ID
Option B: Using AWS Console Navigate to EC2 Console → Security Groups → Create Security Group
FieldValue
Namerelvy-db-sg
DescriptionDatabase security group for Relvy
VPC[Same VPC as EKS cluster]
Inbound Rules:
  • Type: PostgreSQL, Port: 5432, Source: [Cluster Security Group ID from Step 3.1], Description: Allow EKS cluster access

3.3 Create RDS Instance

Option A: Using AWS CLI Create the RDS instance using AWS CLI:
# Use the security group ID from step 3.2
# If you created it via CLI, use $RDS_SG_ID
# If you created it via Console, get the ID:
RDS_SG_ID=$(aws ec2 describe-security-groups \
  --filters "Name=group-name,Values=relvy-db-sg" \
  --query 'SecurityGroups[0].GroupId' \
  --output text)

# Create RDS instance with Relvy specifications
aws rds create-db-instance \
  --db-instance-identifier relvy-app-db \
  --db-instance-class db.t3.medium \
  --engine postgres \
  --engine-version 17.4 \
  --master-username postgres \
  --master-user-password your-secure-password \
  --allocated-storage 100 \
  --storage-type gp3 \
  --max-allocated-storage 200 \
  --vpc-security-group-ids $RDS_SG_ID \
  --db-name relvydb \
  --storage-encrypted \
  --deletion-protection \
  --backup-retention-period 7 \
  --no-publicly-accessible

# Wait for RDS instance to be available
aws rds wait db-instance-available --db-instance-identifier relvy-app-db
Option B: Using AWS Console (Recommended) Navigate to RDS Console → Databases → Create database Engine Options:
FieldValue
Engine typePostgreSQL
VersionPostgreSQL 17.4 (or latest)
TemplatesProduction
Settings:
FieldValue
DB instance identifierrelvy-app-db
Master usernamepostgres
Master password[Generate strong password - save this!]
Instance Configuration:
FieldValue
DB instance classdb.t3.medium (2 vCPU, 4 GB RAM)
Storage typeGeneral Purpose SSD (gp3)
Allocated storage100 GB
Storage autoscalingEnable (max 200 GB)
Connectivity:
FieldValue
VPC[Same VPC as EKS cluster]
DB subnet groupDefault or create new
Public accessNo
VPC security groupsChoose existing → relvy-db-sg
Additional Configuration:
FieldValue
Initial database namerelvydb
Backup retention period7 days
Deletion protectionEnable

Important Database Requirements

📝 Save These Values:
  • Database Password: You’ll need this for the installer
  • Database Name: Default: relvydb
  • Database User: Usually postgres

3.4 Get Database Endpoint

# Get RDS endpoint
aws rds describe-db-instances \
  --db-instance-identifier relvy-app-db \
  --query 'DBInstances[0].Endpoint.Address' \
  --output text

# 📝 Save This Value: Copy the database endpoint - you'll need it for the installer

Option 2: Google Cloud GKE

Step 1: Create GKE Cluster

# Set your project and region
export PROJECT_ID=your-project-id
export REGION=us-central1

# Create GKE cluster
gcloud container clusters create relvy-cluster \
  --region $REGION \
  --num-nodes 1 \
  --node-locations us-central1-a,us-central1-b,us-central1-c \
  --machine-type n1-standard-2 \
  --enable-autoscaling \
  --min-nodes 2 \
  --max-nodes 5 \
  --enable-autorepair \
  --enable-autoupgrade

# Get cluster credentials
gcloud container clusters get-credentials relvy-cluster --region $REGION

# Verify
kubectl get nodes

Step 2: Create Cloud SQL Instance

# Create PostgreSQL instance
gcloud sql instances create relvy-app-db \
  --database-version=POSTGRES_17 \
  --tier=db-custom-2-7680 \
  --region=$REGION \
  --root-password=your-secure-password \
  --storage-size=100GB \
  --storage-type=SSD \
  --storage-auto-increase \
  --storage-auto-increase-limit=200 \
  --backup-start-time=02:00

# Create database
gcloud sql databases create relvydb --instance=relvy-app-db

# Get connection name (you'll need this)
gcloud sql instances describe relvy-app-db --format="value(connectionName)"

Step 3: Configure Cloud SQL Proxy (for GKE)

For GKE to access Cloud SQL, you’ll need to configure the Cloud SQL Proxy or use private IP. See Google Cloud documentation for details.

Option 3: Azure AKS

Step 1: Create AKS Cluster

# Set variables
export RESOURCE_GROUP=relvy-rg
export CLUSTER_NAME=relvy-cluster
export REGION=eastus

# Create resource group
az group create --name $RESOURCE_GROUP --location $REGION

# Create AKS cluster
az aks create \
  --resource-group $RESOURCE_GROUP \
  --name $CLUSTER_NAME \
  --node-count 3 \
  --node-vm-size Standard_D2s_v3 \
  --enable-cluster-autoscaler \
  --min-count 2 \
  --max-count 5 \
  --generate-ssh-keys

# Get credentials
az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME

# Verify
kubectl get nodes

Step 2: Create Azure Database for PostgreSQL

# Create PostgreSQL server
az postgres flexible-server create \
  --resource-group $RESOURCE_GROUP \
  --name relvy-app-db \
  --location $REGION \
  --admin-user postgres \
  --admin-password your-secure-password \
  --sku-name Standard_D2s_v3 \
  --tier GeneralPurpose \
  --storage-size 128 \
  --version 17

# Create database
az postgres flexible-server db create \
  --resource-group $RESOURCE_GROUP \
  --server-name relvy-app-db \
  --database-name relvydb

# Get connection string
az postgres flexible-server show \
  --resource-group $RESOURCE_GROUP \
  --name relvy-app-db \
  --query "fullyQualifiedDomainName" \
  --output tsv

Verify Cluster Setup

Check Cluster Status

# Get nodes
kubectl get nodes

# Check system pods
kubectl get pods -n default

# Verify storage classes
kubectl get storageclass

# Check cluster info
kubectl cluster-info

Test Database Connectivity

# For AWS RDS - test from a temporary pod
kubectl run pg-test --rm -it --image=postgres:17 --namespace default -- \
  psql -h your-rds-endpoint.region.rds.amazonaws.com \
  -U postgres -d relvydb

# Enter password when prompted
# If successful, you'll see: relvydb=>
# Type \q to exit
Checkpoint - You now have a working Kubernetes cluster with database access! Save these values:
  • Cluster name and region
  • Database endpoint
  • Database password

Next Steps

Your Kubernetes cluster and database are ready! Proceed to:
  1. Configure Domain & SSL - Set up SSL certificate and DNS in Domain Configuration
  2. Deploy Relvy - Install Relvy using Helm charts in Application Deployment
I