Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(DMVP-5017): refactor alerts related config and sub-module structure #21

Merged
merged 2 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 55 additions & 152 deletions README.md

Large diffs are not rendered by default.

10 changes: 0 additions & 10 deletions dashboard.tf

This file was deleted.

31 changes: 15 additions & 16 deletions main.tf
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
module "alerts" {
source = "./modules/alerts"

alert_interval_seconds = var.alert_interval_seconds
alert_rules = var.alert_rules
}
module "application_dashboard" {
source = "./modules/dashboard/"

module "contact_points" {
source = "./modules/contact-points"
count = length(var.application_dashboard) > 0 ? 1 : 0

count = length(var.alert_rules) != 0 ? 1 : 0

slack_endpoints = var.slack_endpoints
opsgenie_endpoints = var.opsgenie_endpoints
name = var.name
rows = var.application_dashboard.rows
data_source = var.application_dashboard.data_source
variables = var.application_dashboard.variables
}

module "notifications" {
source = "./modules/notifications"
module "alerts" {
source = "./modules/alerts"

count = length(var.alert_rules) != 0 ? 1 : 0
count = var.alerts != null ? 1 : 0

notifications = var.notifications
alert_interval_seconds = var.alerts.alert_interval_seconds
disable_provenance = var.alerts.disable_provenance
rules = var.alerts.rules
contact_points = var.alerts.contact_points
notifications = var.alerts.notifications
}
43 changes: 43 additions & 0 deletions modules/alert-contact-points/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
## Usage
This Terraform module enables the creation of Grafana contact points for various integrations such as Slack and OpsGenie. Contact points allow you to configure alert notifications to different services based on your requirements.

There are numerous integrations available for Grafana, but currently, this module supports only Slack and OpsGenie. We are continuously working to add more integrations in the future. If you have any questions or need assistance, feel free to open an issue or contact our team.
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0 |
| <a name="requirement_grafana"></a> [grafana](#requirement\_grafana) | >= 1.40.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_grafana"></a> [grafana](#provider\_grafana) | >= 1.40.0 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [grafana_contact_point.opsgenie_contact_point](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/contact_point) | resource |
| [grafana_contact_point.slack_contact_point](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/contact_point) | resource |
| [grafana_contact_point.webhook_contact_point](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/contact_point) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_disable_provenance"></a> [disable\_provenance](#input\_disable\_provenance) | Allow modifying the contact point from other sources than Terraform or the Grafana API. | `bool` | `true` | no |
| <a name="input_opsgenie_endpoints"></a> [opsgenie\_endpoints](#input\_opsgenie\_endpoints) | OpsGenie contact points list. | <pre>list(object({<br> name = string # The name of the contact point<br> api_key = string # The OpsGenie API key to use<br> auto_close = optional(bool, false) # Whether to auto-close alerts in OpsGenie when they resolve in the Alert manager<br> message = optional(string, "") # The templated content of the message<br> api_url = optional(string, "https://api.opsgenie.com/v2/alerts") # Allows customization of the OpsGenie API URL<br> disable_resolve_message = optional(bool, false) # Whether to disable sending resolve messages<br> }))</pre> | `[]` | no |
| <a name="input_slack_endpoints"></a> [slack\_endpoints](#input\_slack\_endpoints) | Slack contact points list. | <pre>list(object({<br> name = string # The name of the contact point<br> endpoint_url = optional(string, "https://slack.com/api/chat.postMessage") # Use this to override the Slack API endpoint URL to send requests to<br> icon_emoji = optional(string, "") # The name of a Slack workspace emoji to use as the bot icon<br> icon_url = optional(string, "") # A URL of an image to use as the bot icon<br> recipient = optional(string, null) # Channel, private group, or IM channel (can be an encoded ID or a name) to send messages to<br> text = optional(string, "") # Templated content of the message<br> title = optional(string, "") # Templated title of the message<br> token = optional(string, "") # A Slack API token,for sending messages directly without the webhook method<br> webhook_url = optional(string, "") # A Slack webhook URL,for sending messages via the webhook method<br> username = optional(string, "") # Username for the bot to use<br> disable_resolve_message = optional(bool, false) # Whether to disable sending resolve messages<br> }))</pre> | `[]` | no |
| <a name="input_webhook_endpoints"></a> [webhook\_endpoints](#input\_webhook\_endpoints) | Contact points that send notifications to an arbitrary webhook, using the Prometheus webhook format. | <pre>list(object({<br> name = string # The name of the contact point<br> url = string # The URL to send webhook requests to<br> authorization_credentials = optional(string, null) # Allows a custom authorization scheme - attaches an auth header with this value. Do not use in conjunction with basic auth parameters<br> authorization_scheme = optional(string, null) # Allows a custom authorization scheme - attaches an auth header with this name. Do not use in conjunction with basic auth parameters<br> basic_auth_password = optional(string, null) # The password component of the basic auth credentials to use<br> basic_auth_user = optional(string, null) # The username component of the basic auth credentials to use<br> disable_resolve_message = optional(bool, false) # Whether to disable sending resolve messages. Defaults to<br> settings = any # Additional custom properties to attach to the notifier<br> }))</pre> | `[]` | no |

## Outputs

No outputs.
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
//Slack Integration
# Slack Integration
resource "grafana_contact_point" "slack_contact_point" {
for_each = { for cp in var.slack_endpoints : cp.name => cp }

name = each.key
name = each.key
disable_provenance = var.disable_provenance

slack {
endpoint_url = each.value.webhook_url
Expand All @@ -18,11 +19,12 @@ resource "grafana_contact_point" "slack_contact_point" {
}
}

//OpsGenie Integration
# OpsGenie Integration
resource "grafana_contact_point" "opsgenie_contact_point" {
for_each = { for cp in var.opsgenie_endpoints : cp.name => cp }

name = each.key
name = each.key
disable_provenance = var.disable_provenance

opsgenie {
api_key = each.value.api_key
Expand All @@ -32,3 +34,22 @@ resource "grafana_contact_point" "opsgenie_contact_point" {
disable_resolve_message = each.value.disable_resolve_message
}
}


# Webhook endpoints Integration
resource "grafana_contact_point" "webhook_contact_point" {
for_each = { for cp in var.webhook_endpoints : cp.name => cp }

name = each.key
disable_provenance = var.disable_provenance

webhook {
url = each.value.url
authorization_credentials = each.value.authorization_credentials
authorization_scheme = each.value.authorization_scheme
basic_auth_password = each.value.basic_auth_password
basic_auth_user = each.value.basic_auth_user
disable_resolve_message = each.value.disable_resolve_message
settings = each.value.settings
}
}
16 changes: 16 additions & 0 deletions modules/alert-contact-points/tests/mixed-contact-points/0-setup.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
terraform {
required_version = ">= 1.3.0"

required_providers {
grafana = {
source = "grafana/grafana"
version = ">= 3.7.0"
}
}
}

# you can start dev grafana server locally using `docker compose up -d` from `/tests` folder before running the test locally
provider "grafana" {
url = "http://localhost:3000"
auth = "admin:admin"
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ This test creates multiple contact points which have different types of integrat

| Name | Version |
|------|---------|
| <a name="requirement_grafana"></a> [grafana](#requirement\_grafana) | >= 1.40.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0 |
| <a name="requirement_grafana"></a> [grafana](#requirement\_grafana) | >= 3.7.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_test"></a> [test](#provider\_test) | n/a |
No providers.

## Modules

Expand All @@ -21,9 +20,7 @@ This test creates multiple contact points which have different types of integrat

## Resources

| Name | Type |
|------|------|
| test_assertions.dummy | resource |
No resources.

## Inputs

Expand Down
16 changes: 16 additions & 0 deletions modules/alert-contact-points/tests/opsgenie/0-setup.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
terraform {
required_version = ">= 1.3.0"

required_providers {
grafana = {
source = "grafana/grafana"
version = ">= 3.7.0"
}
}
}

# you can start dev grafana server locally using `docker compose up -d` from `/tests` folder before running the test locally
provider "grafana" {
url = "http://localhost:3000"
auth = "admin:admin"
}
11 changes: 11 additions & 0 deletions modules/alert-contact-points/tests/opsgenie/1-example.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module "this" {
source = "../../"

opsgenie_endpoints = [
{
name = "opsgenie"
api_key = "xxxxxxxx"
auto_close = true
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ OpsGenie authentication can be done using OpsGenie API Key by passing the value

| Name | Version |
|------|---------|
| <a name="requirement_grafana"></a> [grafana](#requirement\_grafana) | >= 1.40.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0 |
| <a name="requirement_grafana"></a> [grafana](#requirement\_grafana) | >= 3.7.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_test"></a> [test](#provider\_test) | n/a |
No providers.

## Modules

Expand All @@ -23,9 +22,7 @@ OpsGenie authentication can be done using OpsGenie API Key by passing the value

## Resources

| Name | Type |
|------|------|
| test_assertions.dummy | resource |
No resources.

## Inputs

Expand Down
16 changes: 16 additions & 0 deletions modules/alert-contact-points/tests/slack/0-setup.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
terraform {
required_version = ">= 1.3.0"

required_providers {
grafana = {
source = "grafana/grafana"
version = ">= 3.7.0"
}
}
}

# you can start dev grafana server locally using `docker compose up -d` from `/tests` folder before running the test locally
provider "grafana" {
url = "http://localhost:3000"
auth = "admin:admin"
}
10 changes: 10 additions & 0 deletions modules/alert-contact-points/tests/slack/1-example.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module "this" {
source = "../../"

slack_endpoints = [
{
name = "slack"
webhook_url = "https://hooks.slack.com/services/xxxxxxxxx"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ Slack authentication can be done using either a `token` and `recipient` or a `we

| Name | Version |
|------|---------|
| <a name="requirement_grafana"></a> [grafana](#requirement\_grafana) | >= 1.40.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0 |
| <a name="requirement_grafana"></a> [grafana](#requirement\_grafana) | >= 3.7.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_test"></a> [test](#provider\_test) | n/a |
No providers.

## Modules

Expand All @@ -23,9 +22,7 @@ Slack authentication can be done using either a `token` and `recipient` or a `we

## Resources

| Name | Type |
|------|------|
| test_assertions.dummy | resource |
No resources.

## Inputs

Expand Down
51 changes: 51 additions & 0 deletions modules/alert-contact-points/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
variable "disable_provenance" {
type = bool
default = true
description = "Allow modifying the contact point from other sources than Terraform or the Grafana API."
}

variable "slack_endpoints" {
type = list(object({
name = string # The name of the contact point
endpoint_url = optional(string, "https://slack.com/api/chat.postMessage") # Use this to override the Slack API endpoint URL to send requests to
icon_emoji = optional(string, "") # The name of a Slack workspace emoji to use as the bot icon
icon_url = optional(string, "") # A URL of an image to use as the bot icon
recipient = optional(string, null) # Channel, private group, or IM channel (can be an encoded ID or a name) to send messages to
text = optional(string, "") # Templated content of the message
title = optional(string, "") # Templated title of the message
token = optional(string, "") # A Slack API token,for sending messages directly without the webhook method
webhook_url = optional(string, "") # A Slack webhook URL,for sending messages via the webhook method
username = optional(string, "") # Username for the bot to use
disable_resolve_message = optional(bool, false) # Whether to disable sending resolve messages
}))
default = []
description = "Slack contact points list."
}

variable "opsgenie_endpoints" {
type = list(object({
name = string # The name of the contact point
api_key = string # The OpsGenie API key to use
auto_close = optional(bool, false) # Whether to auto-close alerts in OpsGenie when they resolve in the Alert manager
message = optional(string, "") # The templated content of the message
api_url = optional(string, "https://api.opsgenie.com/v2/alerts") # Allows customization of the OpsGenie API URL
disable_resolve_message = optional(bool, false) # Whether to disable sending resolve messages
}))
default = []
description = "OpsGenie contact points list."
}

variable "webhook_endpoints" {
type = list(object({
name = string # The name of the contact point
url = string # The URL to send webhook requests to
authorization_credentials = optional(string, null) # Allows a custom authorization scheme - attaches an auth header with this value. Do not use in conjunction with basic auth parameters
authorization_scheme = optional(string, null) # Allows a custom authorization scheme - attaches an auth header with this name. Do not use in conjunction with basic auth parameters
basic_auth_password = optional(string, null) # The password component of the basic auth credentials to use
basic_auth_user = optional(string, null) # The username component of the basic auth credentials to use
disable_resolve_message = optional(bool, false) # Whether to disable sending resolve messages. Defaults to
settings = any # Additional custom properties to attach to the notifier
}))
default = []
description = "Contact points that send notifications to an arbitrary webhook, using the Prometheus webhook format."
}
Loading
Loading