Skip to content

CLI Commands ​

Reference for the keel CLI. Access levels are admin > developer > viewer. The badges describe the IAM-role path. When you sign in as an operator, the control plane checks the command's capability grant instead. Commands without a badge may still require AWS credentials or an operator grant.

Global flags ​

Available on every command:

FlagTypeDefaultDescription
--regionstring—AWS region override
-v, --verboseboolfalseEnable debug logging
--configstring./keel.ymlConfig file path
--envstring—Target environment (overrides KEEL_ENV and the active environment)
--no-colorboolfalseDisable color output
--cautiousboolfalsePreview and confirm every action before changing AWS state

Core ​

keel init ​

Initialize a new Keel project by creating a keel.yml in the current directory. Interactive: app name (default: directory name), region (default us-east-1), service port (default 8080), networking and load-balancer choices, pipeline source (default github) and repository. Errors if the config file already exists.

Keel also writes an annotated keel.yml.example with every supported option. It does not overwrite an existing example or read it as configuration.

keel up admin ​

Provision all infrastructure defined in keel.yml. Generates OpenTofu configuration and runs plan + apply to create the VPC, ECS cluster, ALB, ECR repositories, sites, schedules, and any add-on services. Registers the app+environment in the DynamoDB registry and (when Keel manages the CodeCommit repo) adds a git remote named keel.

New services start at zero tasks until the first image is built. keel up offers to run the initial deployment; use --deploy -y to run it without prompts.

keel deploy [service-or-site] developer ​

Deploy one service or site, or the entire application. Keel runs git preflight checks, builds with CodeBuild or --local, registers service task definitions, runs the release command, promotes services, and then publishes sites. Sites-only deployments skip container build phases; local site builds also skip git preflight. See build_in.

FlagDefaultDescription
--watchfalseStay attached and stream deployment progress
--localfalseBuild locally instead of using CodeBuild
--lock-timeout30Deploy lock timeout in minutes
--forcefalseOverride an existing deploy lock
--skip-releasefalseSkip the release command for this deploy
--release-timeout—Override release.timeout for this deploy (e.g. 20m)
--allow-dirtyfalseDeploy with uncommitted changes in the working tree
-y, --yesfalseAccept every preflight warning without prompting
--no-pushfalseNever push to the Keel-managed source repository

The release timeout must fit inside --lock-timeout.

keel deploy reconcile developer ​

Inspect incomplete deployment records against live AWS state. For each record, Keel can resume it, mark it succeeded or failed, or skip it, then release any stale deploy lock.

keel rollback [service] developer ​

Point a service to a previous task-definition revision without rebuilding or rerunning the release command.

FlagDefaultDescription
--to0Roll back to a specific task definition revision (default: the previous one)
--watchfalseStay attached and stream rollback progress
--lock-timeout30Deploy lock timeout in minutes
--forcefalseOverride an existing deploy lock

Refuses to roll back to a revision whose image has been expired from ECR.

keel status ​

Show the current status of all ECS services: running task count, health, last deployment time, and CPU/memory utilization.

keel ps ​

List running tasks with task ID, availability zone, revision, uptime, health, CPU, and memory. Per-task metrics can reveal uneven load hidden by service averages. Missing metrics appear as —. Flags: --json, --service.

keel cost ​

Estimate the monthly cost of what keel.yml describes — the provisioned baseline, priced from config alone with no AWS credentials. Usage-driven costs are listed with their rates; override assumptions with flags (--deploys 10, --build-minutes 4, --job-minutes 5, --nat-gb, --log-gb, --transfer-gb, --site-gb, --site-requests, --site-build-mb, --image-gb 5). --all covers every environment; --json for machines. See Cost Estimates & Budgets.

  • cost budget admin — create/update an AWS Budget filtered by this environment's tags. --email (required, repeatable), --limit (default: derived from the estimate), --threshold (default 80,100), --headroom (default 40), --remove
  • cost budget-show — the limit, actual spend, forecast, and alert thresholds

keel history ​

Show the deployment history for this application environment. --limit (default 20) caps the number of entries. The history is Keel's own record of what it deployed — not a view of AWS: a service updated outside Keel leaves no entry, and entries survive the environment they describe being torn down.

