Skip to main content

AWS Deployment

Deploy Optimal Platform to Amazon Web Services using EKS (Elastic Kubernetes Service).

Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│ AWS REGION │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ VPC (10.0.0.0/16) │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Public │ │ Public │ │ Public │ │ │
│ │ │ Subnet AZ1 │ │ Subnet AZ2 │ │ Subnet AZ3 │ │ │
│ │ │ (NAT, ALB) │ │ (NAT, ALB) │ │ (NAT, ALB) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Private │ │ Private │ │ Private │ │ │
│ │ │ Subnet AZ1 │ │ Subnet AZ2 │ │ Subnet AZ3 │ │ │
│ │ │ (EKS Nodes)│ │ (EKS Nodes)│ │ (EKS Nodes)│ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ │ │
│ │ ┌────────────────────────────────────────────────────────────────┐ │ │
│ │ │ EKS CLUSTER │ │ │
│ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │
│ │ │ │ System Node │ │ App Node │ │ │ │
│ │ │ │ Group │ │ Group │ │ │ │
│ │ │ │ (m5.large x3) │ │ (m5.xlarge x3+) │ │ │ │
│ │ │ └─────────────────┘ └─────────────────┘ │ │ │
│ │ └────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ RDS │ │ ElastiCache │ │ S3 │ │ Route 53 │ │
│ │ PostgreSQL │ │ Redis │ │ (Backups) │ │ (DNS) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Prerequisites

  • AWS CLI configured with appropriate permissions
  • Terraform 1.5+
  • kubectl
  • Helm 3.x

Deployment Steps

1. Configure Terraform

cd infra/terraform/aws

# Copy example configuration
cp terraform.tfvars.example terraform.tfvars

Edit terraform.tfvars:

# AWS Configuration
aws_region = "us-east-1"
environment = "production"

# Cluster Configuration
cluster_name = "optimal-production"
cluster_version = "1.28"

# Networking
vpc_cidr = "10.0.0.0/16"
availability_zones = ["us-east-1a", "us-east-1b", "us-east-1c"]

# Node Groups
system_node_instance_type = "m5.large"
system_node_desired_size = 3
app_node_instance_type = "m5.xlarge"
app_node_min_size = 3
app_node_max_size = 10

# Domain (optional)
domain_name = "yourdomain.com"

2. Deploy Infrastructure

# Initialize Terraform
terraform init

# Review plan
terraform plan

# Apply (takes ~15-20 minutes)
terraform apply

3. Configure kubectl

# Update kubeconfig
aws eks update-kubeconfig \
--name optimal-production \
--region us-east-1

# Verify connection
kubectl get nodes

4. Deploy Platform

cd ../../..

# Install dependencies
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

# Deploy platform
helm upgrade --install optimal-platform k8s/helm-charts/optimal-platform \
--namespace optimal-system \
--create-namespace \
-f k8s/helm-charts/optimal-platform/values-production.yaml \
--set global.domain=yourdomain.com

5. Configure DNS

If using Route 53:

# Get Load Balancer hostname
kubectl get svc -n ingress-nginx ingress-nginx-controller \
-o jsonpath='{.status.loadBalancer.ingress[0].hostname}'

# Create DNS records in Route 53
# - portal.yourdomain.com -> ALB
# - api.yourdomain.com -> ALB
# - keycloak.yourdomain.com -> ALB

AWS Services Used

ServicePurposeConfiguration
EKSKubernetes clusterManaged control plane
EC2Worker nodesAuto-scaling groups
RDSPostgreSQL databaseMulti-AZ (optional)
ElastiCacheRedis cacheCluster mode
S3Backup storageVersioning enabled
Route 53DNS managementOptional
ACMTLS certificatesAuto-renewal
ALBLoad balancerVia ingress

Production Configuration

High Availability

# values-production.yaml
portal:
replicas: 3
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: topology.kubernetes.io/zone

apiGateway:
replicas: 3

postgresql:
architecture: replication
readReplicas:
replicaCount: 2

Autoscaling

autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilization: 70
targetMemoryUtilization: 80

Backup with S3

velero:
enabled: true
provider: aws
bucket: optimal-backups-production
region: us-east-1

Security

IAM Roles

The Terraform creates:

  • EKS cluster role
  • Node group role
  • Service account roles (IRSA)

Security Groups

  • Cluster security group (control plane)
  • Node security group (workers)
  • Database security group (RDS)

Encryption

  • EKS secrets encryption with KMS
  • RDS encryption at rest
  • S3 bucket encryption
  • EBS volume encryption

Monitoring

CloudWatch Integration

# Enable CloudWatch logging
cloudwatch:
enabled: true
logRetention: 30
logGroups:
- /aws/eks/optimal-production/cluster

Cost Optimization

  • Use Spot instances for non-critical workloads
  • Configure cluster autoscaler
  • Set resource requests/limits appropriately
  • Use S3 Intelligent-Tiering for backups

Cleanup

# Delete platform
helm uninstall optimal-platform -n optimal-system

# Delete infrastructure
cd infra/terraform/aws
terraform destroy

Troubleshooting

EKS Node Issues

# Check node status
kubectl describe node <node-name>

# View node group scaling
aws eks describe-nodegroup \
--cluster-name optimal-production \
--nodegroup-name app-nodes

RDS Connection

# Get RDS endpoint
aws rds describe-db-instances \
--query 'DBInstances[0].Endpoint.Address'

# Test from pod
kubectl exec -it <pod> -- pg_isready -h <rds-endpoint>