Skip to content

Config Vars & Secrets

Application configuration and secrets are stored in AWS SSM Parameter Store as encrypted SecureStrings, scoped per environment (/keel/<app>/<env>/<key>), and injected into your ECS task definitions.

bash
# Set one or more variables
keel config set DATABASE_POOL_SIZE=20 LOG_LEVEL=info

# Read a value
keel config get LOG_LEVEL

# List all variables for the current environment (values are never printed)
keel config list

# Remove variables
keel config unset LOG_LEVEL

keel config list also shows the AWS-managed block — the DATABASE_* variables injected from the RDS-managed secret — so the full set of variables your containers see is in one place. Managed names are refused by set/get/unset: the password is generated and rotated by AWS, and a hand-set SSM parameter would silently compete with the injected secret for the same name. Read those values with keel db credentials instead (see Database Credentials).

To expose a variable to your containers, list its key under the service's secrets: in keel.yml and run keel up to update the task definitions:

yaml
secrets:                  # added to every service
  - SECRET_KEY_BASE
services:
  worker:
    secrets:              # or per service
      - WORKER_API_TOKEN

Because config is environment-scoped, keel config set in staging does not affect production.

Database and cache variables

The top-level database and cache add-ons give every service their network rules plus these variables:

VariableSource
DATABASE_HOST, DATABASE_PORT, DATABASE_NAMEthe instance or cluster
DATABASE_USER, DATABASE_PASSWORDindividual keys of the RDS-managed secret
DATABASE_CREDENTIALSthat secret's whole JSON value
DATABASE_SCHEMEpostgres or mysql2, matching the engine
CACHE_HOST, CACHE_PORT, CACHE_TLSthe replication group
CACHE_URL, REDIS_URLa complete rediss://host:6379 URL

DATABASE_USER and DATABASE_PASSWORD are injected as separate ECS secrets rather than only as the JSON blob, so an app can assemble a DATABASE_URL in config without shipping code to unpack a credentials document:

ruby
# config/database.yml
production:
  url: <%= "#{ENV['DATABASE_SCHEME']}://#{ENV['DATABASE_USER']}:#{ENV['DATABASE_PASSWORD']}@#{ENV['DATABASE_HOST']}:#{ENV['DATABASE_PORT']}/#{ENV['DATABASE_NAME']}" %>

The cache endpoint is TLS-only

Keel enables transit encryption, so a client that builds redis://host:6379 from CACHE_HOST and CACHE_PORT cannot connect. Use CACHE_URL / REDIS_URL, which carry the rediss:// scheme.

database.name and database.username default to keeldb and keeluser and are configurable, so adopting Keel does not require renaming an existing app's database.

Keel — the AWS CLI you've always wanted.