keel history prune admin ​

Permanently delete deployment history for this app and environment. Keel confirms with the record count; -y, --yes skips the prompt. keel destroy keeps history unless you pass --prune-history.

keel rescue admin ​

Diagnose an interrupted operation by reporting the state lock and resources absent from OpenTofu state. Repairs require explicit flags. Keel prints deletion commands for untracked resources but does not run them. See Interruptions & Rescue.

FlagDefaultDescription
--unlockfalseRelease the state lock (only when nothing holds it; always confirms)
--convergefalseRe-run the apply to finish an interrupted keel up
--finish-destroyfalseRe-run the teardown to finish an interrupted keel destroy
--delete-retainedfalseWith --finish-destroy, delete retain: true resources instead of leaving them

--converge and --finish-destroy together is an error. Within one run the order is: report → unlock → converge/finish-destroy.

keel plan ​

Preview all infrastructure changes that will be applied on the next keel up.

keel dashboard ​

Launch the interactive TUI dashboard for the selected environment. Live ECS/RDS/ElastiCache/ALB/CloudWatch/SSM state; actions are gated by your access level or operator grants inside the TUI. --direct bypasses the control plane for an IAM session. See The Dashboard.

keel destroy admin ​

Tear down all infrastructure Keel provisioned for this application. Resources declared retain: true are left running in AWS and released from Keel's state; the database is deleted after a final snapshot unless --no-final-snapshot. Confirmation requires typing the app name.

FlagDefaultDescription
--forcefalseSkip confirmation prompt
--delete-retainedfalseDelete resources declared retain: true instead of leaving them in AWS
--no-final-snapshotfalseDelete the database without taking a final snapshot
--prune-historyfalseAlso delete this environment's deployment history (irreversible)

A successful destroy also releases the deploy lock if one was held, and reports how many deployment records were kept. An interrupted destroy points at keel rescue.

keel apps ​

List all Keel applications registered in the DynamoDB app registry for the current AWS account. The registry is created by the first keel up.

keel version ​

Print the version, commit hash, and build date of the Keel binary.

keel license and keel licenses ​

keel license reports the active edition, expiry, source, and every gated capability (--json). keel licenses prints Keel's Apache-2.0 licence; --third-party prints attribution for every module linked into the binary.

keel orphans ​

List AWS resources tagged as Keel-managed that no current keel.yml declares, with their estimated cost (--json).

Runtime operations ​

keel logs [service] ​

Stream or tail CloudWatch logs for one service (default: the first service in keel.yml).

FlagDefaultDescription
-f, --followfalseStream logs in real time
--since10mHow far back to fetch logs (e.g. 10m, 1h, 2d)
--filter—CloudWatch Logs filter pattern

keel exec [service] developer ​

Open an interactive shell or run a command inside a running container via ECS Exec. -c, --command defaults to /bin/sh; --reason is recorded beside the transcript when session audit is enabled.

Keel speaks the SSM session protocol itself, so the normal path needs neither the AWS CLI nor session-manager-plugin. --legacy-session (or KEEL_LEGACY_SESSION=1) uses those external tools as an escape hatch.

keel run -- <command>... developer ​

Run a one-off command — a migration, a backfill, a console — as a new ECS task using a service's task definition, IAM role, security group, and environment.

FlagDefaultDescription
-s, --servicerelease serviceService whose task definition and role to use
-i, --interactivefalseAttach a terminal, for a console or a REPL
--timeout1hGive up and stop the task after this long
--cpu—Task CPU units for this run (e.g. 1024)
--memory—Task memory in MiB for this run (e.g. 2048)

Interactive run -i still needs the AWS CLI and session-manager-plugin; unlike keel exec, it attaches to a newly launched task through the legacy external session path.

keel scale <service> <count> developer ​

Set the ECS desired task count for a service. Scheduled tasks are not supported because EventBridge starts one task per event.

keel autoscale ​

  • autoscale show [service] — what scales each service, configured and live, with drift called out (--json). A difference usually means an apply is pending, so both halves are reported.
  • autoscale set <service> admin — write autoscaling to keel.yml; only the flags you pass change. Flags: --min, --max, --cpu, --memory, --requests, --queue, --backlog-per-task, cooldowns, and matching --no-* flags. A queue target is required for min: 0. Nothing changes in AWS until keel up — OpenTofu owns the scalable target.
  • autoscale off <service> admin — remove the service's autoscaling block

