Skip to main content
This guide takes a typical undocumented deployment — a shell script, a handful of environment variables, and a README that says which CLIs to install — and turns it into a Keel deployment. The example deploys an API to AWS ECS, but the shape is the same for any target.

Before you start

Collect three things from the person who deploys today:
  1. The tools they have installed: aws, docker, jq, a language runtime for the scripts.
  2. The commands, in order, including the login.
  3. The inputs: every environment variable or prompt, which ones are secret, which ones differ per client or environment, and where each value comes from.
1

Define the environment

Write a Dockerfile that installs the tools. Start from the vendor’s CLI image when there is one:
deploy/aws.Dockerfile
Images whose ENTRYPOINT is the CLI itself (as amazon/aws-cli is) need ENTRYPOINT [] so Keel can run a shell in them.
Pin versions. The whole point is that the deployment behaves the same on every machine, and “latest” defeats that. More patterns are in Environment images.
2

Write the steps

Keep the steps short and keep the logic in scripts that live in the repository. Make the login the first step.
keel.yaml
aws sts get-caller-identity at the end of the login step fails fast with a clear message when the credentials are wrong, before anything is built.
3

Declare the variables

One declaration per input. Give each a type, mark the secrets, and write the text a client will read.
keel.yaml
A few decisions worth making deliberately:
  • Use select for anything with a fixed set of values. A region typo is a wasted run; a dropdown is not.
  • Give safe defaults to tuning values so the form is short for the common case.
  • Put the format in validation. The form shows it as a hint, the manifest renders it, and Keel enforces it.
  • Add a manifest block to every value a client must supply, and leave it off internal switches.
4

Add outputs

If the deployment produces something people ask for afterwards, export it and declare it:
keel.yaml
5

Validate and try it

Create a target for a test account, fill in the form, and deploy. Fix the steps until the run is green. Because Keel Dev mounts your working tree, you can edit a script and deploy again without committing.
6

Hand it over

Export the manifest and send it to whoever supplies the real values:
Commit keel.yaml and deploy/. From now on the deployment is code: reviewed in pull requests, versioned with the application, and runnable by anyone with a browser.

Practices that hold up

  • Idempotent steps. A re-run after a failure should converge, not duplicate. Most cloud CLIs are idempotent by nature; scripts that create resources should check first.
  • Print progress, not secrets. Secret values are masked in logs, but derived values (a URL that embeds a token) are not unless they contain the secret verbatim. Do not echo credentials.
  • One deployment per operation. A database-migrate deployment next to aws-production is clearer than a RUN_MIGRATIONS boolean, unless the operations genuinely share a procedure — then a deploy-time select is the right tool.
  • Test the environment image in CI. A failing docker build is a failing deploy; a quick docker build -f deploy/aws.Dockerfile . in CI catches broken package pins early.