An awesome list of declaratively configured applications and engines.
- Understanding Declarative Configuration
- The List
This is a list of awesome application which qualify as being declaratively configured. To understand what qualifies for this list, it is important to understand what declarative actually means. Declarative programming as defined in wikipedia is;
"a style of building the structure and elements of computer programs—that expresses the logic of a computation without describing its control flow."
An operator can declare what they want and the app makes it a reality by handling all the gritty details. Truly declarative languages that must figure out several interdependencies in the correct order in a repeatable manner will often employ graph theory such as direct acycle graphs(DAGS) to achieve their desired results. For example, a common declarative infrastructure tool known as terraform will use such algorithms along with a separate 'state' to speed up future runs and track the current known state after the declarative manifest has processed. In theory, this allows not only to deploy repeatable infrastructure for IT projects, but also can be used to control configuration drift by making the deployment itself idempotent.
At a high level, a declaratively structured workflow looks pretty simple.
The declarative engine is an abstraction layer that produces a desired end state from an input manifest written in a Domain Specific Language (DSL). This is a simple but powerful approach to application configuration and deployment workflows.
Understanding Declarative Configuration
The next few sections will provide foundational knowledge of declarative configuration.
Several benefits emerge when using declarative engines to accomplish configuration tasks. Declarative configuration is;
- Easier to comprehend
- More succinct
- More reusable
- Naturally resistent to configuration skew/drift
- Easy to check into version control
- Is often self-documenting
There are drawbacks to this model as well. A few of these in no particular order.
- State management can be trickier to maneuver in some cases
- Upgrade of the underlying DSL schema can be a labyrinthine effort
- Version 'pinning' of configuration code becomes far more important
- Exclusivity of declarative configuration is almost required to reap the aforementioned benefits
These drawbacks typically emerge in more complex declarative configurations.
Three broad categories of software will be considered for this list. The difference between them is a bit fuzzy but largely comes down to the target of the declarative manifests it consumes. Categories are as follows:
Engines - Engines consume declarative manifests in some manner to simplify the attainment of desired state of a broad range of systems outside of the application itself. A prime example of a declarative engine would be Terraform.
Applications - An application which is able to be configured declaratively or uses declarative manifests to accomplish application specific tasks. One example of a declarative application would be a Kubernetes operator.
Platforms - A platform which consumes declarative manifests to configure or deploy platform specific elements. A great example of a declarative platform would be Kubernetes.
The crux of a declarative configuration file is the manifest used to actually declare desired state. The input for a declarative application, platform, or engine will be one or more declarative manifests that meet the following criteria to be on this list;
- Are human readable
- Follow a concrete configuration schema or language definition
- Present a reduction of overall complexity to the operator
We do not include dependency graphing or other more complex mechanisms as a requirement as it is perfectly plausible to meet the above criteria without advanced pathing/convergence techniques. The manifest format is not relevant either. They need only be human readable so that one can look at a manifest and understand what the end state will be if processed. This means toml, hcl, json, ini, cuelang, and the ever loved/hated yaml are perfectly valid declarative configuration formats on this list.
What Does Not Qualify
Some applications that have broad industry support can be used as a means to enable declarative declaration for any number of other applications. For example, a great deal of effort has gone into modernizing applications to run on Kubernetes via helm. These helm packages come in the form of versioned 'charts' that can then be used by operators to express, in a declarative manner, a deployment of that application to the Kubernetes platform. These charts can mask an underlying non-declaratively configured application. These charts are the source manifest for a declarative tool to apply the desired state against a Kubernetes cluster. As such, individual helm charts are not going to be considered for this list but rather, helm itself would be on this list as an application that facilitates declarative configuration.
The list can be viewed via Github here or be consumed in its published form here.
The list itself is a declarative YAML file,
list.yml, that you can submit new contributions to quite easily. This one yaml file goes through some testing to ensure validity via Culang. After the hard tests have been passed, the entry itself will be go through the soft-test and (hopefully) approved. The final merge will kick off a gomplate template merge with
list.yml as the datasource.
We then assemble the mkdocs files as defined in the declarative
mkdocs.yml file and build the published site on github pages. Sub-pages for the mkdocs published version are soft-linked into the docs folder.
NOTE I put forth a bit of effort to generate the list via cuelang natively but was not able to effectively make that happen. Perhaps someone else can? (hint hint)
Read the contribution guidelines for more info and other guidelines for submitting change requests to this project.