Skip to content

Environments ​

An app can have multiple environments, such as staging and production. Every Keel command targets one app and environment. Define environments under environments: in keel.yml; Keel merges each environment's overrides into the app-level configuration.

yaml
name: acme-api
region: us-east-1                 # app default region

environments:
  staging:
    # no account override → shares the app's account, isolated by name prefix
    services:
      web:
        desired_count: 1

  production:
    region: us-east-1
    account: "111111111111"       # opts into a separate AWS account
    services:
      web:
        desired_count: 3
        cpu: 1024
    database:
      instance: db.r6g.large

default_environment: production

If environments: is omitted, Keel operates on a single synthetic default environment.

Isolation models ​

Two isolation models are supported, selectable per environment:

  • Namespace isolation (default): Environments share an AWS account and use an <app>-<env> prefix. Because Keel roles are account-wide, environments in the same account share credentials.
  • Account isolation: Set account and, optionally, region to place an environment in another AWS account. Each account-isolated environment stores credentials under ~/.keel/contexts/<app>/<env>/ and requires keel auth setup or keel auth join in that account.

Resource names, OpenTofu state keys, SSM paths, log groups, and registry entries include the app and environment names.

How overrides merge ​

Overrides are merged field by field, so a block only has to name what differs:

SectionMerge rule
database, cache, domainfield by field; unset fields inherit the base
services.<name>field by field
services.<name>.environment, top-level environment, tagsmerged per key; the override wins
secrets (app or service)union by name; order follows the base
bindingsmerged by resource; an override replaces that one entry
permissionsappended
resourcesmerged per resource name
release, wafreplaced whole

For example, a database.instance override inherits the base block's engine, version, storage, and multi_az values. This field-level merge prevents an environment override from resetting unrelated boolean or count fields.

Selecting an environment ​

Precedence, highest first:

  1. --env <name> flag
  2. KEEL_ENV environment variable
  3. The active environment set with keel env use <name> (persisted under ~/.keel)
  4. default_environment in keel.yml
bash
keel env list                    # list environments and see which one is active
keel env use staging             # persist the active environment for this app
keel env current                 # print the environment the current context targets
keel deploy web --env production # override for a single command

Adding an environment ​

keel env add declares a new environment by editing keel.yml in place — comments and key order survive:

bash
keel env add staging
keel env add production --env-region us-east-1 --account 111111111111

When you add the first named environment, Keel also writes the existing implicit default environment and keeps it as the default, preserving the current stack name. Run keel up --env <name> to provision the new environment. You can also add an environment from the dashboard with e.

Keel — the missing platform layer for AWS.