Deploying to Amazon EKS
Complete guide to deploying self-hosted Spacelift Flows on Amazon EKS using OpenTofu and Helm.
This guide provides a way to quickly get Spacelift Flows up and running on an Elastic Kubernetes Service (EKS) cluster. The infrastructure is deployed using OpenTofu, and the application services are deployed using Helm charts.
Currently, agents have to run outside the Kubernetes cluster, e.g., on an EC2 Auto Scaling Group. We will soon provide a fully Kubernetes-native solution.
Overviewยป
This deployment creates a complete Spacelift Flows instance with the following components:
- EKS Auto Mode cluster for container orchestration
- RDS Aurora PostgreSQL for the database
- S3 bucket for object storage
- KMS encryption for data at rest
- ACM certificates for SSL/TLS
- Agent pool deployed via Terraform module
The following services will be deployed as Kubernetes pods using the Helm charts:
- The server.
- The worker.
- The gateway.
The server hosts the Spacelift Flows HTTP API and serves the embedded frontend assets. The server is exposed to the outside world through an Application Load Balancer for HTTP traffic, including the OAuth and MCP endpoints required for external integrations.
The worker is the component that handles recurring tasks and asynchronous jobs.
The gateway is a service that hosts the WebSocket server for agents and routes JavaScript evaluations to the right agents/runtimes.
The agent pool is deployed as an EC2 ASG and consists of an agent service. Agent services handle requests from the gateway and distribute execution commands.
Requirementsยป
Before starting, ensure you have:
AWS Prerequisitesยป
- AWS CLI configured with appropriate permissions
- Access to an AWS account with the following service limits:
- EKS clusters: At least 1 available
- RDS Aurora clusters: At least 1 available
- VPC: At least 1 available (or use existing)
- NAT Gateways: At least 1 available per AZ
- Elastic IPs: At least 1 available per NAT Gateway
Tools Requiredยป
- OpenTofu >= 1.6.0 (or Terraform >= 1.5.0)
- kubectl for Kubernetes management
- Helm >= 3.0 for application deployment
- AWS CLI >= 2.0
Domain Requirementsยป
- A registered domain name with DNS management access
- Ability to create DNS records for certificate validation
Optional Requirementsยป
- SMTP server for email notifications (recommended). You can enable Amazon SES by setting the Terraform variable
enable_ses = true. - Anthropic API key for AI features (recommended)
- OpenTelemetry collector endpoint for observability
Deploy Infrastructureยป
The infrastructure deployment uses a modular approach with OpenTofu to provision all necessary AWS resources.
1. Prepare the Environmentยป
First, ensure your AWS CLI is configured with the appropriate credentials and region:
1 2 3 4 5 | |
2. Create Working Directoryยป
Create a new directory for your infrastructure deployment:
1 2 | |
3. Create Infrastructure Configurationยป
Create a main.tf file that references the Spacelift Flows infrastructure module:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | |
See more examples with different configurations in the GitHub repository.
If you want to reuse Spacelift Self-Hosted RDS, create a Postgres database:
1 | |
We also suggest creating a separate user.
And then you should build a connection URL like this:
1 | |
4. Create Variables Fileยป
Create a variables.tf file with variable definitions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | |
5. Create Outputs Fileยป
Create an outputs.tf file to expose important values:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
6. Set Environment Variablesยป
Configure your deployment using environment variables. Start with the minimum required variables:
Choose a domain you control and can create DNS records for. Subdomains work well (e.g., flows.yourcompany.com).
1 2 3 4 5 6 7 8 9 10 | |
Flows has an incredibly powerful and helpful AI assistant, which can help you quickly build and debug Flows. The AI assistant requires an API key from Anthropic to work, and you can get it by signing up at https://console.anthropic.com/ .
While Flows will work without it, we strongly advise not skipping this.
7. Initialize OpenTofuยป
Initialize the working directory and download required providers:
1 | |
8. Review the Deployment Planยป
Generate and review the execution plan:
1 | |
9. Deploy the Infrastructureยป
Apply the configuration to create the infrastructure:
1 | |
When prompted, type yes to confirm the deployment.
10. Verify Infrastructure Deploymentยป
Once applied, you should grab all variables that need to be exported in the shell that will be used in next steps. We expose a shell output in tofu that you can source directly for convenience.
1 2 | |
11. Configure kubectl Accessยป
Configure kubectl to access your new EKS cluster:
1 2 3 4 5 | |
12. Validate the certificatesยป
You can skip this step if you already provided an issued certificate as a cert_arn variable.
After the infrastructure is deployed, you should validate that the ACM certificates are properly issued and configured:
1 2 3 4 5 | |
The certificate status should show ISSUED. If it shows PENDING_VALIDATION, you need to validate the certificate by creating the required DNS records:
1 2 | |
Create the CNAME records shown in the output in your DNS provider. The certificate will automatically be issued once DNS validation is complete (usually within a few minutes).
You can monitor the validation status:
1 2 | |
Once all domains show SUCCESS, the certificate is ready to use.
Infrastructure Deployment Completeยป
At this point, you have successfully deployed:
- โ VPC with public and private subnets
- โ EKS Auto Mode cluster ready for workloads
- โ RDS Aurora PostgreSQL database cluster
- โ S3 bucket for object storage with encryption
- โ KMS key for encryption at rest
- โ IAM roles and policies for service access
The next step is to deploy the application services using the generated Kubernetes manifests.
Deploy Application Servicesยป
1. Apply Configuration Secretยป
Create the main configuration secret:
1 | |
2. Apply Ingress Configurationยป
Create an AWS ingress class:
1 | |
For private VPC deployments: Use the internal ingress class instead:
1 | |
3. Deploy Core Servicesยป
Create helm values file for the spacelift flows installation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Install the main Spacelift Flows services using the module reference:
1 2 3 4 | |
Monitor deployment progress:
1 | |
Wait for the load balancer to be provisioned:
1 | |
4. Update DNS Recordsยป
Once the ingress has an external IP/hostname, create DNS records:
1 2 3 4 5 6 7 8 9 | |
Deploy Agent Poolยป
1. Uncomment the spacelift_flows_agent_pool moduleยป
Now that all backend services are running, uncomment the spacelift_flows_agent_pool module.
2. Run Tofu Applyยป
1 | |
Verify Deploymentยป
1. Configure SES (if using SES)ยป
If you enabled Amazon SES for email delivery (enable_ses = true), you must verify your domain in SES and either request production access or verify individual email addresses as identities before emails can be sent.
2. Access the Web Interfaceยป
Navigate to your domain in a web browser:
1 | |
You should see the Spacelift Flows login page.
3. Loginยป
On first access, you'll be prompted to provide your email to log in. If you have correctly configured your SMTP credentials, you should receive an email with a login link. Alternatively, if you have enabled email developer mode sending, you will find the login link in the logs.
Admin Password Loginยป
If you don't have SMTP configured yet, you can set an admin_password variable in the Terraform module to enable password-based login for the admin user. The password must be at least 32 characters long.
1 2 3 4 | |
Once configured, navigate to https://$SPACELIFT_FLOWS_DOMAIN/auth/admin-login to sign in using the admin email and password. This is useful for initial setup, allowing you to configure alternative login methods (such as OIDC) without needing SMTP.
4. Test Agent Poolยป
- Log into the web interface
- Navigate to the sample flows in your project and verify that they work
5. Health Checksยป
Verify all services are healthy:
1 | |
All pods should show STATUS: Running and READY: 1/1.
Configuration Optionsยป
Scaling the Deploymentยป
EKS Node Scalingยป
EKS Auto Mode handles node scaling automatically based on pod resource requests.
Resource Allocationยป
Update resource requests and limits in values files:
1 2 3 4 5 6 7 8 9 | |
Troubleshootingยป
Common Issuesยป
Pods Stuck in Pendingยป
Check node capacity and resource requests:
1 2 | |
EKS Auto Mode should automatically provision nodes, but may take 5-10 minutes.
Agent Connection Problemsยป
Check agent logs in CloudWatch Logs.
Logs and Debuggingยป
Application Logsยป
1 2 3 4 5 6 7 8 | |
Infrastructure Logsยป
1 2 | |
Maintenanceยป
Updatesยป
Application Updatesยป
Update image tags in Helm values and upgrade:
1 | |
Infrastructure Updatesยป
Update OpenTofu configuration and apply:
1 2 | |
Re-Apply Configuration Secretยป
Update the main configuration secret:
1 | |
Re-Apply Ingress Configurationยป
Update the AWS ingress class:
1 | |
Or for private VPC deployments:
1 | |
Force Restart Application Podsยป
Restart application pods without changing the deployment configuration. This is useful when you need to pick up configuration changes from Secrets, or force a fresh start of the application:
1 2 3 4 5 6 7 8 9 10 11 | |
Cleanupยป
This will permanently destroy all data. Ensure you have backups if needed.
Remove Application Servicesยป
1 2 | |
Destroy Infrastructureยป
Ensure that you have disabled RDS delete protection and S3 bucket retain on destroy:
1 2 | |
1 | |
Manual Cleanupยป
Some resources may require manual cleanup:
- ACM certificates (if DNS validation records weren't removed)
- Route53 DNS records created manually
Advanced Settingsยป
For advanced configuration options including private VPC deployment, HTTP proxy configuration, and custom CA certificates, see the Advanced Settings guide.
Next Stepsยป
Configure traces with OpenTelemetry operator.