Skip to content

NaumanMunir9/devops-eks-saas-platform-infrastructure

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DevOps EKS SaaS Platform Infrastructure

Production-grade AWS EKS platform with Helm-based service deployment, ArgoCD GitOps, KEDA autoscaling, and External Secrets Operator — for SaaS teams scaling multi-service architectures.

Problem Statement

SaaS platforms running on Kubernetes inevitably outgrow manual deployment workflows. Services multiply, each needing its own Helm chart, IRSA role, secrets, autoscaling policy, and ArgoCD application. Without a standardized pattern, every new service becomes a snowflake — different environment variable naming, inconsistent resource limits, ad-hoc secret management. The existing DevOps engineer becomes a bottleneck because only they know where everything is configured. Onboarding a second engineer takes weeks instead of hours because there's no discoverable, repeatable pattern.

Solution Overview

This repository provides a complete, opinionated infrastructure pattern for running a multi-service SaaS platform on AWS EKS. Terraform manages the foundational AWS resources (EKS, Aurora PostgreSQL, ElastiCache Redis, SQS/SNS, SES). A reusable Helm chart handles service deployment with IRSA, KEDA autoscaling, and health checks built in. ArgoCD manages GitOps delivery via an app-of-apps pattern. External Secrets Operator syncs secrets from AWS Secrets Manager into Kubernetes. SOPS + KMS encrypts any values committed to Git. GitHub Actions handles CI with OIDC auth — no static AWS credentials anywhere.

Architecture

flowchart TB
    subgraph Internet["🌐 Internet"]
        Users["👥 Users"]
        DNS["🌐 Route53"]
    end

    subgraph AWS["☁️ AWS Account"]
        subgraph VPC["🔒 VPC — Multi-AZ"]
            subgraph Public["Public Subnets"]
                ALB["⚖️ ALB / Ingress"]
            end
            subgraph Private["Private Subnets"]
                subgraph EKS["☸️ EKS Cluster"]
                    ArgoCD["🔄 ArgoCD"]
                    ESO["🔐 External Secrets Operator"]
                    KEDA["📈 KEDA"]
                    SVC1["📦 Service A"]
                    SVC2["📦 Service B"]
                    SVC3["📦 Service C"]
                end
            end
            subgraph Data["Data Subnets"]
                Aurora["🐘 Aurora PostgreSQL"]
                Redis["⚡ ElastiCache Redis"]
            end
        end
        SQS["📨 SQS Queues"]
        SNS["📢 SNS Topics"]
        SES["✉️ SES Email"]
        SM["🔑 Secrets Manager"]
        KMS["🔐 KMS"]
        S3["🗂️ S3 / TF State"]
        Lambda["⚡ Lambda"]
        ECR["📦 ECR"]
    end

    subgraph CI["⚙️ GitHub Actions"]
        Build["🔨 Build + Test"]
        Push["📦 Push to GHCR/ECR"]
    end

    Users --> DNS --> ALB --> SVC1 & SVC2 & SVC3
    ArgoCD -->|"sync"| SVC1 & SVC2 & SVC3
    ESO -->|"fetch"| SM
    KEDA -->|"scale on"| SQS
    SVC1 --> Aurora & Redis
    SVC2 --> SQS
    SVC3 --> SES
    Lambda --> SQS
    SM --> KMS
    CI --> Push -->|"OCI helm push"| ArgoCD
    S3 -->|"TF state"| VPC
Loading

Tech Stack

Layer Technology
Cloud AWS (EKS, Aurora PostgreSQL, ElastiCache Redis, SQS, SNS, SES, Lambda, S3, KMS, ACM)
IaC Terraform >= 1.6 with S3 + DynamoDB backend
Orchestration Kubernetes (EKS) with IRSA pod identity
Package Management Helm 3 with OCI registry (GHCR)
GitOps ArgoCD with app-of-apps pattern
Autoscaling KEDA (SQS queue depth, Redis list length, cron)
Secrets External Secrets Operator + AWS Secrets Manager + SOPS/KMS
CI/CD GitHub Actions with OIDC auth to AWS
DNS / Email Route53, SES with DKIM/SPF/DMARC
Scripting Bash, Node.js

Prerequisites

  • Terraform >= 1.6 installed (brew install terraform)
  • AWS CLI v2 configured (aws configure)
  • kubectl installed (brew install kubectl)
  • Helm 3 installed (brew install helm)
  • SOPS installed (brew install sops)
  • ArgoCD CLI installed (brew install argocd)
  • AWS account with permissions for EKS, RDS, ElastiCache, SQS, SNS, SES, Secrets Manager, KMS, IAM, Route53

Quick Start

git clone https://github.com/NaumanMunir9/devops-eks-saas-platform-infrastructure.git
cd devops-eks-saas-platform-infrastructure

# Check prerequisites
./scripts/prerequisites.sh

# Deploy infrastructure (staging)
cd terraform
terraform init
terraform plan -var-file=environments/staging.tfvars -out=tfplan
terraform apply tfplan

# Configure kubectl
aws eks update-kubeconfig --name saas-platform-staging --region us-east-1

