Quickstart
In about 2 minutes you will build configs for two services in two environments, then make three everyday changes that would normally mean editing files across services by hand, and see a broken reference stop the build.
1. Install
No Homebrew? Get a binary for macOS, Linux, Windows or a Java jar.
2. Get the example
Or download the zip and unzip it.
The example has two services, payment-backend and payment-frontend, in the
payments group, and two environments, dev and prod. Shared
parts live in components/common:
components
├── common
│ ├── log # logging settings and the logback.xml template
│ ├── monitoring # monitoring settings for every service
│ └── postgres # database settings, dev and prod hosts
└── payments
├── payment-backend
└── payment-frontend
envs
├── base.yaml # which services exist
├── dev.yaml
└── prod.yaml
3. Build
Filtered 2 component(s) in [dev] env.
Copied 'payment-backend' template ../log/logback.xml -> logback.xml
Generated payment-backend/application.yaml
Generated payment-backend/deploy.yaml
Copied 'payment-frontend' template ../log/logback.xml -> logback.xml
Generated payment-frontend/application.yaml
Generated payment-frontend/deploy.yaml
Generated [dev] configs in 8ms
Open build/payment-backend/application.yaml. Monitoring, database and logging settings
are already merged in from common, and the database host is the one for
dev. These are plain files your services can read as is.
For comparison: written by hand, the same configs for two services in two environments take 92 lines (see initial.md). The Microconfig sources take 50, and every new service adds only the lines that are unique to it.
Now the interesting part
Four situations from real life. Each one takes a single edit.
2Change a value other services depend on
The backend moves its API to /api/v2. Last time, the frontend found out in
production.
Edit components/payments/payment-backend/application.yaml:
server:
port: 80
context: /api/v2
The frontend doesn't copy this value, it references it:
path: ${payment-backend@server.context}. Build and check the diff:
==> build/payment-backend/diff-application.yaml <==
server:
context: /api -> /api/v2
==> build/payment-frontend/diff-application.yaml <==
payment-backend:
path: /api -> /api/v2
You changed the backend, and the frontend followed. No one had to remember that they are connected.
3Add an environment in two small files
A client needs their own stage by tomorrow, with its own database.
Create envs/staging.yaml with the same services as the base environment:
include:
env: base
And override only what differs. Create
components/common/postgres/application.staging.yaml:
#var dbHost: 30.30.30.30
Build the new environment:
url: jdbc:postgres://30.30.30.30:5432/payments
A complete new environment for every service: the new database host, and everything else inherited from the base config.
4Break a reference on purpose
Someone renames a key or makes a typo. Without Microconfig, the service finds out at startup, in production.
In components/payments/payment-frontend/application.yaml, misspell the reference:
payment-backend:
path: ${payment-backend@server.contxt}
Can't build configs for root component 'payment-frontend[dev]'.
Exception in
../components/payments/payment-frontend/application.yaml:10'
payment-backend.path=${payment-backend@server.contxt}
Can't resolve ${payment-backend@server.contxt}
The build stops with a non-zero exit code and points to the file and line. In CI, that means the broken config never reaches an environment.
Useful build options
-e prodbuild all services of an environment-g paymentsbuild only a group of services-s payment-backendbuild only specific services-r path/to/configsconfig root, the current directory by default-d path/to/outputwhere to put the result,./buildby default
All options are in the documentation.
Try it on your own configs
Pick one block that is copy-pasted between your services, like monitoring, logging or a database
pool. Move it to components/common, #include it, and build. Your other
configs can stay as they are until you are ready.
Next steps:
- Features: every feature on a real-life problem
- IDE plugin: resolve values for every environment right in the editor
- Documentation: the full reference
- Questions? Ask in Slack or open an issue on GitHub