Appearance
What is Keel?
Keel gives you a platform-style workflow on your own AWS account. Describe your app in keel.yml, then use one CLI to provision infrastructure, deploy code, and operate the app.
Keel has no vendor-hosted control plane or separate account to manage. The CLI runs locally; its optional control-plane Lambda runs in your AWS account. Your team keeps control of its identities, data, infrastructure, and bill, and the resources Keel creates continue running if you stop using it.
What Keel provisions
From a single keel.yml, Keel creates and manages:
- Compute: ECS services on Fargate, Fargate Spot, or an EC2 capacity-provider fleet
- Scheduled tasks: EventBridge Scheduler running one-off ECS tasks
- Static sites: private S3 buckets served through CloudFront
- Networking: a VPC with public and private subnets, NAT, and security groups
- Load balancing: an Application Load Balancer with HTTPS
- Builds: CodeBuild pipelines using a Dockerfile or Cloud Native Buildpacks
- Container images: ECR repositories with lifecycle policies
- Databases: RDS for PostgreSQL, MySQL, and Aurora
- Caches: ElastiCache for Valkey and Redis
- DNS and TLS: Route 53 and ACM certificates
- Security: AWS WAF with managed rule sets
- Identity: optional Cognito pools for internal application users and Keel operators
- Observability: CloudWatch logs and metrics
Every managed resource is tagged with ManagedBy=keel plus the app and environment it belongs to, and each app+environment is recorded in a DynamoDB app registry so any team member can discover it with keel apps.
Networking choices
Load balancing, task placement, and outbound networking are independent settings. There is no mode preset: an enum that implied all three became misleading once different services could choose different subnets.
yaml
# Production-style defaults when omitted
load_balancer:
enabled: true
networking:
public_tasks: false
nat_gateway: single
# A service may override only its own placement
services:
image-worker:
networking:
public_tasks: trueThe inexpensive footprint sets load_balancer.enabled: false, networking.public_tasks: true, and networking.nat_gateway: none. A public subnet does not open ingress; the service security group still decides what can reach it.
How it works
Keel uses two paths depending on the operation:
- Infrastructure commands such as
keel upandkeel infra plan/applygenerate OpenTofu configuration and run it with state in S3 and locking in DynamoDB. - Runtime commands such as
keel deploy,keel logs,keel exec, andkeel scaleuse the AWS SDK directly. - The optional control plane serves cached reads and brokers narrow operator capabilities. IAM sessions fall back to the direct path; operators deliberately do not hold a direct AWS credential.
See Architecture and The Keel Control Plane for the full picture.
Next steps
- Getting Started — install, set up auth, and ship your first deploy
- Configuration — the anatomy of
keel.yml - Deploying Rails — a worked example with a web process, a worker, and migrations