For AWS production deployments, use the Terraform EKS module to provision infrastructure, then deploy the application with Helm. This provides better separation of concerns and security.
Quick Start: EKS + Helm
Step 1: Provision EKS Infrastructure
cd infra/aws-helm/terraform-eks
# Copy and edit configuration
cp terraform.tfvars.example terraform.tfvars
# Edit with your AWS account, VPC, and subnet details
# Deploy infrastructure
terraform init
terraform plan
terraform apply
# Configure kubectl
aws eks update-kubeconfig --region <your-region> --name <your-cluster-name>
Step 2: Deploy Application with Helm
cd ../anysource-chart
# Add required repositories
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add jetstack https://charts.jetstack.io
helm repo update
# Create secrets for external services
kubectl create secret generic anysource-db-secret \
--from-literal=password="your-rds-password" \
--namespace anysource
kubectl create secret generic anysource-redis-secret \
--from-literal=password="your-redis-password" \
--namespace anysource
# Deploy with AWS production values
# Option 1: Using chart directory
helm upgrade --install anysource . \
--namespace anysource --create-namespace \
-f values.example.yaml \
--wait --timeout=10m
# Option 2: Using packaged chart (recommended for production)
helm upgrade --install anysource ./anysource-chart-1.0.0.tgz \
--namespace anysource --create-namespace \
-f values.example.yaml \
--wait --timeout=10m
This approach provides:
- Managed Infrastructure: RDS, ElastiCache, VPC, IAM roles
- Security: IRSA, ALB with ACM certificates, private subnets
- Scalability: Auto-scaling groups, load balancing
- Monitoring: CloudWatch integration
For detailed EKS provisioning, see the EKS + Terraform deployment guide or the Terraform EKS module README.
AWS IAM Role Configuration
For AWS production deployments, you’ll need to create an IAM role with the following configuration:
Required Permissions
The role must have the following Bedrock permissions:
{
"Effect": "Allow",
"Action": [
"bedrock:CreateGuardrail",
"bedrock:GetGuardrail",
"bedrock:ListGuardrails",
"bedrock:UpdateGuardrail",
"bedrock:DeleteGuardrail",
"bedrock:ApplyGuardrail",
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": "*"
}
Trust Policy
The role must have this trust policy to allow EKS service account access:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<aws_account_id>:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/oidc_id"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-east-1.amazonaws.com/id/oidc_id:sub": "system:serviceaccount:<anysource_namespace>:anysource",
"oidc.eks.us-east-1.amazonaws.com/id/oidc_id:aud": "sts.amazonaws.com"
}
}
}
]
}
Replace:
<aws_account_id> with your AWS account ID
<oidc_id> with your EKS cluster’s OIDC provider ID
<anysource_namespace> with your deployment namespace
Set the role ARN in your values file:
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::<aws_account_id>:role/your-anysource-role"
Overview
Deploy Runlayer on Kubernetes clusters using Helm charts. This guide covers multiple deployment patterns:
- AWS EKS + Terraform (Recommended): Provision infrastructure with Terraform, deploy application with Helm
- Development: Use embedded databases for local testing
- Production: External databases with high availability
Helm Chart Location: infra/aws-helm/anysource-chart/
AWS Production Architecture
The recommended AWS production deployment separates infrastructure provisioning from application deployment. The Terraform EKS module supports three deployment modes:
- Full Stack: Create new VPC + new EKS cluster + application infrastructure
- Existing VPC: Use existing VPC + create new EKS cluster + application infrastructure
- Existing EKS: Use existing VPC + existing EKS cluster + application infrastructure only
For AWS production, first provision infrastructure with EKS Terraform
module, then deploy the application with this Helm
chart. This separation provides better security, scalability, and operational
control.
Quick Start
Step 1: Navigate to the Helm chart
cd infra/aws-helm/anysource-chart
Minimal (Recommended)
Custom Configuration
Get production-ready deployment with just 5 parameters:
# Deploy with development values
helm upgrade --install anysource . \
--namespace anysource-dev --create-namespace \
-f values-local.yaml \
--atomic --wait
# OR deploy with AWS production values (requires external RDS/ElastiCache)
helm upgrade --install anysource . \
--namespace anysource-prod --create-namespace \
-f values.example.yaml \
--atomic --wait
That’s it! You get production-ready defaults for everything else.Deployment Telemetry: The chart automatically sends deployment completion events to Sentry via Helm hooks for observability. Use --atomic --wait flags to ensure both success and failure events are captured. Telemetry gracefully degrades if SENTRY_DSN is not configured.
Ensure your Kubernetes cluster has an ingress controller and certificate management for automatic SSL certificates.
See the SSL Certificate Management guide for detailed cert-manager vs ACM configuration.
Configuration Options
Prerequisites
Kubernetes Cluster
- Kubernetes 1.19+
- Sufficient resources (4+ CPU cores, 8+ GB RAM)
- Storage class for persistent volumes
- Load balancer support (for ingress)
Required Tools
# Helm 3.8+
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
helm version
# kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl && sudo mv kubectl /usr/local/bin/
AWS Production Requirements
- EKS cluster with AWS Load Balancer Controller
- External RDS PostgreSQL and ElastiCache Redis
- AWS ACM certificate
- IAM role with Bedrock permissions and EKS OIDC trust policy
Ingress Controller (Required)
# Install AWS Load Balancer Controller for EKS
helm repo add eks https://aws.github.io/eks-charts
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
--namespace kube-system \
--set clusterName=your-cluster-name
# OR use NGINX Ingress Controller
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx --create-namespace
Cert-Manager (Optional)
# Install cert-manager for automatic SSL certificates (if not using AWS ACM)
helm repo add jetstack https://charts.jetstack.io
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager --create-namespace \
--set installCRDs=true
Deployment
1. Add Required Repositories
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add jetstack https://charts.jetstack.io
helm repo update
Copy and customize the example values file:
cp values.example.yaml values-<environment>.yaml
# Edit values-<environment>.yaml with your specific configuration
3. Deploy Runlayer
Deploy directly from the chart source:cd infra/aws-helm/anysource-chart
# With embedded databases (development)
helm upgrade --install anysource . \
--namespace anysource-dev --create-namespace \
-f values-local.yaml \
--atomic --wait
# With external AWS services (production)
helm upgrade --install anysource . \
--namespace anysource --create-namespace \
-f values.example.yaml \
--atomic --wait
Best for local development and testing chart changes.
Deployment takes 5-10 minutes. SSL certificate provisioning may add 2-5
minutes.
4. Verify
# Check deployment status
kubectl get pods -n anysource
kubectl get ingress -n anysource
kubectl get hpa -n anysource
# View logs
kubectl logs -f deployment/anysource-backend -n anysource
kubectl logs -f deployment/anysource-frontend -n anysource
# Check events
kubectl get events -n anysource --sort-by='.lastTimestamp'
Configuration
Copy values.example.yaml to create your environment-specific values file:
cp values.example.yaml values-<environment>.yaml
Required Configuration
Set these values in your values file:
global:
domain: "your-domain.com"
auth_client_id: "your-auth-client-id"
backend:
secrets:
SECRET_KEY: "your-jwt-secret-key-minimum-32-characters"
MASTER_SALT: "your-master-salt-minimum-32-characters"
AUTH_API_KEY: "your-auth-api-key"
Database Configuration
Embedded PostgreSQL (Development):
postgresql:
enabled: true
External RDS (Production):
postgresql:
enabled: false
externalDatabase:
enabled: true
host: "your-rds-endpoint"
existingSecret: "anysource-db-secret"
Certificate Management
AWS ACM (Recommended for AWS):
awsCertificate:
enabled: true
arn: "arn:aws:acm:region:account:certificate/cert-id"
certManager:
enabled: false
Let’s Encrypt (Non-AWS Deployment):
certManager:
enabled: true
issuer:
email: "[email protected]"
awsCertificate:
enabled: false
Architecture
Commands
Install/Upgrade
Deploy directly from the chart directory:cd infra/aws-helm/anysource-chart
helm upgrade --install anysource . \
--namespace anysource --create-namespace \
-f values-<environment>.yaml \
--atomic --wait
Use this when developing or testing chart changes locally.
Uninstall
helm uninstall anysource -n anysource
kubectl delete namespace anysource
Debug
# Debug with chart directory
helm template anysource . -f values-<environment>.yaml --debug --validate=false
# Debug with packaged chart
helm template anysource ./anysource-chart-1.0.0.tgz \
-f values-<environment>.yaml --debug --validate=false
Deployment Telemetry
The Helm chart automatically reports deployment status to Sentry via Helm hooks for observability and debugging.
How It Works
The chart includes Helm hook Jobs that run automatically after each deployment:
- post-upgrade hook: Sends success event after successful deployment
- post-rollback hook: Sends failure event if deployment fails (triggered by
--atomic flag)
Telemetry is enabled by default and gracefully degrades if SENTRY_DSN is not configured.
Key Features
- Automatic: No wrapper scripts needed - hooks run on every
helm upgrade
- Secure: SENTRY_DSN only exposed to short-lived hook Jobs, not long-running pods
- Reliable: Exactly one event per deployment outcome (no duplicates on pod restarts)
- Non-blocking: Telemetry failures don’t impact deployment success
Configuration
Telemetry settings are read from your values file:
global:
domain: "acme-corp.runlayer.com" # Used as customer_id
environment: "production" # Environment tag
deployment:
infraVersion: "2.1.0" # Infrastructure version for tracking
backend:
secrets:
SENTRY_DSN: "https://[email protected]/project" # Required for telemetry
telemetry:
enabled: true # Enable/disable telemetry hooks (default: true)
What Gets Reported
Each deployment event includes:
- Deployment status (success/failure)
- Customer ID (from
global.domain)
- Infrastructure version (from
global.deployment.infraVersion)
- Environment (from
global.environment)
- Deployment duration and timestamp
- Operator and hostname metadata
Disabling Telemetry
To disable telemetry hooks, set in your values file:
telemetry:
enabled: false
Advanced: Pre-Deployment Diff Telemetry
For pre-deployment diff capture (optional), use the wrapper script:
cd infra/aws-helm/anysource-chart
# Enable pre-deployment diff telemetry
DEPLOY_TELEMETRY_DIFF=true \
./files/deploy-helm-with-telemetry.sh auto auto -f values-production.yaml
This wrapper sends an additional event with Helm diff output before deployment.
Recommended: Always use --atomic --wait flags with helm upgrade to ensure:
- Deployments roll back automatically on failure
- The post-rollback hook captures failure telemetry
- Kubernetes waits for pods to be ready before marking success
Troubleshooting
Check Status
kubectl get pods -n anysource
kubectl get ingress -n anysource
kubectl get hpa -n anysource
View Logs
kubectl logs -f deployment/anysource-backend -n anysource
kubectl logs -f deployment/anysource-frontend -n anysource
Check Events
kubectl get events -n anysource --sort-by='.lastTimestamp'
Support
For issues and questions, contact the Runlayer team at [email protected]
Next Steps