When using Prometheus monitoring stack, Alertmanager is an essential part of the monitoring, while responsible to send alerts. I explain here how I manage, the respective configuration using Terraform.
The Alertmanager handles alerts sent by client applications such as the Prometheus server. It takes care of deduplicating, grouping, and routing them to the correct receiver integration such as email, PagerDuty, or OpsGenie. It also takes care of silencing and inhibition of alerts.
The problem with this is, once you would like to add additional routes and/or receivers, changes made to this config and running an “upgrade” of the app will not change the Alertmanager Config Secret. So the only way to add routes and/or receivers is doing it within the Rancher UI. Unfortunately, it only appends newly created routes to the end, which is not what you want. In the above example I have a main channel, and all alerts are sent to this channel. Now if you want specific alerts to be sent to another channel, this rout should go between match: alertname: Watchdog and match: prometheus: cattle-monitoring-system/rancher-monitoring-prometheus.
So what I started to do, to overcome the problem, is to manage the Alertmanager Config Secret with Terraform:
While ${path.module}/apps/alertmanager.yaml points to the yaml file, which contains the config as seen above. Unfortunately changes made to this file, will be only picked up under two circumstances
alertmanager pod is restarted, which will re-create secret alertmanager-rancher-monitoring-alertmanager-generated
secret alertmanager-rancher-monitoring-alertmanager-generated is deleted, which will then been re-created
So even so all was managed by Terraform, there is still manual intervention done do make changes work.
Deprecation of “Routes and Receivers”
With Rancher 2.6.5, there also came the deprecation of Routes and Receiver resources:
The Route and Receiver resources are deprecated. Going forward, routes and receivers should not be managed as separate Kubernetes resources on this page. They should be configured as YAML fields in an AlertmanagerConfig resource.
To manage Alertmanager configuration, one should make use of AlertmanagerConfigs:
Add alertmanagerConfigs to each namespace using Terraform
As each team/solution has it’s own projects, as well as it’s own alerting channel, I would like to use the same alert channel for all ns of a project, but without I have to specify the namespaces in Terraform. Simply cause new namespaces are added over time and it’s in the responsibility of the team to care about the namespaces. In my last post I explained how I manage Rancher-projects using Terraform.
So I want to extend the local.projects with an element channel which will - if defined - be added to all namespaces of the project. Unfortunately neither rancher2_project data source nor rancher2_namespace data source let me get all ns of a project. The only thing I found is kubernetes_all_namespaces. The only way we can know to which project the namespace is associated, is by looking at the annotation field.cattle.io/projectId. So how to achieve this? Let’s start by
As you can see ns.project currently looks like this
However I want to set it only to the value of field.cattle.io/projectId. You can use the lookup function:
I iterate over all projects local.projects, and then check for namespaces having the respective annotation:
Here my full code….
… which gives me the mapping of namespaces to project:
Unfortunately I need a flat list, but merge does not seem to work as expected and still gives the result above:
As a final step, I iterate over local.project_namespaces and create a resource, but only if it’s not null:
Here an example of what’s created:
Wrap-Up
In this post I explained you my solution to managing the namespaced alertmanagerConfigs by using Terraform expressions and functions. What do you think about this approach? Is it useful for you as well? Leave me a comment below.