Skip to content

Architecture

Keel is a single Go binary that combines infrastructure-as-code with direct SDK calls.

                         keel.yml
                            |
                     +------+------+
                     |             |
              Infrastructure   Runtime Ops
                     |             |
              +------+------+     +------+------+
              |             |     |      |      |
           HCL Gen     OpenTofu   ECS   ECR  CloudWatch
              |             |     SDK   SDK    SDK
           .tf files   S3 State
              |        DynamoDB
           Plan/Apply   Lock

Two planes

Infrastructure provisioning (keel up, keel infra plan/apply) flows through OpenTofu. Keel generates HCL from your config, writes .tf files, and shells out to the tofu binary with an S3 backend and DynamoDB state locking. State is keyed per environment (<app>/<env>/terraform.tfstate). Credentials are passed to the subprocess via environment variables, never written to disk.

Runtime operations (keel deploy, keel logs, keel exec, keel scale) go directly through the AWS SDK — no Terraform round-trip. A deploy doesn't re-plan your VPC; it builds an image, registers a task definition, and updates a service.

The app registry

A DynamoDB table tracks all Keel app+environments across the account, so any team member can run keel apps to discover deployed applications, regardless of which machine ran keel up.

Internal layout

For contributors, the codebase splits along the same lines:

PackageResponsibility
internal/cliCobra commands — thin glue that delegates to domain packages
internal/configkeel.yml parsing, validation, defaults, environment merging
internal/authAccess levels, credential caching, IAM bootstrap, team management
internal/awsAWS SDK v2 wrappers (ECS, ECR, CloudWatch, SSM, STS)
internal/infraOpenTofu orchestration and HCL generation
internal/deployDocker/CodeBuild builds, ECS deploys, release commands, rollback
internal/projectWorkspace detection and the DynamoDB app registry
internal/tuiThe Bubbletea dashboard
internal/utilLogging, error types, terminal detection

Access control

Every privileged command declares the access level it requires (viewer, developer, or admin) and checks it before doing anything. The same levels gate actions in the dashboard, and the command palette annotates each command with the level it needs. See The Auth Model for how the levels map to IAM roles.

Keel — the AWS CLI you've always wanted.