Skip to content

AWS Deployment (EKS)

AWS Architecture

GOVERN on AWS uses the following managed services:

ServicePurposeTier
EKSKubernetes clusterRequired
RDS PostgreSQLDatabaseRequired
ElastiCache (Redis)Cache + sessionsRequired
ALBLoad balancer / ingressRequired
ACMTLS certificatesRequired
Secrets ManagerCredential storageRecommended
CloudWatchLogs and metricsRecommended
WAFWeb Application FirewallRecommended

Prerequisites

Terminal window
# Install tools
brew install awscli eksctl helm kubectl
# Configure AWS
aws configure

Create EKS Cluster

Terminal window
# Create cluster with eksctl
cat <<EOF > cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: govern-cluster
region: us-east-1
version: "1.29"
managedNodeGroups:
- name: govern-workers
instanceType: t3.xlarge
minSize: 2
maxSize: 10
desiredCapacity: 3
volumeSize: 100
iam:
attachPolicyARNs:
- arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
- arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
- arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
addons:
- name: vpc-cni
- name: coredns
- name: kube-proxy
- name: aws-ebs-csi-driver
EOF
eksctl create cluster -f cluster.yaml

Create RDS PostgreSQL

Terminal window
# Create DB subnet group
aws rds create-db-subnet-group \
--db-subnet-group-name govern-db-subnet \
--db-subnet-group-description "GOVERN database subnet" \
--subnet-ids $SUBNET_1 $SUBNET_2
# Create PostgreSQL instance
aws rds create-db-instance \
--db-instance-identifier govern-db \
--db-instance-class db.t3.medium \
--engine postgres \
--engine-version 15.4 \
--master-username govern \
--master-user-password $DB_PASSWORD \
--allocated-storage 100 \
--db-subnet-group-name govern-db-subnet \
--vpc-security-group-ids $SG_ID \
--no-publicly-accessible \
--storage-encrypted

Create ElastiCache Redis

Terminal window
aws elasticache create-replication-group \
--replication-group-id govern-redis \
--replication-group-description "GOVERN cache" \
--engine redis \
--engine-version 7.0 \
--cache-node-type cache.t3.medium \
--num-cache-clusters 2 \
--security-group-ids $SG_ID \
--subnet-group-name govern-cache-subnet

Install GOVERN

Terminal window
# Create Secrets Manager secrets
aws secretsmanager create-secret \
--name govern/api-key \
--secret-string $GOVERN_API_KEY
# Install AWS Load Balancer Controller
helm install aws-load-balancer-controller \
eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=govern-cluster
# Install GOVERN
helm install govern govern/govern \
--namespace govern \
--create-namespace \
--values values-aws.yaml

values-aws.yaml

ingress:
enabled: true
className: alb
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/certificate-arn: $ACM_CERT_ARN
observability:
cloudwatch:
enabled: true
region: us-east-1
logGroup: /govern/production

IAM Roles for Service Accounts (IRSA)

Terminal window
# Create IAM service account for Secrets Manager access
eksctl create iamserviceaccount \
--cluster govern-cluster \
--namespace govern \
--name govern-api \
--attach-policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite \
--approve