Clouds and targets
The cloud block says which cloud and where in it. It is a tagged union:
provider selects which fields apply and the rest are rejected, so the file has
the same shape whichever cloud it targets, and a leftover field from a copied
config is an error rather than something silently ignored.
provider |
Target types |
Rest of the block |
|---|---|---|
aws |
ecs, lambda |
account + region |
gcp |
cloud-run |
project + region |
azure |
container-app, container-app-job, function-app |
subscription + resource_group, optionally app_config |
kubernetes |
helm |
context + namespace |
cloud: provider: aws account: "513712104672" region: eu-west-1account is a guard, not an address. The account is implicit in the
credentials, so the tool compares this value against sts:GetCallerIdentity and
refuses on a mismatch. Everything else in the file is reviewable; without this,
where it points would not be.
Quote it. YAML will otherwise read a 12-digit account number as an integer and drop a leading zero.
services: purchase: version: abc1234 type: ecs cluster: platformECS keeps image, environment, cpu and probes in one immutable
container_definitions blob, so field-level ignore_changes is impossible.
Instead each owner gets its own task definition family: Terraform registers the
shape into <name>-base, nothing points at it, and evolve-deploy derives the
running family from it. base defaults to <name>-base and can be set
explicitly. See What Terraform must do.
lambda
Section titled “lambda”A Lambda has no registry to read a tag from, so the package location is spelled
out. {{.version}} is substituted:
targets: - type: lambda name: purchase-events code: bucket: labdigital-evolve-artifacts key: purchase-sha-{{.version}}.zipLambda is also the one place where references are read by the tool rather than handed to the platform: its environment variables are literal strings with no reference mechanism at all.
cloud: provider: gcp project: evolve-tst region: europe-west4cloud-run
Section titled “cloud-run”services: purchase: version: abc1234 type: cloud-runUpdates carry only the template field mask, so ingress, IAM, traffic split and
everything else on the service are untouched.
cloud: provider: azure subscription: 00000000-0000-0000-0000-000000000000 resource_group: evolve-tst app_config: https://evolve-tst.azconfig.io # only if you use ${param:...}Updates are a merge patch carrying only the template, which on Azure is necessity rather than tidiness: a full write-back would blank every secret, because a read never returns their values.
container-app and container-app-job
Section titled “container-app and container-app-job”services: discover: version: abc1234 targets: - { type: container-app, name: evolve-tst-discover } - { type: container-app-job, name: evolve-tst-discover-products }The reference implementation for blue-green:
the tool owns ingress.traffic, the sides are labels it writes, and every
blue-green feature works here.
Jobs carry no traffic, so in a blue-green release they ride along — their templates are written at the switch, never before it.
function-app
Section titled “function-app”services: purchase: version: abc1234 code: url: https://artifacts.blob.core.windows.net/functions/purchase/purchase-sha-{{.version}}.zip targets: - { type: function-app, name: evolve-tst-purchase-events }Deploying one is a one deploy, the only technology Flex Consumption
supports: the package is fetched from blob storage and posted to the app’s
publish endpoint. Because nothing in the app then records which package it is
running, the tool writes an EVOLVE_DEPLOY_VERSION app setting — the same
marker Lambda needs, for the same reason.
Whoever runs this needs Storage Blob Data Reader on the artifacts account: the package is fetched over the data plane, not through ARM, so the roles that let you manage the storage account are not enough to read from it.
Maturity
Section titled “Maturity”Not every driver has the same amount of road behind it. This is worth knowing before you pick one to be brave on.
| Status | |
|---|---|
| Azure Container Apps and Jobs | Exercised against a real subscription: reading, planning, the diff both ways, skipping when nothing changed, the full write, concurrency, sidecars untouched, --set |
| Azure Function Apps | Half proven — planning works against real apps, but nothing has been deployed to one yet |
| AWS (ECS, Lambda) | Built, never run against a real account |
| GCP (Cloud Run) | Built, never run against a real account |
| Kubernetes / Helm | Not built; refuses explicitly |