# Install platform components (ArgoCD, KEDA, External Secrets Operator)
./scripts/deploy.sh staging

# Deploy a service via ArgoCD
kubectl apply -f kubernetes/argocd/app-of-apps.yaml

Detailed Deployment Steps

Step 1 — Provision AWS Infrastructure

Terraform creates the VPC, EKS cluster, Aurora PostgreSQL, ElastiCache Redis, SQS queues, SNS topics, and SES domain configuration.

cd terraform
terraform init
terraform plan -var-file=environments/staging.tfvars -out=tfplan
terraform apply tfplan

Step 2 — Configure kubectl and Verify Cluster

aws eks update-kubeconfig --name saas-platform-staging --region us-east-1
kubectl get nodes
kubectl get namespaces

Step 3 — Install Platform Components

The deploy script installs ArgoCD, KEDA, and External Secrets Operator via Helm, then configures the ClusterSecretStore.

./scripts/deploy.sh staging

Step 4 — Encrypt Secrets with SOPS

# Encrypt a values file with SOPS + KMS
export SOPS_KMS_ARN="arn:aws:kms:us-east-1:ACCOUNT_ID:key/KEY_ID"
sops --encrypt --in-place helm/platform-service/secrets.staging.yaml

Step 5 — Deploy Services via ArgoCD

# Apply the app-of-apps root application
kubectl apply -f kubernetes/argocd/app-of-apps.yaml

# Monitor sync status
argocd app list
argocd app get platform-services --refresh

Step 6 — Verify Service Health

./scripts/health-check.sh staging

Configuration Reference

Variable Description Default Required
project_name Project identifier for resource naming saas-platform Yes
environment Target environment (dev/staging/production) Yes
region AWS region us-east-1 Yes
vpc_cidr VPC CIDR block 10.0.0.0/16 No
availability_zones List of AZs ["us-east-1a", "us-east-1b", "us-east-1c"] No
eks_cluster_version Kubernetes version 1.29 No
eks_node_instance_types Node group instance types ["m6i.large"] No
eks_node_min_size Minimum nodes 2 No
eks_node_max_size Maximum nodes 10 No
aurora_instance_class Aurora instance type db.r6g.large No
aurora_engine_version PostgreSQL version 15.4 No
redis_node_type ElastiCache node type cache.r6g.large No
ses_domain SES verified domain Yes
alarm_email CloudWatch alarm destination Yes

Architecture Decisions

  • Why EKS over ECS Fargate: Multi-service SaaS platforms benefit from Kubernetes-native tooling — KEDA for event-driven autoscaling, ArgoCD for GitOps, External Secrets Operator for secret sync, RBAC for team-level access control. ECS lacks equivalents for these.
  • Why KEDA over HPA: SQS queue depth and Redis list length are the real scaling signals for async workers. HPA only supports CPU/memory natively; custom metrics require CloudWatch adapter configuration. KEDA provides first-class triggers for SQS, Redis, and cron with zero custom metrics plumbing.
  • Why External Secrets Operator over SOPS alone: SOPS encrypts secrets at rest in Git — necessary for GitOps. But ESO provides runtime sync from Secrets Manager into Kubernetes, auto-rotation, and a clean separation between encrypted-at-rest (SOPS) and live-in-cluster (ESO) secrets.
  • Why ArgoCD app-of-apps over Flux: ArgoCD provides a web UI for sync status and diff visualization. For teams with a dedicated DevOps engineer plus additional contributors, the UI reduces "what's deployed where?" questions dramatically.
  • Why Helm OCI on GHCR over ChartMuseum: GHCR is free for public repos, supports OCI artifacts natively, and integrates with GitHub Actions OIDC. No self-hosted chart registry to manage.
  • Why Aurora PostgreSQL over RDS PostgreSQL: Aurora provides 3x throughput, automatic storage scaling, fast failover (< 30s), and up to 15 read replicas. For a SaaS platform with growing data needs, Aurora's storage auto-scaling avoids capacity planning overhead.
  • Why multi-AZ with 3 subnets: EKS control plane requires subnets in at least 2 AZs. Using 3 AZs provides better fault tolerance and allows Aurora to spread replicas across zones.

Cost Estimate (Approximate — Staging)

Resource Monthly Cost
EKS control plane ~$73
EKS nodes (2× m6i.large) ~$140
Aurora PostgreSQL (db.r6g.large) ~$175
ElastiCache Redis (cache.r6g.large) ~$130
NAT Gateway (1 AZ) ~$32
ALB ~$22
SQS/SNS ~$5
Secrets Manager ~$5
S3 + CloudWatch ~$10
Total (Staging) ~$592/month

Production cost scales with node count, Aurora instances, and Redis replicas. Expect 2–3× staging for a production workload.

Cleanup

# Remove ArgoCD applications first
kubectl delete -f kubernetes/argocd/app-of-apps.yaml

# Uninstall platform components
./scripts/deploy.sh staging --uninstall

# Destroy infrastructure
cd terraform
terraform destroy -var-file=environments/staging.tfvars

Author

Nauman Munir — Senior DevOps & Cloud Engineer


Available for DevOps and Cloud Engineering engagements. Open to discussing your infrastructure challenges.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages