Environments
An application runs in more than one place: on a developer’s machine, in a test pipeline, in staging, in production. Those places differ in almost everything except the application itself. They have different databases, different domain names, different secrets, and different amounts of hardware.
Toa keeps the application constant and concentrates the differences in one declaration. An environment is a named set of answers to the questions a deployment has to settle.
§One source
The components do not change between environments. This follows from what they are allowed to contain: an operation has no address, credential, or hostname in it, so there is nothing in it to vary.
Everything that does vary is declared in the Context, and the Context is a single file read for a named environment.
§Variation by suffix
Any value in the Context can be given per environment with an @ suffix:
# context.toa.yaml
mongodb@local: mongodb://localhost
mongodb@production: mongodb://db.internal.example.com
exposition:
authorities:
main@local: localhost:8000
main@production: api.example.com
configuration:
orders:
limit: 10000
limit@staging: 100 A key without a suffix applies everywhere. A key with one applies in that environment and takes precedence there. The whole description of every environment is visible in one place, and the difference between two of them is exactly the set of suffixed keys.
The mechanism is uniform. Infrastructure addresses, extension settings, component configuration, and deployment shape are all varied the same way, because they are all values in the same document.
§What an environment can change
Where things are. The addresses of the database, the broker, the cache, and external services.
How the application is configured. Any configuration value, and which secrets are supplied.
How it is shaped. Compositions, replica counts, and resources. A production deployment may run ten compositions with several replicas each, while a developer runs everything in one process.
What is included. An environment can leave out components or services that are run by other means there.
What an environment cannot change is behavior. There is no way to give an operation a different implementation in staging.
§Derived environments
Environments are often nearly alike. Staging is production with a few differences. An environment can be read as a chain, where each value comes from the first environment in the chain that defines it. Staging then declares only what distinguishes it and inherits the rest.
§The local environment
Development is an environment like the others, with one notable property: its shape is usually the most compact one. The whole application — every component and every service the platform provides — can run as a single process against local infrastructure.
This is possible because of the separation described in The Big Picture. Compositions are a deployment decision, so the application that runs as one process on a laptop is the same application that runs as many in production, with the same components, contracts, and guarantees. A developer does not work against a simplified imitation.
§Environments and guarantees
Some guarantees depend on what the infrastructure can do; see Connectors. A local database without transactions cannot commit events together with state, and the runtime says so when it starts.
It is therefore worth keeping the infrastructure of lower environments capable of the same guarantees as production, even at a smaller scale. The application code is identical everywhere. Whether its guarantees are identical depends on what it is given to run on.