keel jobs ​

  • jobs list [service] — scheduled tasks: what's declared, what's live in EventBridge Scheduler, and when each next fires (computed locally — Scheduler doesn't report it). Drift, including a schedule pinned to a stale revision, is called out (--json)
  • jobs run <service> developer — run one firing now, using the schedule's own task definition, network config, and security group; the schedule itself is untouched (--timeout, default 15m)

keel sites ​

  • sites list [site] — configured vs live state per site: bucket, where it builds, object count, size, URL (--json). A provisioned-but-never-deployed site serves a 403, and the listing says so
  • sites deploy [site] developer — build the site where build_in says (printed before it starts), publish it, and invalidate the CDN with a single /* path. In CodeBuild the build clones the commit and uploads the files itself; locally it uploads changed files (compared by content hash) and deletes removed ones. Flags: --local, --skip-build, --no-delete, --dry-run
  • sites verify <site> admin — for domain.dns: external: read the us-east-1 certificate from ACM and record cdn.certificate_issued in keel.yml so the next apply can attach the alias

Services & environments ​

keel services ​

  • services list — list configured services with type and status
  • services add <type> — add a database or cache add-on to keel.yml (run keel up after)
  • services remove <type> — remove an add-on service

keel env ​

  • env list — list environments, regions, accounts, and the active one
  • env use <environment> — persist the active environment for this app under ~/.keel
  • env current — show the environment the current context targets
  • env add <environment> — declare a new environment in keel.yml while preserving comments. Flags: --env-region (defaults to the app region) and --account (enables account isolation). Adding the first named environment also writes the existing implicit default environment. Run keel up --env <name> to provision it.

keel db ​

Inspect the managed database. The master password is generated and rotated by AWS and stored in Secrets Manager; Keel never holds a copy. See Database Credentials.

  • db credentials (alias creds) admin — host, port, database, username, and the password masked; --show prints it
  • db url admin — one-line admin connection string (postgresql://... or mysql://...), e.g. psql "$(keel db url)"
  • db shell (aliases psql, mysql) admin — open a local database client through a Keel tunnel; the password is passed through the process environment rather than its argument list
  • db grant <iam-user> / db revoke <iam-user> admin — create or drop a per-person database role when database.iam_auth is enabled (Pro)
  • db logs — tail database engine logs from CloudWatch. Requires database.log_exports in keel.yml; Keel reports the missing setting when exports are disabled. Flags: -f/--follow, --since 10m, --filter, --type
  • db resize <instance-class> admin — write the new size to keel.yml, then review with keel plan. Never calls the AWS API directly (OpenTofu owns the size); the output names the consequences — RDS restarts the instance, single-AZ means downtime, multi-AZ fails over

keel cache ​

  • cache resize <node-type> admin — same contract as db resize; ElastiCache replaces the nodes, and cached data is lost unless a replica can fail over

The database lives in private subnets, so db shell and third-party clients use keel tunnel @database. Keel ships no database client; install psql or mysql locally.

Config variables & settings ​

keel config ​

Values are stored in SSM Parameter Store as SecureStrings at /keel/<app>/<env>/<key> and injected into ECS task definitions.

  • config set KEY=VALUE [KEY=VALUE ...]
  • config get KEY
  • config list — names/type/version only; values never printed. Also lists the AWS-managed block (e.g. @database credentials and the DATABASE_* variables it injects) so the full set of variables your containers see is in one place.
  • config unset KEY [KEY ...]

Managed variable names (DATABASE_USER, DATABASE_PASSWORD, DATABASE_CREDENTIALS) are refused by set/get/unset — they come from a secret AWS generates and rotates; read them with keel db credentials.

keel settings ​

Project-level CLI behavior, persisted in keel.yml and shared across environments.

  • settings / settings list — show all settings
  • settings get <setting> — print one value
  • settings set <setting> <true|false> — change and persist (verbose, cautious)

Resources & access ​

keel resources ​

Summarize built-in (@vpc, @cluster, @registry, @load-balancer, @logs, @pipeline, @database, @cache, @domain, @waf), managed, and linked resources with bindings, IAM capabilities, network rules, and ownership. Flags: --service, --managed, --existing, --json.

  • resources show <name> — effective bindings and rules for one resource (--json)
  • resources add <type> <name> — declare a managed s3, sns, or sqs resource. Flags: --bind SERVICE:CAP[,CAP] (repeatable), --versioning, --fifo, --visibility-timeout (default 30), --retain (default true)
  • resources link <arn-or-identifier> — link an existing resource. Flags: --as (required), --type, --url, --endpoint, --port, --security-group, --secret-arn, --secret-env, --kms-key-arn, --bind
  • resources bind <resource> <service> — grant capabilities. Flags: --access (required, comma-separated), --prefix (S3), --env
  • resources unbind <resource> <service>
  • resources remove <name> — refuses while bound (--force) or protected by retain: true

keel resources status ​

The live state of the managed database, cache, and load balancer, with metrics — the terminal view of the dashboard's Resources tab, including topology (read replicas, Aurora cluster members, cache replicas). A declared resource that doesn't exist in AWS reports NOT DEPLOYED rather than being omitted. --json.

keel access ​

  • access show <service> — the service's task role, security group, bindings, add-ons, and custom IAM (--json)
  • access explain <service> <resource> — why a service can access a resource

Domains & WAF ​

keel domains ​

A domain needs a zone, a certificate, and records; domain.dns records who owns the zone (route53 | route53-managed | external) and decides how much Keel does for you. See Custom Domains.

  • domains add <domain> admin — writes keel.yml (scoped to the environment) and nothing else; run keel up after. Looks the zone up once and records the mode; a zone that doesn't exist requires you to choose --dns route53-managed or --dns external. Flags: --zone, --zone-id, --dns, --alias (repeatable), --certificate-arn, --no-force-https
  • domains remove <domain> admin — removes it from keel.yml; the next keel up destroys the certificate and alias records. A hosted zone Keel created is never destroyed (recreating one invalidates the registrar delegation)
  • domains status (alias list) — the live state: zone, delegation checked with a real DNS query (Route 53 reports a healthy zone even when the registrar points elsewhere), certificate, and the single next thing to do (--json)
  • domains records — every record someone still has to create, in provider-form shape; empty means nothing left (--json)
  • domains verify admin — recheck end to end and, for dns: external, record an issued certificate in keel.yml so the next apply attaches the HTTPS listener. --wait polls (--timeout 15m)

keel waf ​

  • waf enable admin — default rule set AWSManagedRulesCommonRuleSet; --rules for a comma-separated list
  • waf disable admin
  • waf status

Infrastructure ​

keel infra ​

  • infra plan admin — preview infrastructure changes; --json emits OpenTofu's JSON plan schema on stdout. --keep-plan leaves the saved plan in place so the next apply is bound to it (by default the plan file is discarded when the command ends — it embeds a state snapshot including sensitive values).
  • infra apply admin — apply pending changes and converge ECS services against the resulting infrastructure. When a saved plan exists (from infra plan --keep-plan), the change set that runs is exactly the one that was displayed; otherwise a fresh apply.
  • infra output — show outputs from the last apply (ALB DNS name, ECR URLs, VPC IDs)
  • infra history — applies and destroys, including failed or interrupted operations, with actor, commit, plan summary, and resulting state (--limit, --json)
  • infra history prune admin — permanently remove this environment's apply history (-y)
  • infra unlock <LOCK_ID> admin — release a stale OpenTofu state lock left by an interrupted operation. LOCK_ID is the "ID:" field of the "Error acquiring the state lock" message. Confirms first; --yes for scripts. Only break a lock nobody holds. (keel rescue finds the lock ID and holder for you — see Interruptions & Rescue.)

Control plane and audit ​

keel api ​

  • api deploy admin — create or update the account-level control-plane Lambda, Function URL, roles, and cache
  • api status — report what is deployed and whether this client can reach it (--json)
  • api whoami — ARN, role, level, authorization path, operator label, and stable principal established by the server
  • api destroy admin — remove the control plane; direct IAM operation continues

See The Keel Control Plane.

keel audit ​

  • audit decisions — authorization decisions from the last seven days by default. Flags: --outcome allowed|denied, --who, --since-hours, and --all to include routine reads
  • audit sessions — recorded interactive sessions in this environment
  • audit transcript <stream> — print one recorded session

Decision reads use the account-scoped audit capability. Session listings and transcripts use the environment-scoped transcript capability. See Audit Records.

Operators and grants ​

keel auth idp ​

  • idp setup — create the account-level operator Cognito pool, identity pool, hosted sign-in page, and federated role (--hosted-ui-prefix; elevated key)
  • idp status — show what is provisioned
  • idp add <email> / idp remove <email> — begin or end an enrollment; removal also drops the principal's grants
  • idp suspend <email> / idp restore <email> — disable and restore access without changing grants
  • idp list — enrolled operators with principal and provider subject
  • idp export — print the one account-wide sign-in token (--json for the provider document)
  • idp login — browser sign-in (--token for first use, or --provider for the scriptable file form)
  • idp logout — remove local authentication while remembering the provider; --forget removes both
  • idp destroy — remove the operator identity provider (--force; elevated key)

keel auth grants ​

  • grants list — your rows, or the whole grid for an administrator (--json)
  • grants allow <operator> <capability> / deny — write a row scoped with --app, --env, or --platform; --reason records why
  • grants revoke <operator> <capability> — remove a row

An operator may be named by email or stable prn_… principal. See Operators for capability kinds and precedence.

Shared platforms and previews ​

keel platform ​

platform init, up, show, list, set, export, apply -f, lock, and destroy manage one shared VPC and ECS cluster. An EC2 fleet is configured with keys such as capacity.ec2.instance_types; the same cluster may host Fargate and the fleet. destroy refuses while tenants remain, even with --force.

keel preview ​

preview name, create, list, destroy, and reap manage branch-named environments synthesized from preview:. Pull-request numbers are optional metadata rather than names. Creation/listing require Pro; teardown remains available regardless of license state.

Auth & teams ​

keel auth ​

  • auth login — start a session, prompting for an MFA code. --mfa-serial overrides device discovery. Sessions last 8 hours and are not auto-renewed.
  • auth logout — clear the cached session; --purge also removes the stored access key
  • auth setup — guided one-time setup: creates the three roles, your Keel admin user, and its MFA device. --dry-run prints every policy document without touching AWS; --force skips confirmation. Needs elevated AWS credentials, held in memory only.
  • auth whoami — current identity, account, role, access level, and credential expiry
  • auth join — configure auth from an admin-issued access key. --account (required), --role (expectation only; IAM decides)
  • auth connect github <organization> admin — create the CodeConnections connection CodeBuild uses to clone from GitHub, register the account source credential, print the console authorization URL, and wait (--timeout, default 15m). Follow Connecting GitHub, especially the required App Installation selection.

keel auth mfa ​

  • mfa enroll — register an authenticator app against your Keel IAM user; the secret never leaves your machine
  • mfa status admin — enforcement per role and enrollment per member
  • mfa open admin — grant enrollment rights to existing members when migrating a team to MFA (--force)
  • mfa enforce admin — require MFA to assume any Keel role (--disable to remove, --force to skip confirmation)

keel auth team ​

  • team list viewer — list members (--all includes disabled)
  • team add <email> <role> admin — provision a member's IAM user and access key, pending MFA enrollment (--no-user for SSO-managed accounts, --force)
  • team activate <email> admin — grant access once they have enrolled exactly one MFA device
  • team reenroll <email> admin — reset a lost MFA device and reissue their key (--keep-key, --force)
  • team remove <email> admin — revoke access, delete their access keys and IAM user (--purge, --force, --allow-self)
  • team set <email> <role> admin — change a member's role, re-scoping their IAM user

Diagnostics ​

keel debug ​

  • debug logs — recent diagnostic log entries (-n lines, default 50; -f, --follow; --all)
  • debug path — print the log file path (~/.keel/logs/keel.log)
  • debug info — version, platform, and log diagnostics for bug reports

Keel — the missing platform layer for AWS.