I had aked a question in this Charming Docs post but later realized that I should’ve asked the question here. So I’m re-asking here.
How does a charm author reconcile config.yaml
's deliberate restrictiveness with an application’s hierarchical configuration? For example, AlertManager has a non-flat configuration file (example) and translating some of the options to config.yaml
would be non-trivial.
For the simpler parts, it would obviously just be a matter of flattening the options in the config.yaml
file. For example, the following AlertManager configuration options:
global:
smtp_smarthost: 'localhost:25'
smtp_from: 'alertmanager@example.org'
smtp_auth_username: 'alertmanager'
smtp_auth_password: 'password'
Would be defined in the charm’s config.yaml
as
options:
global_smtp_smarthost:
type: string
global_smtp_from:
type: string
global_smtp_auth_username:
type: string
global_stmp_auth_password:
type: string
But how would one deal with repeating options such as AlertManager’s receivers? For example, I tried to map the following to what was possible with config.yaml
receivers:
- name: 'team-X-mails'
email_configs:
- to: 'team-X+alerts@example.org'
- name: 'team-X-pager'
email_configs:
- to: 'team-X+alerts-critical@example.org'
pagerduty_configs:
- service_key: <team-X-key>
...
The “best” approach I could get with config.yaml
was
options:
receivers1_name:
type: string
receivers1_config_type:
type: string
receivers1_config_options:
type: string # Would really have to be a minified JSON string or a base64 encoded YAML string
receivers2_name:
type: string
receivers2_config_type:
type: string
receivers2_config_options:
type: string # Would really have to be a minified JSON string or a base64 encoded YAML string
...
Obviously the above approach is not ideal for a number of reasons:
- The number of receivers defined would be limited to however many
receiversX_*
is defined inconfig.yaml
- Dropping down to a JSON string or a base64-encoded YAML string defeats the purpose of
config.yaml
's restrictiveness which is to simplify AlertManager configuration - As per the documentation referred to above: “If you’re considering using base64 encoding to slip structured data through the deliberately restrictive configuration language, you’re probably ‘Doing It Wrong.’”
- Note in the AlertManager config above how the
team-X-pager
receiver has a config for both email and pagerduty. How does one represent that inconfig.yaml
?
My initial analysis to the above problem is that it’s a symptom of me trying to create an “Unnecessary Abstraction Over An Abstraction™.” AlertManager’s configuration is already an abstraction over a complex problem domain and it is, for now, the simplest way to configure alerting. To try and abstract that with options in config.yaml
seems unnecessary and a side effect of this would be that the charm user would have to learn the configuration options of the charm and try and map that to AlertManager’s own configuration options. This means a lot of jumping back and forth between the charm’s documentation and AlertManager’s documentation. Again, that defeats the intended purpose of conig.yaml
and charming in general which is to simplify the job of deploying and operating AlertManager or any other application.
Of course, I haven’t stopped my analysis there. To move forward with my charming work, I tried to prototype a number of approaches. One of the approaches that I found promising was making use of juju’s --resource
option. This GitHub Pull Request already explains this thought process well enough.
I am also wary of the possibility that I might just be missing some hidden powers behind config.yaml
's parser so I’d be more than happy to be corrected of my (mis)understanding of the above restrictiveness.
I would love to know what the rest of the community thinks about this. Thank you so much for reading this far.