Skip to content

The config file

One file per environment, one cloud per file. The filename is the environment name by default: deploy/tst.yaml is the tst environment.

cloud:
provider: azure
subscription: bbbf237a-8c9e-492a-b6a3-9b0bd4869690
resource_group: evolve-tst
services:
purchase:
version: 27ec167
targets:
- { type: container-app, name: evolve-tst-purchase }

There are four top-level keys, and only two of them are usually present:

Key
cloud which cloud, and where in it required
services what to deploy required
strategy the file-wide default release strategy optional, default direct
refs policy for resolving references optional

A service is one unit of release: a single version, one or more deployables.

services:
catalog-commercetools:
version: 27ec167
targets:
- { type: container-app, name: evolve-tst-catalog-commercetools }
- { type: container-app-job, name: evolve-tst-catalog-ct-products }
- { type: container-app-job, name: evolve-tst-catalog-ct-categories }

The version lives on the service, not on the target, and that is the point: one image, five deployables, one version written once. A sync job can never drift away from the service it shares an image with.

env, envFrom, before and after are all service-level for the same reason. Hooks run once per service, not once per target — publishing a schema five times for a service with four jobs is not what anyone wants.

A target is a single deployable resource: the thing the image actually gets set on.

targets:
- type: container-app
name: evolve-tst-catalog-commercetools
- type: container-app-job
name: evolve-tst-catalog-ct-products
env:
SERVICE_ENTRYPOINT: sync-products/index.mjs

A target may add to or override the service’s env. Everything else it needs — which cluster, which package, which container — is either inherited from the service or spelled out here.

A service with exactly one target, named after the service, can skip the targets block:

services:
site:
version: abc1234
type: ecs
cluster: platform

That is exactly equivalent to:

services:
site:
version: abc1234
targets:
- { type: ecs, name: site, cluster: platform }

Set these on the service and every target that understands them picks them up. Each is inherited only by the target types it applies to, so a service with both an ECS service and a Lambda can set cluster once without the Lambda acquiring a field that means nothing to it.

Field Applies to
cluster ecs the ECS cluster name or ARN
base ecs the task definition family Terraform owns, default <name>-base
container ecs which container carries the application image
code lambda, function-app where the deployment package lives

Most tasks have one container and there is nothing to decide. When a task has several — a reverse proxy, an OpenTelemetry collector — the tool takes the one named after the target, and sidecars are never touched.

If none of them uses that conventional name, it refuses rather than guessing, and container: on the target is the answer:

targets:
- type: ecs
name: purchase
cluster: platform
container: app
cloud:
provider: azure
subscription: 00000000-0000-0000-0000-000000000000
resource_group: evolve-tst
app_config: https://evolve-tst.azconfig.io
services:
purchase:
version: abc1234
type: container-app
env:
LOG_LEVEL: info
CTP_CLIENT_SECRET: ${secret:ctp-client-secret}
before:
- hive schema:check --service purchase --commit {{.version}}
after:
- hive schema:publish --service purchase --commit {{.version}}
# One image, five deployables: the service plus its sync jobs.
discover:
version: abc1234
envFrom:
- ${param:/evolve/${env}/discover/setup}
targets:
- { type: container-app, name: evolve-tst-discover }
- { type: container-app-job, name: evolve-tst-discover-products }
- { type: container-app-job, name: evolve-tst-discover-categories }
site:
version: def5678
type: container-app
depends_on: [purchase, discover]

The complete list of every key is in the config schema reference.